Movatterモバイル変換


[0]ホーム

URL:


Skip to content

Navigation Menu

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up

Native debugging for VSCode

License

NotificationsYou must be signed in to change notification settings

WebFreak001/code-debug

Repository files navigation

VS MarketplaceOpen VSX RegistryGitHub CI StatusCoverage Status

Native VSCode debugger. Supports both GDB and LLDB.

Installation

Press ctrl-p (cmd+p on OS X) and runext install webfreak.debug in visual studio code and install GDB/LLDB. SeeUsage for details on how to set it up.

Preview

Usage

Image with red circle around a gear and a red arrow pointing at GDB and LLDB

Or if you already have an existing debugger in your project setup you can click "Create Configuration" or use the auto completion instead:

Visual studio code debugger launch.json auto completion showing alternative way to create debuggers

Open your project and click the debug button in your sidebar. At the top right pressthe little gear icon and select GDB or LLDB. It will automatically generate the configurationyou need.

Note: for LLDB you need to havelldb-mi in your PATH

If you are on OS X you can addlldb-mi to your path usingln -s /Applications/Xcode.app/Contents/Developer/usr/bin/lldb-mi /usr/local/bin/lldb-mi if you have Xcode.

Default config with a red circle around the target

Now you need to changetarget to the application you want to debug relativeto thecwd. (Which is the workspace root by default)

Additionally you can setterminal if you want to run the program in a separate terminal withsupport for input. On Windows set it to an empty string ("") to enable this feature. On linuxset it to an empty string ("") to use the default terminal emulator specified withx-terminal-emulatoror specify a custom one. Note that it must support the-e argument.

Before debugging you need to compile your application first, then you can run it usingthe green start button in the debug sidebar. For this you could use thepreLaunchTaskargument vscode allows you to do. Adding breakpoints while the program runs will notinterrupt it immediately. For that you need to pause & resume the program once first.However adding breakpoints while its paused works as expected.

Extending variables is very limited as it does not support child values of variables.Watching expressions works partially but the result does not get properly parsed andit shows the raw output of the command. It will rundata-evaluate-expressionto check for variables.

While running you will get a console where you can manually type GDB/LLDB commands or MIcommands prepended with a hyphen-. The console shows all output separatedinstdout for the application,stderr for errors andlog for log messages.

Some exceptions/signals like segmentation faults will be caught and displayed butit does not support for example most D exceptions.

Support exists for stopping at the entry point of the application. This is controlledthrough thestopAtEntry setting. This value may be either a boolean or a string. Inthe case of a boolean value offalse (the default), this setting is disabled. In thecase of a boolean value oftrue, if this is a launch configuration and the debuggersupports thestart (orexec-run --start MI feature, more specifically), than thiswill be used to run to the entry point of the application. Note that this appears towork fine for GDB, but LLDB doesn't necessarily seem to adhere to this, even though it mayindicate that it supports this feature. The alternative configuration option for thestopAtEntry setting is to specify a string where the string represents the entry pointitself. In this situation a temporary breakpoint will be set at the specified entry pointand a normal run will occur for a launch configuration. This (setting a temporarybreakpoint) is also the behavior that occurs when the debugger does not support thestart feature and thestopAtEntry was set totrue. In that case the entry point willdefault to "main". Thus, the most portable way to use this configuration is to explicitlyspecify the entry point of the application. In the case of an attach configuration, similarbehavior will occur, however since there is no equivalent of thestart command forattaching, a boolean value oftrue for thestopAtEntry setting in a launch configurationwill automatically default to an entry point of "main", while a string value for thissetting will be interpreted as the entry point, causing a temporary breakpoint to be set atthat location prior to continuing execution. Note that stopping at the entry point for theattach configuration assumes that the entry point has not yet been entered at the time ofattach, otherwise this will have no affect.

There is a Registers view in the VARIABLES view. As we fetch all registers at once, there canbe cases where a register that cannot be fetched causes the entire register request to fail,corrupting the entire Registers output. If this happens, you might need to set theregisterLimit option to specify which registers you want the debugger to fetchautomatically.

For example, to display only registersrax andrip in an x64 debug session, send thecommand-data-list-register-names in the debug console of an active x64 debug session.You will then receive a response containing an array starting with["rax","rbx" ...].In this array, the index ofrax is 0 andrip is 16, so set the option as"registerLimit": "0 16". If you find the response text hard to navigate, you can pasteit into a browser's developer tools console and press enter to get an expandable responseobject with array elements' indices explicitly displayed.

Attaching to existing processes

Attaching to existing processes currently only works by specifying the PID in thelaunch.json and settingrequest to"attach". You also need to specify the executablepath for the debugger to find the debug symbols.

