使用 zxdb 时,您可以控制线程的执行以便进行调试。 在调试时,您可以使用以下工具来控制执行:
线程
线程是进程中的执行单元。它代表 可以单独执行的指令序列。
要通过 zxdb 中的线程控制执行,请参阅线程。
堆栈帧
堆栈帧是调用堆栈的一部分, 调用该方法。它会存储函数执行所需的信息,例如:
- 局部变量:在函数中声明的变量。
- 参数:传递给函数的值。
- 返回地址:在代码中经过 函数完成。
要通过 zxdb 中的堆栈帧控制执行,请参见 堆栈帧:
线程
在 zxdb 中,thread
是可与 zxdb 搭配使用的名词
动词。
如需列出当前进程中的线程,请执行以下操作:
[zxdb] thread
# State Koid Name
▶ 1 Blocked 1323 initial-thread
2 Running 3462 worker-thread
在某些情况下,您可能会发现某个线程被标记为 Blocked
,这意味着
表示线程在系统调用时停止。通常,当您
异步应用,这也可以指示等待时间。
线程控制命令仅适用于已暂停的线程,不适用于阻塞或正在运行的线程 线程。挂起线程有以下几种方法:
pause
消息串
例如,如需使用 pause
命令挂起线程 2
,请使用以下命令:
[zxdb] thread 2 pause
🛑 syscalls-x86-64.S:67
65 m_syscall zx_port_create 60 2 1
66 m_syscall zx_port_queue 61 2 1
▶ 67 m_syscall zx_port_wait 62 3 0
68 m_syscall zx_port_cancel 63 3 1
69 m_syscall zx_timer_create 64 3 1
当线程暂停时,zxdb 会显示当前源代码位置。如果会话串 进行系统调用时(如上例所示),则源代码位置将解析为 与生成系统时使用的汇编语言宏文件中的位置有关 调用。
如果您在没有任何其他上下文的情况下运行 pause
,则 zxdb 会暂停
当前挂接的所有进程
例如:
[zxdb] pause
508 const zx_port_packet_t* packet))
509
▶ 510 BLOCKING_SYSCALL(port_wait, zx_status_t, /* no attributes */, 3, (handle, deadline, packet),
511 (_ZX_SYSCALL_ANNO(use_handle("Fuchsia")) zx_handle_t handle, zx_time_t deadline,
512 zx_port_packet_t* packet))
🛑 $elf(SYSCALL_zx_port_wait) + 0x7 • syscalls.inc:510
continue
消息串
暂停讨论帖并开始调试问题后,您可能需要
continue
线程。“继续”表示继续执行,直到您的程序
以便正常运行。
例如,对于 continue
线程 1
:
[zxdb] thread 1 continue
如果您在没有任何其他上下文的情况下运行 continue
,zxdb 会继续
所有附加进程的线程。
例如:
[zxdb] continue
单步调试线程
线程暂停后,您可以控制其执行。您可以使用 命令:
finish
(fi
)退出函数并在调用后立即停止。
[zxdb] finish
next
(n
)跳转至下一行,跳过函数调用。
[zxdb] next
nexti
前进到下一条说明,但跳过了通话说明中 目标架构。
[zxdb] nexti
ss
列出当前行上的函数调用,然后单步进入所选的调用。这个 自动完成最先发生的任何其他调用。
[zxdb] ss 1 std::string::string 2 MyClass::MyClass 3 HelperFunctionCall 4 MyClass::~MyClass 5 std::string::~string quit >
step
(s
)前进到下一个代码行。如果函数调用发生在 该函数会单步进入,并在 该函数的开头。
您还可以提供一个参数子字符串来匹配特定的函数调用。 系统会跳过不包含参数子字符串的函数名称, 只有匹配的函数会单步进入。
[zxdb] step [zxdb] step MyFunction
stepi
前进一个机器指令。
[zxdb] stepi
until
(u
)给定代码行位置后,继续执行线程,直至执行到达该位置。对于 例如,运行到当前文件的第
45
行:[zxdb] until 45
您也可以一直运行,直到执行返回到给定堆栈帧:
[zxdb] frame 2 until
堆栈帧
堆栈帧是一种函数调用。当一个函数调用另一个函数时, 帧。列出线程的帧会返回调用堆栈。
如需列出当前线程中的堆栈帧,请执行以下操作:
[zxdb] frame
▶ 0 fxl::CommandLineFromIterators<const char *const *>() • command_line.h:203
1 fxl::CommandLineFromArgcArgv() • command_line.h:224
2 main() • main.cc:174
当您处理堆栈帧时,0
表示堆栈的顶端,
表示执行的结束。堆栈的底部,
最高的堆栈帧号,表示开始执行。
浏览堆栈帧
您可以使用 up
和 down
命令在帧列表中导航。
例如,使用 up
从当前帧 0
导航到帧 1
:
[zxdb] up
1 fxl::CommandLineFromIterators<const char *const *>() • command_line.h:204
例如,使用 down
从当前帧 1
导航到帧 0
:
[zxdb] down
0 fxl::CommandLineFromIteratorsFindFirstPositionalArg<const char *const *>() • command_line.h:185
您也可以使用 frame
命令和
帧号:
[zxdb] frame 1
使用 backtrace
了解更多详情
在某些情况下,您可能希望看到
堆栈帧所不具备的优点backtrace
命令与 frame
完全相同,但
可提供更详细的地址信息以及函数参数。
列出当前线程中的堆栈帧,但包含更详细的
信息,请使用 backtrace
:
[zxdb] backtrace
▶ 0 fxl::CommandLineFromIteratorsFindFirstPositionalArg<const char *const *>() • 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. >
...
使用 list
查看源代码
每个堆栈帧都有一个代码位置。使用 list
命令查看
源代码。
您可以列出特定堆栈帧的指令指针周围的代码。
例如,如需对堆栈指令指针周围的源代码执行 list
操作,
画面 3
:
[zxdb] frame 3 list
在没有上下文的情况下使用 list
时,zxdb 会列出源代码
当前堆栈帧的指令指针周围:
[zxdb] list
183 inline CommandLine CommandLineFromIteratorsFindFirstPositionalArg(
184 InputIterator first, InputIterator last,
▶ 185 InputIterator* first_positional_arg) {
186 if (first_positional_arg)
187 *first_positional_arg = last;
list
的其他用例
此外,您还可以使用 list
列出特定内容:
函数
使用 list
列出函数:
[zxdb] list MyClass::MyFunc
文件
使用 list
列出特定文件:
[zxdb] list --all myfile.cc:1
包含行号的文件
使用 list
可列出具有特定行号的特定文件:
[zxdb] list foo.cc:43