Repository navigation
Symbols loading from the target (via gdb/gdbserver) does not work #11949
Copy link
Copy link
Open
Labels
Language Servicedebuggerhelp wantedCan be fixed in the public (open source) repo.Can be fixed in the public (open source) repo.
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) <-logoutOther 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
Reactions are currently unavailable
Metadata
Metadata
Assignees
Labels
Language Servicedebuggerhelp wantedCan be fixed in the public (open source) repo.Can be fixed in the public (open source) repo.
Activity
UR3IQO commentedon Feb 14, 2024
I looked at the
GetInitializeCommandsin DebuggedProcess.cs (MIEngine repo) and realized that Option 3 in the possible solutions was already implemented. So, I tried to use fully custom setup and launch gdb commands and it did the trick:And the filtered log:
jfuentesa commentedon Sep 30, 2024
Is it possible to avoid sending the -file-exec-and-symbols command?
I'm using the following syntax to start a gdbserver instance via stdin with a custom .gdbinit:
"target remote | ssh HOST gdbserver - --attach PID"
I don't want to debug the executable itself; instead, I want to debug a shared library. However, the trace shows the following error:
I have tested the options "launch" and "attach" but they don't work for one reason or another.
"attach": It asks for a local PID.
"launch": Try to run the program, which is already launched. It fails if the file does not exist (it only exists in the remote host).
I need a way to override this behaviour.
Thank you.