Breakpoints stop execution when code is executed. To create a breakpoint, use the break
command and give it a location to break.
For example, to create a breakpoint on the main
function:
break main Breakpoint 3 (Software) on Global, Enabled, stop=All, @ main 180 ◉ 181 int main(int argc, char**argv) { 182 fbl::unique_fd dirfd;
There are several ways to express a breakpoint in zxdb. For example:
{Function name}
You can specific a function name which matches functions with the name in any namespace:
break main
{Member function}
You can specify a member function or functions inside a specific namespace or class:
break {{"<var>my_namespace</var>"}}::{{"<var>MyClass</var>"}}::{{"<var>MyFunction</var>"}} [zxdb] break ::{{"<var>OtherFunction</var>"}}
{Source and line}
You can also specify a source file and the line number to break on:
Note: Make sure to separate the source file name and line number with a colon.
break mymain.cc:22
{Line number}
You can specify a line number within the current frame’s current source file. This is useful when you are stepping through code:
break 23
{Memory address}
You can specify a memory address:
break 0xf72419a01
{Expression}
You can specify an expression, see Evaluate expressions for more information on expressions in zxdb. Prefixing with *
treats the input that follows as an expression that evaluates to a specific address. This is useful when you work with hardware breakpoints.
break --type=write *&foo
To view all of the breakpoints, use breakpoint
:
Note: This is the breakpoint
noun. You can also use bp
to express breakpoint
.
breakpoint # scope stop enabled type #addrs hit-count location ▶ 3 global all false software 1 0 machine.h:7
To remove a specific breakpoint, give that breakpoint index as the context for the breakpoint <index> rm
.
For example, to clear breakpoint 3
:
breakpoint 3 rm Removed Breakpoint 3 enabled=false @ machine.h:7
Key Point: GDB users: delete <index>
is mapped to breakpoint <index> rm
.
To remove all breakpoints at a particular location, you do not need to specify an index:
clear
When you create or stop on a breakpoint, that breakpoint becomes the default automatically. Whenever you run clear
without a specific index, the command clears the latest breakpoint that you hit.
clear
can also take an optional location just like a break
command. In this way, it will try to clear all breakpoints at that location and ignore the default breakpoint context.
Key Point: GDB users: clear <number>
behaves the same in GDB and zxdb.
For example, to disable breakpoint 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 };
Note: If you do not provide a breakpoint index, the last breakpoint that you hit is used.
To disable the current breakpoint:
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),
After you have disabled a breakpoint, you may want to re-enable the disabled breakpoint.
For example, to enable breakpoint 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 };
You can also modify breakpoint properties with the get
and set
commands.
For example, to retrieve the location
property from breakpoint 4
:
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
For example, to set the location
property from breakpoint 4
to machine.h:8
:
breakpoint 4 set location = machine.h:8 Set breakpoint 4 location = machine.h:8
You can also configure a breakpoint to have conditionals. A conditional is an expression that evaluates to either true
or false
. When you set a conditional, the breakpoint does not trigger a stop unless the this conditional is true
.
For example, if you are debugging the cobalt.cm
component:
For example, to add a conditional breakpoint location of 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.";
In zxdb, hardware breakpoints are exposed as a type of breakpoint rather than as a separate watchpoint.
The processor can be set to break execution when it reads or writes certain addresses. This can be useful to track down memory corruption.
You can create a hardware breakpoint when you use any of the following values for the type
property of a break
command.
execute
write
read-write
For example, to set a breakpoint of type execute
:
break --type=execute myfile.rs:123
A watch
is the same as using break --type=read-write
. See watch
command.
watch
commandAs a shortcut, the watch
command takes the contents of a variable or the result of an expression and set a data write breakpoint over its range:
Note: CPUs only support a limited number of hardware watchpoints, typically around 4.
watch i [zxdb] watch foo[5]->bar
If you watch
a variable on the stack and nobody touches it, you will often see it hit in another part of the program when the stack memory is re-used. If you get a surprising breakpoint hit, check that execution is still in the frame you expect.
Key Point: GDB Users: watch
evaluates the expression once and then sets a breakpoint on the result. It won't re-evaluate the expression. In the above example, it triggers when bar
changes but not if foo[5]
changes to point to a different bar
.
In some cases you may want to catch a specific condition in your code. To do this you can insert a hard coded breakpoint in your code.
Note: This does not work in GCC Zircon builds.
Clang has a built-in:
__builtin_debugtrap();
If zxdb is already attached to the process, it will stop as if a normal breakpoint was hit. You can then step
or continue
from there. If the debugger is not already attached, this will cause a crash.