Permalink
9c57988 Oct 2, 2018
2 contributors

Users who have contributed to this file

@vadimcn @suztomo
409 lines (341 sloc) 21.7 KB

Table of Contents

Starting a Debug Session

To start a debug session you will need to create a launch configuration for your program:

Launching

parameter type req
name string Y Launch configuration name.
type string Y Set to lldb.
request string Y Set to launch.
program string Y Path to the debuggee executable.
cargo string Y See Cargo support.
args string ❘ [string] Command line parameters. If this is a string, it will be split using shell-like syntax.
cwd string Working directory.
env dictionary Additional environment variables. You may refer to existing environment variables using ${env:NAME} syntax, for example "PATH" : "${env:HOME}/bin:${env:PATH}".
stdio string ❘ [string] ❘ dictionary See Stdio Configuration.
terminal string Destination for debuggee's stdio streams:
  • console (default) for Debug Console
  • integrated for VSCode integrated terminal
  • external for a new terminal window
stopOnEntry boolean Whether to stop debuggee immediately after launching.
initCommands [string] LLDB commands executed upon debugger startup.
preRunCommands [string] LLDB commands executed just before launching the debuggee.
postRunCommands [string] LLDB commands executed just after launching the debuggee.
exitCommands [string] LLDB commands executed at the end of debugging session.
expressions string The default expression evaluator type: simple, python or native. See Expressions.
sourceMap dictionary See Source Path Remapping.
sourceLanguages A list of source languages used in the program. This is used to enable language-specific debugger features.

Stdio

The stdio property is a list of redirection targets for each of debuggee's stdio streams:

  • null (default) will connect stream to a terminal (as specified by the terminal launch property)1.
  • "/some/path" will cause stream to be redirected to the specified file, pipe or a TTY device 2.

For example, "stdio": [null, null, "/tmp/my.log"] will connect stdin and stdout to a terminal, while sending stderr to the specified file.

  • A scalar value will configure all three streams identically: "stdio": null.
  • You may also use dictionary syntax: "stdio": { "stdin": null, "stdout": null, "stderr": "/tmp/my.log" }.

1 On Windows debuggee is always launched in a new window, however stdio streams may still be redirected as described above.
2 Use tty command inside a terminal window to find out its TTY device path.

Attaching

Note that attaching to a running process may be restricted on some systems. You may need to adjust system configuration to enable it.

parameter type req
name string Y Launch configuration name.
type string Y Set to lldb.
request string Y Set to attach.
program string Y Path to debuggee executable.
pid number Process id to attach to. pid may be omitted, in which case debugger will attempt to locate an already running instance of the program. You may also put ${command:pickProcess} or ${command:pickMyProcess} here to choose a process interactively.
stopOnEntry boolean Whether to stop the debuggee immediately after attaching.
waitFor boolean Wait for the process to launch.
initCommands [string] LLDB commands executed upon debugger startup.
preRunCommands [string] LLDB commands executed just before attaching to the debuggee.
postRunCommands [string] LLDB commands executed just after attaching to the debuggee.
exitCommands [string] LLDB commands executed at the end of debugging session.
expressions string The default expression evaluator type: simple, python or native. See Expressions.
sourceMap dictionary See Source Path Remapping.
sourceLanguages A list of source languages used in the program. This is used to enable language-specific debugger features.

Custom Launch

The custom launch method puts you in complete control of how debuggee process is created. This happens in three steps:

  1. initCommands sequence is executed. It is responsible for creation of the debug target.
  2. Debugger configures breakpoints using target created in step 1.
  3. preRunCommands sequence is executed. It is responsible for creation of (or attaching to) the debuggee process.
parameter type req
name string Y Launch configuration name.
type string Y Set to lldb.
request string Y Set to custom.
targetCreateCommands [string] Commands that will create debug target.
processCreateCommands [string] Commands that will create debuggee process.
exitCommands [string] LLDB commands executed at the end of debugging session.
expressions string The default expression evaluator type: simple, python or native. See Expressions.
sourceMap dictionary See Source Path Remapping.
sourceLanguages A list of source languages used in the program. This is used to enable language-specific debugger features.

