使用断点

断点会在执行代码时停止执行。如需创建断点,请使用 break 命令,并指定一个要中断的位置。

例如,如需在 main 函数上创建断点,请使用以下代码:

[zxdb] 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 中,有几种表示断点的方法。例如:

函数名称

您可以指定函数名称,该函数名称与 任何命名空间:

[zxdb] break main

成员函数

您可以指定特定命名空间内的一个或多个成员函数 或类:

[zxdb] break my_namespace::MyClass::MyFunction
[zxdb] break ::OtherFunction

来源和代码行

您还可以指定源文件和要换行的行号:

[zxdb] break mymain.cc:22

行号

您可以在当前帧的当前源中指定行号 文件。在单步调试代码时,这非常有用:

[zxdb] break 23

内存地址

您可以指定内存地址:

[zxdb] break 0xf72419a01

表达式

您可以指定表达式,请参阅评估表达式 有关 zxdb 中的表达式的详情。使用前缀 * 作为前缀将处理 一个输入,后跟一个求特定地址的表达式。 当您使用硬件断点时,这会非常有用。

[zxdb] break --type=write *&foo

列出断点

如需查看所有断点,请使用 breakpoint

[zxdb] breakpoint
  # scope  stop enabled type     #addrs hit-count location
▶ 3 global all  false   software      1         0 machine.h:7

移除断点

要移除特定断点,请将该断点索引指定为 breakpoint <index> rm

例如,如需清除 breakpoint 3,请运行以下命令:

[zxdb] breakpoint 3 rm
Removed Breakpoint 3 enabled=false @ machine.h:7

清除断点

要删除特定位置的所有断点,您不需要指定 索引:

[zxdb] clear

当您在某个断点上创建或停止时,该断点将成为默认断点 。每当您在没有特定索引的情况下运行 clear 时,命令 清除您遇到的最新断点。

clear 也可以采用可选位置,就像 break 命令一样。在本课中, 它就会尝试清除该位置的所有断点,并忽略 默认断点上下文。

停用断点

例如,如需停用断点 3,请运行以下命令:

[zxdb] 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 };

如需停用当前断点,请执行以下操作:

[zxdb] 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,请运行以下命令:

[zxdb] 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 };

设置和获取断点属性

您还可以使用 getset 命令修改断点属性。

例如,如需从断点 4 中检索 location 属性,请使用以下代码:

[zxdb] 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

例如,如需将 location 属性从断点 4 设置为 machine.h:8,请使用以下代码:

[zxdb] breakpoint 4 set location = machine.h:8
Set breakpoint 4 location = machine.h:8

条件断点

您还可以将断点配置为设置条件。条件是 计算结果为 truefalse 的表达式。当您设置 有条件地,那么除非此条件语句,否则该断点不会触发停止 为 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

例如,如需设置 execution 类型的断点,请使用以下代码:

[zxdb] break --type=execution myfile.rs:123

watch 与使用 break --type=read-write 相同。请参阅 watch 命令

watch 命令

作为一种捷径,watch 命令接受变量的内容或 并在其范围内设置数据写入断点:

[zxdb] watch i
[zxdb] watch foo[5]->bar

如果您对堆栈上的某个变量使用 watch,但无人触及该变量,通常会导致 在堆栈内存被重复使用时,它会在程序的其他部分遇到。 如果您遇到意外的断点,请检查执行是否仍在 帧。

程序化断点

在某些情况下,您可能需要在代码中捕获特定条件。操作步骤 则可以在代码中插入一个硬编码的断点。

Clang 拥有内置功能:

__builtin_debugtrap();

如果 zxdb 已附加到进程,则会像正常情况下一样停止。 断点。然后,您可以从中stepcontinue。如果 调试程序,这会导致崩溃。