断点会在代码执行时停止执行。如需创建断点,请使用 break
命令并为其指定断点位置。
例如,如需在 main
函数上创建断点,请使用以下代码:
break main
Breakpoint 3 (Software) on Global, Enabled, stop=All, @ main
180
◉ 181 int main(int argc, char**argv) {
182 fbl::unique_fd dirfd;
在 zxdb 中,您可以通过多种方式表达断点。例如:
函数名称
您可以指定一个函数名称,该名称与任何命名空间中的同名函数匹配:
break main
成员函数
您可以在特定命名空间或类中指定成员函数或函数:
break my_namespace::MyClass::MyFunction
[zxdb] break ::OtherFunction
来源和行
您还可以指定要中断的源文件和行号:
break mymain.cc:22
行号
您可以指定当前帧的当前源文件中的行号。在浏览代码时,这非常有用:
break 23
内存地址
您可以指定内存地址:
break 0xf72419a01
表达式
您可以指定一个表达式,如需详细了解 zxdb 中的表达式,请参阅评估表达式。使用 *
作为前缀会将后续的输入视为一个表达式,该表达式会求值为特定地址。在使用硬件断点时,这非常有用。
break --type=write *&foo
列出断点
如需查看所有断点,请使用 breakpoint
:
breakpoint
# scope stop enabled type #addrs hit-count location
▶ 3 global all false software 1 0 machine.h:7
移除断点
如需移除特定断点,请将该断点编号作为 breakpoint <index> rm
的上下文。
例如,如需清除 breakpoint 3
,请执行以下命令:
breakpoint 3 rm
Removed Breakpoint 3 enabled=false @ machine.h:7
清除断点
如需移除特定位置的所有断点,您无需指定索引:
clear
当您创建断点或在断点上停止时,该断点会自动成为默认断点。每当您在不指定索引的情况下运行 clear
时,该命令都会清除您触发的最新断点。
clear
还可以接受可选位置,就像 break
命令一样。这样,它会尝试清除该位置的所有断点,并忽略默认断点上下文。
停用断点
例如,如需停用断点 3
,请执行以下操作:
breakpoint 3 disable
Disabled Breakpoint 3 enabled=false @ machine.h:7
35 static constexpr SizeType InitialStackPointer(SizeType base, SizeType size) {
36 // Stacks grow down on most machines.
◯ 37 return (base + size) & -kStackAlignment<SizeType>;
38 }
39 };
如需停用当前断点,请执行以下操作:
disable
Disabled Breakpoint 2 enabled=false @ main.rs:5
24
25 enum Services {
◯ 26 ComponentRunner(frunner::ComponentRunnerRequestStream),
27 StarnixManager(fstarnixrunner::ManagerRequestStream),
28 AttributionProvider(fattribution::ProviderRequestStream),
启用断点
停用断点后,您可能需要重新启用已停用的断点。
例如,如需启用断点 3
,请执行以下命令:
breakpoint 3 enable
Enabled Breakpoint 3 @ machine.h:7
35 static constexpr SizeType InitialStackPointer(SizeType base, SizeType size) {
36 // Stacks grow down on most machines.
◉ 37 return (base + size) & -kStackAlignment<SizeType>;
38 }
39 };
设置和获取断点属性
您还可以使用 get
和 set
命令修改断点属性。
例如,如需从断点 4
检索 location
属性,请执行以下操作:
breakpoint 4 get location
location (locations)
The location (symbol, line number, address, or expression) where this
breakpoint will be set. See "help break" for documentation on how to specify.
location = machine.h:7
例如,如需将断点 4
的 location
属性设置为 machine.h:8
,请执行以下操作:
breakpoint 4 set location = machine.h:8
Set breakpoint 4 location = machine.h:8
条件断点
您还可以将断点配置为具有条件。条件是计算结果为 true
或 false
的表达式。设置条件后,除非此条件为 true
,否则断点不会触发停止。
例如,如果您要调试 cobalt.cm
组件,请执行以下操作:
例如,如需添加 main.cc:352
的条件断点位置,请执行以下操作:
[zxdb] b main.cc:352 if command_line.has_argv0 == false
Created Breakpoint 1 condition="command_line.has_argv0 == false" @ ../../src/myapp/bin/app/main.cc:352
351 }
◉ 352 inspector.Health().Ok();
353 loop.Run();
354 FX_LOGS(INFO) << "Cobalt will now shut down.";
硬件数据断点
在 zxdb 中,硬件断点会作为一种断点而非单独的监视点进行公开。
处理器可设置为在读取或写入特定地址时中断执行。这对于跟踪内存损坏很有用。
当您为 break
命令的 type
属性使用以下任一值时,便可以创建硬件断点。
execute
write
read-write
例如,如需设置类型为 execute
的断点,请使用以下代码:
break --type=execute myfile.rs:123
watch
与使用 break --type=read-write
相同。请参阅 watch
命令。
watch
命令
作为快捷方式,watch
命令会获取变量的内容或表达式的结果,并在其范围内设置数据写入断点:
watch i
[zxdb] watch foo[5]->bar
如果您对栈上的变量执行 watch
操作,并且没有人再触碰它,那么当栈内存被重复使用时,您通常会在程序的其他部分看到该变量。如果您遇到意外的断点命中,请检查执行是否仍在预期的帧中。
程序化断点
在某些情况下,您可能需要捕获代码中的特定条件。为此,您可以在代码中插入硬编码断点。
Clang 具有以下内置功能:
__builtin_debugtrap();
如果 zxdb 已附加到进程,则会像遇到常规断点一样停止。然后,您可以在此处执行 step
或 continue
。如果调试程序尚未附加,这将导致崩溃。