Remote debugging

For general information on remote debugging please see LLDB Remote Debugging Guide.

Connecting to lldb-server agent

  • Run lldb-server platform --server --listen *:<port> on the remote machine.
  • Create launch configuration similar to this:
{
    "name": "Remote launch",
    "type": "lldb",
    "request": "launch",
    "program": "${workspaceFolder}/build/debuggee", // Local path.
    "initCommands": [
        "platform select <platform>",
        "platform connect connect://<remote_host>:<port>"
    ],
}

See platform list for a list of available remote platform plugins.

  • Start debugging as usual. The executable identified in the program property will be automatically copied to lldb-server's current directory on the remote machine. If you require additional configuration of the remote system, you may use preRunCommands script to execute commands such as platform mkdir, platform put-file, platform shell, etc. (See help platform for a list of available platform commands).

Connecting to gdbserver agent

  • Run gdbserver *:<port> <debuggee> <debuggee args> on the remote machine.
  • Create a custom launch configuration:
{
    "name": "Remote attach",
    "type": "lldb",
    "request": "custom",
    "targetCreateCommands": ["target create ${workspaceFolder}/build/debuggee"],
    "processCreateCommands": ["gdb-remote <remote_host>:<port>"]
}
  • Start debugging.

Loading a Core Dump

Use custom launch with target crate -c <core path> init command:

{
    "name": "Core dump",
    "type": "lldb",
    "request": "custom",
    "targetCreateCommands": ["target create -c ${workspaceFolder}/core"],
}

Source Path Remapping

Source path remapping is helpful in cases when program's source code is located in a different directory then it was in during the build (for example, if a build server was used).

A source map consists of pairs of "from" and "to" path prefixes. When the debugger encounters a source file path beginning with one of the "from" prefixes, it will substitute the corresponding "to" prefix instead. Example:

    "sourceMap": { "/old/path/*/to/source/" : "/the/new/source/path/" }
  • "from" prefixes may contain shell globs (?, *, [abc], [!abc]). If you need to use one of the meta-characters verbatim, enclose it in brackets ([?] matches ?).
  • "to" prefixes may be null, which will cause CodeLLDB to ignore matching source files.

Parameterized Launch Configurations

Sometimes you'll find yourself adding the same parameters (e.g. a path of a dataset directory) to multiple launch configurations over and over again. CodeLLDB provides a feature to help with configuration management in such cases: you may put common configuration values in lldb.dbgconfig section of your workspace configuration, and then reference them using ${dbgconfig:variable} syntax in your launch configurations:

// settings.json
...
    "lldb.dbgconfig":
    {
        "dateset": "dataset1",
        "datadir": "${env:HOME}/mydata/${dbgconfig:dataset}" // "dbgconfig" properties may reference each other,
                                                             // as long as there is no recursion.
    }

// launch.json
...
    {
        "name": "Debug program",
        "type": "lldb",
        "program": "${workspaceFolder}/build/bin/program",
        "cwd": "${dbgconfig:datadir}" // will be expanded to "/home/user/mydata/dataset1"
    }

Debugger Features

Commands

Show Disassembly ... Choose when the disassembly view is shown. See Disassembly View.
Toggle Disassembly Choose when the disassembly view is shown. See Disassembly View.
Display Format ... Choose default variable display format. See Formatting.
Toggle Numeric Pointer Values Choose whether to display the pointee's value rather than numeric value of the pointer itself. See Pointers.
Toggle Container Summaries Choose whether CodeLLDB should generate summaries of compound objects, for which there is no built-in support.
Note that having this on may slow down line stepping, because more data needs to be examined to generate the variables view.
Run Diagnostics Run diagnostic on LLDB, to make sure it can be used with this extension. The command is executed automatically the first time when CodeLLDB is used.

Regex Breakpoints

Function breakpoints prefixed with '/re', are interpreted as regular expressions. This causes a breakpoint to be set in every function matching the expression. The list of created breakpoint locations may be examined using break list command.

