microsoft / microsoft/vscode-cpptools
Symbols loading from the target (via gdb/gdbserver) does not work
Nobody has claimed this yet.
- Dominant language
- TypeScript
- Stars
- 6.2k
- Forks
- 1.7k
- Avg merge
- 14h 46m
- Merged PRs (30d)
- 61
Description
Environment
- OS and version:
ОС: Windows_NT x64 10.0.19044 - VS Code:
1.86.0 - C/C++ extension:
1.19.1 - OS and version of remote machine (if applicable):
Linux raspberrypi 4.19.304-v7+ #3 SMP Wed Jan 10 14:46:02 MSK 2024 armv7l GNU/Linux - GDB / LLDB version:
14.1
Bug Summary and Steps to Reproduce
When using remote debugging with extended remote target it is possible to load symbols from the remote target directly using the target:/path-to-executable path for the -file-exec-and-symbols GDB command.
Unfortunately there is a problem in the current cpptools.
Steps to reproduce:
- Use any project with the remote debugging (target and host machines should differ)
- Set
programin thelaunch.jsontotarget:/path-to-executable-on-the-remote-target - Enable extended remote
"useExtendedRemote": true - Start remote gdbserver and debugging
cpptools issue GDB -file-exec-and-symbols command before connecting to the remote target, so it looks for the file on the host, fails and debugging can not be started (see the filtered log)
Debugger Configurations
{
//NOTE: remote username, address, project directory and executable name are defined in the config file (.vscode/settings.json)
"version": "0.2.0",
"configurations": [
{
"name": "Remote debug",
"type": "cppdbg",
"request": "launch",
"targetArchitecture": "arm",
"useExtendedRemote": true,
"program": "target:${config:remote.dir}/${config:remote.exec}",
"miDebuggerServerAddress": "${config:remote.addr}:1234",
"args": [],
"stopAtEntry": true,
"cwd": "${workspaceRoot}",
"environment": [],
"externalConsole": true,
"sourceFileMap":{
"/share/OGL" : "$WorkspaceRoot}"
},
"windows": {
"MIMode": "gdb",
"miDebuggerPath": "C:\\gdb-arm-linux\\bin\\arm-linux-gnueabihf-gdb.exe",
"preLaunchTask": "debug"
},
"logging": {
"engineLogging": true,
"trace": true
}
}
]
}
Debugger Logs
1: (202) <-1001-gdb-set mi-async on
1: (233) <-1002-interpreter-exec console "show configuration"
1: (261) <-1003-interpreter-exec console "set pagination off"
1: (276) <-1004-gdb-set auto-solib-add on
1: (291) <-1005-gdb-set solib-search-path target:/share/OGL/build;
1: (308) <-1006-environment-cd D:/Oleg/_Projects/Neon3/Software/Client/CtrlPi
1: (324) <-1007-gdb-set new-console on
1: (347) <-1008-file-exec-and-symbols target:/share/OGL/build/main.elf
1: (355) ->1008^error,msg="/share/OGL/build/main.elf: No such file or directory."
1: (360) <--gdb-exit
1: (363) <-logout
Other Extensions
No response
Additional Information
Possible solutions
- Probably the most correct is to connect to remote target early (before issuing
-file-exec-and-symbolscommand) ifprogramstarts withtarget: - The most simple is to skip checking program existence on the host if path specified in
programstarts withtarget:
How it works:
It is possible to issuetarget extended-remotecommand explicitly by using thesetupCommands. themiDebuggerServershould not be used, cause we connect to target insetupCommands. Unfortunately whenmiDebuggerServeris not specified cpptools check the existence of the program specified by theprogramand of cause it does not exists on the host (moreover the path is also invalid). If it will not do that check the following configuration will work and load symbols from the target directly:
{
//NOTE: remote username, address, project directory and executable name are defined in the config file (.vscode/settings.json)
"version": "0.2.0",
"configurations": [
{
"name": "Remote debug",
"type": "cppdbg",
"request": "launch",
"targetArchitecture": "arm",
"useExtendedRemote": true,
"program": "target:${config:remote.dir}/${config:remote.exec}",
"args": [],
"stopAtEntry": true,
"cwd": "${workspaceRoot}",
"environment": [],
"externalConsole": true,
"sourceFileMap":{
"/share/OGL" : "$WorkspaceRoot}"
},
"setupCommands": [
{ "text":"target extended-remote ${config:remote.addr}:1234", "ignoreFailure":false }
],
"windows": {
"MIMode": "gdb",
"miDebuggerPath": "C:\\gdb-arm-linux\\bin\\arm-linux-gnueabihf-gdb.exe",
"preLaunchTask": "debug"
},
"logging": {
"engineLogging": true,
"trace": true
}
}
]
}
- The ability to specify fully custom setup commands (so the
-file-exec-and-symbolsand-target-select extended-remoteare specified explicitly) will also solve this problem
Ugly current workaround
Issue target extended-remote command in the setupCommands and do not remove miDebuggerServer from the launch.json. This will result in issuing target extended-remote command twice, but somehow it works :). Not sure it will with the other GDB version:
1: (217) <-1001-gdb-set mi-async on
1: (228) <-1002-interpreter-exec console "show configuration"
1: (256) <-1003-interpreter-exec console "target extended-remote 192.168.122.233:1234"
1: (327) <-1004-interpreter-exec console "set pagination off"
1: (328) <-1005-gdb-set auto-solib-add on
1: (349) <-1006-gdb-set solib-search-path target:/share/OGL/build;
1: (369) <-1007-environment-cd D:/Oleg/_Projects/Neon3/Software/Client/CtrlPi
1: (380) <-1008-gdb-set new-console on
1: (401) <-1009-file-exec-and-symbols target:/share/OGL/build/main.elf
1: (4575) <-1010-interpreter-exec console "show architecture"
1: (4593) <-1011-break-insert -f main
1: (5106) <-1012-target-select extended-remote 192.168.122.233:1234
1: (5180) <-1013-interpreter-exec console "set remote exec-file /share/OGL/build/main.elf"
1: (5199) <-1014-interpreter-exec console "set scheduler-locking step"
<-- C (setBreakpoints-3): {"command":"setBreakpoints","arguments":{"source":{"name":"test.c","path":"d:\\Oleg\\_Projects\\Neon3\\Software\\Client\\CtrlPi\\test.c"},"lines":[243],"breakpoints":[{"line":243}],"sourceModified":false},"type":"request","seq":3}
1: (5273) <-1015-break-insert -f test.c:243
1: (5306) <-1016-symbol-list-lines D:/Oleg/_Projects/Neon3/Software/Client/CtrlPi/test.c
<-- C (setFunctionBreakpoints-4): {"command":"setFunctionBreakpoints","arguments":{"breakpoints":[]},"type":"request","seq":4}
<-- C (setDataBreakpoints-5): {"command":"setDataBreakpoints","arguments":{"breakpoints":[]},"type":"request","seq":5}
<-- C (setInstructionBreakpoints-6): {"command":"setInstructionBreakpoints","arguments":{"breakpoints":[]},"type":"request","seq":6}
<-- C (setExceptionBreakpoints-7): {"command":"setExceptionBreakpoints","arguments":{"filters":[],"filterOptions":[]},"type":"request","seq":7}
<-- C (configurationDone-8): {"command":"configurationDone","type":"request","seq":8}
<-- C (threads-9): {"command":"threads","type":"request","seq":9}
1: (5399) <-1017-exec-run
Contributor guide
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- Open a pull request that references the issue number.
Research direction
Reproduce the launch configuration with useExtendedRemote and a target: program, then inspect the GDB initialization sequence around -file-exec-and-symbols and target extended-remote. Done means remote debugging starts successfully and symbols load from the target executable without requiring the workaround that connects twice.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- cpp, vscode
- Domain
- devtools
- Issue type
- Bug
- Difficulty
- 4/5
- Estimated time
- 3-5 days
- Activity status
- Stale
- Clarity
- Mostly clear
- Newbie friendliness
- 35/100