"request": "attach","executable": "./bin/executable","target": "4285"

This will attach to PID 4285 which should already run. GDB will pause the program on entering and LLDB will keep it running.

Usinggdbserver for remote debugging (GDB only)

You can also connect to a gdbserver instance and debug using that. For that modify thelaunch.json by settingrequest to"attach" andremote totrue and specifying theport and optionally hostname intarget.

"request": "attach","executable": "./bin/executable","target": ":2345","cwd": "${workspaceRoot}","remote": true

This will attach to the running process managed by gdbserver on localhost:2345. You mightneed to hit the start button in the debug bar at the top first to start the program.

Control over whether the debugger should continue executing on connect can be configuredby settingstopAtConnect. The default value isfalse so that execution will continueafter connecting.

Using ssh for debugging on remote

Debugging using ssh automatically converts all paths between client & server and also optionallyredirects X11 output from the server to the client.
Simply add assh object in yourlaunch request.

"request": "launch","target": "./executable","cwd": "${workspaceRoot}","ssh": {"forwardX11": true,"host": "192.168.178.57","cwd": "/home/remoteUser/project/","keyfile": "/path/to/.ssh/key", // OR"password": "password123","user": "remoteUser","x11host": "localhost",// x11port may also be specified as string containing only numbers (useful to use configuration variables)"x11port": 6000,// Optional, content will be executed on the SSH host before the debugger call."bootstrap": "source /home/remoteUser/some-env"}

ssh.sourceFileMap will be used to trim off local paths and map them to the server. This isrequired for basically everything except watched variables or user commands to work.

For backward compatibility you can also usecwd andssh.cwd for the mapping, this is only usedif the newerssh.sourceFileMap is not configured.

For X11 forwarding to work you first need to enable it in your Display Manager and allow theconnections. To allow connections you can either add an entry for applications or runxhost +in the console while you are debugging and turn it off again when you are done usingxhost -.

Because some builds requires one or more environment files to be sourced before running anycommand, you can use thessh.bootstrap option to add some extra commands which will be prependedto the debugger call (using&& to join both).

Debugging a process from a different user (especially root/system processes)

To debug a program that needs additional privileges you may use one of the two approaches:

  1. start vscode with the necessary rights (so both the program and the started debugger instance willhave root rights) -sudo code /sudo codium or "start as admin".
    Note that this has a lot of security implications and will have the user settings of vscode for this user.
  2. preferred: use a small wrapper script that callssudo gdb $* /runas /profile /user:admin-user(or the debugger of your choice) and configure this extension to use it (for example withgdbpath)

Extra Debugger Arguments

Additional arguments can be supplied to the debugger if needed. These will be added whenthe debugger executable (e.g., gdb, lldb-mi, etc.) is launched. Extra debugger argumentsare supplied via thedebugger_args setting. Note that the behavior of escaping theseoptions depends on the environment in which the debugger is started. For non-SSHdebugging, the options are passed directly to the application and therefore no escaping isnecessary (other than what is necessary for the JSON configuration). However, as a resultof the options being passed directly to the application, care must be taken to placeswitches and switch values as separate entities indebugger_args, if they would normallybe separated by a space. For example, supplying the option and value-iex "set $foo = \"bar\"" would consist of the followingdebugger_args:

"debugger_args" : ["-iex","set $foo =\"bar\""]

If= is used to associate switches with their values, than the switch and value shouldbe placed together instead. In fact, the following example shows 4 different ways inwhich to specify the same switch and value, using both short and long format, as well asswitch values supplied as a separate parameter or supplied via the=:

  • "debugger_args" : ["-iex","set $foo =\"bar\""]
  • "debugger_args" : ["-iex=set $foo =\"bar\""]
  • "debugger_args" : ["--init-eval-command","set $foo =\"bar\""]
  • "debugger_args" : ["--init-eval-command=set $foo =\"bar\""]

Where escaping is really necessary is when running the debugger over SSH. In this case,the options are not passed directly to the application, but are instead combined with theapplication name, joined together with any other options, and sent to the remote system tobe parsed and executed. Thus, depending on the remote system, different escaping may benecessary. The following shows how the same command as above needs to be escapeddifferently based on whether the remote system is a POSIX or a Windows system.

  • SSH to Linux machine:
    "debugger_args": ["-iex","'set $foo =\"bar\"'"]
  • SSH to Windows machine:
    "debugger_args": ["-iex","\"set $foo =\\\"bar\\\"\""]

You may need to experiment to find the correct escaping necessary for the command to besent to the debugger as you intended.

LogMessage

LogMessage will print a message in the debug console when breakpoint is hit. Expressions within {} are interpolated.

LogMessage


[8]ページ先頭

©2009-2025 Movatter.jp