Conditional Breakpoints

You may use any of the supported expression syntaxes to create breakpoint conditions. When a breakpoint condition evaluates to False, the breakpoint will not be stopped at. Any other value (or expression evaluation error) will cause the debugger to stop.

Disassembly View

When execution steps into code for which debug info is not available, CodeLLDB will automatically switch to disassembly view. This behavior may be controlled using Show Disassembly and Toggle Disassembly commands. The former allows to choose between never, auto (the default) and always, the latter toggles between auto and always.

While is disassembly view, 'step over' and 'step into' debug actions will perform instruction-level stepping rather than source-level stepping.

disassembly view

Formatting

You may change the default display format of evaluation results using the Display Format command.

When evaluating expressions in Debug Console or in Watch panel, you may control formatting of individual expressions by adding one of the suffixes listed below. For example evaluation of var,x will display the value of var formatted as hex.

suffix format
x Hex
o Octal
d Decimal
u Unsigned decimal
b Binary
f Float (reinterprets bits, no casting is done)
p Pointer
s C string
y Bytes
Y Bytes with ASCII

Pointers

When displaying pointer and reference variables, CodeLLDB will prefer to display the value of the object pointed to. If you would like to see the raw address value, you may toggle this behavior using Toggle Numeric Pointer Values command. Another way to display raw pointer address is to add the pointer variable to Watch panel and specify an explicit format, as described in the previous section.

LLDB Commands

To access LLDB features not exposed via the VS Code UI, you may enter LLDB commands directly into the Debug Console.

If you would like to evaluate an expression instead, prefix it with '?', e.g. ?a+b.

Expressions

CodeLLDB implements three expression evaluator types: "simple", "python" and "native". These are used wherever user-entered expression needs to be evaluated: in "Watch" panel, in the Debug Console (for input prefixed with ?) and in breakpoint conditions.
By default, "simple" is assumed, however you may change this using the expressions launch configuration property. The default type may also be overridden on a per-expression basis by using a prefix.

Simple expressions

Prefix: /se
Simple expressions consist of debuggee's variables (local or static), Python operators, as well as operator keywords and, or, not. No other Python keywords are allowed. The values of debuggee variables are obtained through LLDB data formatters, thus if you have formatters installed for specific library types, they will work as expected. For example, things like indexing an std::vector with an integer, or comparing std::string to a string literal should just work.
Variables, whose names are not valid Python identifiers may be accessed by escaping them with ${...}.

Python expressions

Prefix: /py
Python expressions use normal Python syntax. In addition to that, any identifier prefixed with $ (or enclosed in ${...}), will be replaced with the value of the corresponding debuggee variable. Such values may be mixed with regular Python variables. For example, /py [math.sqrt(x) for x in $a] will evaluate to a list containing square roots of values contained in debuggee's array a.

Native expressions

Prefix: /nat
These use LLDB built-in expression evaluators. The specifics depend on source language of the current debug target (e.g. C, C++ or Swift).
For example, the C++ expression evaluator offers many powerful features including interactive definition of new data types, instantiation of C++ classes, invocation of functions and class methods, and more.

Note, however, that native evaluators ignore data formatters and operate on "raw" data structures, thus they are often not as convenient as "simple" or "python" expressions.

Debugger API

