Controlling thread execution in zxdb

Threads

To list the current process’ threads (see “Interaction model” above for more):

```none {:.devsite-disable-click-to-copy} [zxdb] thread

State Koid Name

▶ 1 Blocked 1323 initial-thread 2 Running 3462 worker-thread

  1. Often when you attach to a process the thread will be blocked”, meaning it is stopped on a system
  2. call. For asynchronous programs this will typically be some kind of wait.
  3. Most thread control and introspection commands only work when a thread is suspended (not blocked or
  4. running). A thread will be suspended when it is stopped at a breakpoint or crashes. You can
  5. explicitly suspend a thread with the `pause` command:
  6. ```none {:.devsite-disable-click-to-copy}
  7. [zxdb] thread 2 pause
  8. 🛑 syscalls-x86-64.S:67
  9. 65 m_syscall zx_port_create 60 2 1
  10. 66 m_syscall zx_port_queue 61 2 1
  11. ▶ 67 m_syscall zx_port_wait 62 3 0
  12. 68 m_syscall zx_port_cancel 63 3 1
  13. 69 m_syscall zx_timer_create 64 3 1

When a thread is paused the debugger will show the current source code location. Often threads will be in a system call that will resolve to the location in the assembly-language macro file that generated the system call as shown in the above example.

Running pause by itself with no context will pause all threads of all processes currently attached:

```none {:.devsite-disable-click-to-copy} [zxdb] pause

  1. Unpause a thread with `continue`. As before, `continue` with no context will resume all threads:
  2. ```none {:.devsite-disable-click-to-copy}
  3. [zxdb] continue

Or continue a specific thread:

```none {:.devsite-disable-click-to-copy} [zxdb] thread 1 continue

  1. ## Stack frames
  2. A stack frame is a function call. When a function calls another function, a new nested frame is
  3. created. So listing the frames of a thread tells you the call stack. You can only see the stack
  4. frames when a thread is suspended (see Working with threads above).
  5. To list the current threads stack frames (the `f` abbreviation will also work).
  6. ```none {:.devsite-disable-click-to-copy}
  7. [zxdb] frame
  8. ▶ 0 fxl::CommandLineFromIterators<const char *const *>() • command_line.h:203
  9. 1 fxl::CommandLineFromArgcArgv() • command_line.h:224
  10. 2 main() • main.cc:174

And to select a given frame as the default:

```none {:.devsite-disable-click-to-copy} [zxdb] frame 2

  1. Frames are numbered with 0 being the top of the stack. Increasing numbers go backwards in time.
  2. You can use the `up` and `down` commands to navigate the frame list:
  3. ```none {:.devsite-disable-click-to-copy}
  4. [zxdb] up
  5. 1 fxl::CommandLineFromIterators<const char *const *>() • command_line.h:204
  6. [zxdb] down
  7. 0 fxl::CommandLineFromIteratorsFindFirstPositionalArg<const char *const *>() • command_line.h:185

For more context, you can use the backtrace command. This is identical to frame but gives more detailed address information as well as function parameters. This command can be abbreviated bt:

```none {:.devsite-disable-click-to-copy} [zxdb] bt ▶ 0 fxl::CommandLineFromIteratorsFindFirstPositionalArg() • command_line.h:185 IP = 0x10f982cf2ad0, BP = 0x66b45a01af50, SP = 0x66b45a01af38 first = (const char const) 0x59f4e1268dc0 last = (const char const) 0x59f4e1268dc8 first_positional_arg = (const char const**) 0x0 1 fxl::CommandLineFromIterators<const char const *>() • command_line.h:204 IP = 0x10f982cf2ac0, BP = 0x66b45a01af50, SP = 0x66b45a01af40 first = <’first’ is not available at this address. > last = <’last’ is not available at this address. > …

  1. Each stack frame has a code location. Use the `list` command to look at source code. By itself, it
  2. lists the source code around the current stack frames instruction pointer:
  3. ```none {:.devsite-disable-click-to-copy}
  4. [zxdb] list
  5. 183 inline CommandLine CommandLineFromIteratorsFindFirstPositionalArg(
  6. 184 InputIterator first, InputIterator last,
  7. ▶ 185 InputIterator* first_positional_arg) {
  8. 186 if (first_positional_arg)
  9. 187 *first_positional_arg = last;

You can list code around the current instruction pointer of other stack frames, too:

```none {:.devsite-disable-click-to-copy} [zxdb] frame 3 list

  1. Or you can list specific things like functions:
  2. ```none {:.devsite-disable-click-to-copy}
  3. [zxdb] list MyClass::MyFunc

File/line numbers:

```none {:.devsite-disable-click-to-copy} [zxdb] list foo.cc:43

  1. Or whole files:
  2. ```none {:.devsite-disable-click-to-copy}
  3. [zxdb] list --all myfile.cc:1

Stepping a thread

When a thread is suspended (see “Threads” above) you can control its execution:

next / n: Advances to the next line, stepping over function calls.

```none {:.devsite-disable-click-to-copy} [zxdb] n

  1. `step` / `s`: Advances to the next line. If a function call happens before the next line, that
  2. function will be stepped into and execution will stop at the beginning of it. You can also supply an
  3. argument, which is a substring to match of a specific function call. Function names not containing
  4. this substring will be skipped and only matching ones will be stepped into:
  5. ```none {:.devsite-disable-click-to-copy}
  6. [zxdb] s
  7. [zxdb] s MyFunction

ss: List function calls on the current line and step in to the call selected, automatically completing any of the other calls that happen to occur first.

```none {:.devsite-disable-click-to-copy} [zxdb] ss 1 std::string::string 2 MyClass::MyClass 3 HelperFunctionCall 4 MyClass::~MyClass 5 std::string::~string quit >

  1. `finish` / `fi`: Exits the function and stops right after the call.
  2. ```none {:.devsite-disable-click-to-copy}
  3. [zxdb] finish

until / u: Given a location (the same as breakpoints, see above), continues the thread until execution gets there. For example, to run until line 45 of the current file:

```none {:.devsite-disable-click-to-copy} [zxdb] u 45

  1. `jump`: Move the instruction pointer to a new address.
  2. ```none {:.devsite-disable-click-to-copy}
  3. [zxdb] jump 22 // Line number
  4. [zxdb] jump 0x87534123 // Address

To run until execution gets back to a given stack frame:

none {:.devsite-disable-click-to-copy} [zxdb] frame 2 until