CodeLLDB provides a Python API via the debugger module (which is auto-imported into debugger's main script context).

debugger.evaluate(expression: str) -> Value

Allows dynamic evaluation of simple expressions.

debugger.unwrap(obj: Value) -> lldb.SBValue

Extract lldb.SBValue from result of evaluation of a simple expression.

debugger.wrap(obj: lldb.SBValue) -> Value

Converts lldb.SBValue to an object the may be used in simple expressions.

debugger.stop_if(condition: bool, handler: Callable[]) -> bool

If condition evaluates to True, executes the handler function and returns True. Otherwise, returns False.
This function is handy when creating conditional breakpoints with side effects. For example, this breakpoint condition: /py debugger.stop_if($x % 50 == 0, lambda: print($y)) will cause a stop when variable x becomes a multiple of 50 and will print the value of variable y.

debugger.display_html(uri: str, title: str=None, position: int=None, content: Dict[string, string]={})

Displays HTML content in VSCode UI.

  • url: URL of the main content. Most likely you'll want to use a debugger: URL.
  • title: Title of the HTML view tab.
  • position: Position of the tab. The allowed range is 1 through 3.
  • content: A dictionary of static content indexed by URLs. All keys must use the debugger: URL scheme. All values must be strings (binary content such as images is not supported).

debugger.register_content_provider(provider: Callable[[string],string])

Allows generation of dynamic content for HTML display. Any debugger: content not found in the content dictionary, will be directed to provider callback, which takes a URL parameter and returns content as a string.

Rust Language Support

CodeLLDB supports visualization of most common Rust data types:

  • Built-in types: tuples, enums, arrays, array and string slices.
  • Standard library types: Vec, String, CString, OSString.

To enable this feature, add "sourceLanguages": ["rust"] into your launch configuration.

Note: There is a known incompatibility of debug info emitted by rustc and LLDB 3.8: you won't be able to step through code or inspect variables if you have this version. The workaround is to use either LLDB 3.7 or 3.9. On macOS, LLDB shipped with Xcode 8 is known to have this problem fixed.

source

Cargo support

Several Rust users had pointed out that debugging tests and benches in Cargo-based projects is somewhat difficult since names of the output test/bench binary generated by Cargo is not deterministic. To cope with this problem, CodeLLDB can now query Cargo for names of the compilation artifacts. In order to use this feature, replace program property in your launch configuration with cargo:

{
    "type": "lldb",
    "request": "launch",
    "cargo": {
        "args": ["test", "--no-run", "--lib"], // Cargo command line to build the debug target
        // "args": ["build", "--bin=foo"] is another possibility
        "filter": { // Filter applied to compilation artifacts (optional)
            "name": "mylib",
            "kind": "lib"
        }
    }
}

Try to be as specific as possible when specifying the build target, because if there's more than one binary output, CodeLLDB won't know which one you want to debug!

Normally, Cargo output will be used to set the program property (but only if it isn't defined). However, in order to support custom launch and other odd-ball scenarios, there is also a substitution variable, which expands to the same thing: ${cargo:program}.

CodeLLDB will also use Cargo.toml in the workspace root to generate initial debug configurations (if there is no launch.json in the workspace).

Workspace Configuration

General

lldb.executable Path to debugger executable. (default="lldb")
lldb.executable_env Environment variables to pass to debugger. You may refer to existing environment variables using ${env:NAME} syntax, for example "PATH" : "${env:HOME}/bin:${env:PATH}".
lldb.logLevel Logging level as defined by Python's 'logging' module.
lldb.logFile Name of the file to write log to (instead of sending it to VSCode's output panel).
lldb.dbgconfig See Parameterized Launch Configurations.
lldb.evaluationTimeout Timeout for expression evaluation, in seconds (default=5s).
lldb.suppressMissingSourceFiles Suppress VSCode's missing source file messages (requires probing for existence of the source file).
lldb.reverseDebugging Enable reverse debuggee execution. (Experimental! Works with gdb-server and rr backends only!)

Default launch configuration settings

lldb.launch.initCommands Commands executed before initCommands in individual launch configurations.
lldb.launch.preRunCommands Commands executed before preRunCommands in individual launch configurations.
lldb.launch.exitCommands Commands executed after exitCommands in individual launch configurations.
lldb.launch.env Additional environment variables that will be merged with 'env' of individual launch configurations.
lldb.launch.cwd Default program working directory.
lldb.launch.stdio Default stdio destination.
lldb.launch.terminal Default terminal type.
lldb.launch.sourceMap Additional entries that will be merged with 'sourceMap's of individual launch configurations.
lldb.launch.sourceLanguages A list of source languages used in the program. This is used to enable language-specific debugger features.