Skip to content

5 Stopping and Continuing

5.1 Breakpoints, Watchpoints, and Catchpoints

名称 说明 command
breakpoint A breakpoint makes your program stop whenever a certain point(location) in the program is reached. break
watchpoint A watchpoint is a special breakpoint that stops your program when the value of an expression changes. watch
catchpoint A catchpoint is another special breakpoint that stops your program when a certain kind of event occurs, such as the throwing of a C++ exception or the loading of a library. catch

info break

5.1.4 Deleting Breakpoints节

5.1.1 Setting Breakpoints

ccomand 说明
break location
break When called without any arguments, break sets a breakpoint at the next instruction to be executed in the selected stack frame
break ... if cond Set a breakpoint with condition cond; 具体用法参见下面的example
tbreak args Set a breakpoint enabled only for one stop temporary breakpoint
hbreak args Set a hardware-assisted breakpoint.
thbreak args Set a hardware-assisted breakpoint enabled only for one stop.
rbreak regex Set breakpoints on all functions matching the regular expression regex.
rbreak file:regex If rbreak is called with a filename qualification, it limits the search for functions matching the given regular expression to the specified file.

Example

break ... if cond

stackoverflow GDB: break if variable equal value回答 给出了它的用法:

in addition to a watchpoint nested inside a breakpoint you can also set a single breakpoint on the 'filename:line_number' and use a condition. I find it sometimes easier.

(gdb) break iter.c:6 if i == 5
Breakpoint 2 at 0x4004dc: file iter.c, line 6.
(gdb) c
Continuing.
0
1
2
3
4

Breakpoint 2, main () at iter.c:6
6           printf("%d\n", i);

If like me you get tired of line numbers changing, you can add a label then set the breakpoint on the label like so:

#include <stdio.h>
main()
{ 
     int i = 0;
     for(i=0;i<7;++i) {
       looping:
        printf("%d\n", i);
     }
     return 0;
}

(gdb) break main:looping if i == 5

5.1.2 Setting Watchpoints

Example

stackoverflow GDB: break if variable equal value:

#include <stdio.h>
main()
{ 
     int i = 0;
     for(i=0;i<7;++i)
        printf("%d\n", i);

     return 0;
}

A

You can use a watchpoint for this (A breakpoint on data instead of code).

You can start by using watch i. Then set a condition for it using condition <breakpoint num> i == 5

You can get the breakpoint number by using info watch

5.1.3 Setting Catchpoints

catch event
event 命令格式 语言 说明
throw、rethrow、catch cat event [regexp] C++ The throwing, re-throwing, or catching of a C++ exception
exception Ada An Ada exception being raised
exception unhandled Ada
assert Ada
exec
syscall [name|number|group:groupname |g:groupname ] A call to or return from a system call, a.k.a. syscall.
fork A call to fork.
vfork A call to vfork.
load [regexp]unload [regexp] The loading or unloading of a shared library
signal [signal... | all ] The delivery of a signal.

Example

找出抛出异常的语句
$ gdb a.out
(gdb) catch throw
Function "__cxa_throw" not defined.
Catchpoint 1 (throw)
(gdb) r
[New Thread 0x7ffff7ff0700 (LWP 3121)]
[New Thread 0x7ffff5f53700 (LWP 3122)]
tcp://127.0.0.1:8001
[New Thread 0x7ffff5752700 (LWP 3123)]
[New Thread 0x7ffff4f51700 (LWP 3124)]
[New Thread 0x7ffff4daf700 (LWP 3125)]
[Switching to Thread 0x7ffff5752700 (LWP 3123)]
Catchpoint 1 (exception thrown), 0x00007ffff6eb2920 in __cxa_throw () from /usr/lib64/libstdc++.so.6
Missing separate debuginfos, use: debuginfo-install glibc-2.17-196.el7.x86_64 libgcc-4.8.5-39.el7.x86_64 libstdc++-4.8.5-39.el7.x86_64
(gdb) bt
#0  0x00007ffff6eb2920 in __cxa_throw () from /usr/lib64/libstdc++.so.6
#1  0x00007ffff72f060e in CppSQLite3DB::open (this=<optimized out>, szFile=<optimized out>) at ./cpp_sqlite3/CppSQLite3.cpp:1216
#2  0x00007ffff7297651 in CHSInsTradeApiCacheService_ust::ApiPushCacheInit (this=0x63a760, 
    cacheFileName=cacheFileName@entry=0x7ffff573e400 "./log/STOCKOPT_HSINSAPI_20200730_1082", svrMaxSerialno=1998)
    at trade_api_cache.cpp:250

通过bt来查看stack frame,frame #1指示了抛出exception的语句;

catch syscall
(gdb) catch syscall
Catchpoint 1 (syscall)
(gdb) r
Starting program: /tmp/catch-syscall
Catchpoint 1 (call to syscall ’close’), \
0xffffe424 in __kernel_vsyscall ()
(gdb) c
Continuing.
Catchpoint 1 (returned from syscall ’close’), \
0xffffe424 in __kernel_vsyscall ()
(gdb)
catch syscall chroot
(gdb) catch syscall chroot
Catchpoint 1 (syscall ’chroot’ [61])
(gdb) r
Starting program: /tmp/catch-syscall
Catchpoint 1 (call to syscall ’chroot’), \
0xffffe424 in __kernel_vsyscall ()
(gdb) c
Continuing.
Catchpoint 1 (returned from syscall ’chroot’), \
0xffffe424 in __kernel_vsyscall ()
(gdb)

5.1.4 Deleting Breakpoints

clear

5.1.6 Break Conditions

The simplest sort of breakpoint breaks every time your program reaches a specified place. You can also specify a condition for a breakpoint. A condition is just a Boolean expression in your programming language (see Section 10.1 [Expressions], page 117). A breakpoint with a condition evaluates the expression each time your program reaches it, and your program stops only if the condition is true.

Break Condition VS assertion

...

Break Condition VS watchpoint

...

Break conditions can be specified when a breakpoint is set, by using ‘if’ in the arguments to the break command. See Section 5.1.1 [Setting Breakpoints], page 46. They can also be changed at any time with the condition command.

You can also use the if keyword with the watch command. The catch command does not recognize the if keyword; condition is the only way to impose a further condition on a catchpoint.

condition bnum expression

Specify expression as the break condition for breakpoint, watchpoint, or catchpoint number bnum.

condition bnum

Remove the condition from breakpoint number bnum.

Example: specify a condition on an existing breakpoint

文章fayewilliams GDB Conditional Breakpoints中给出了一些例子:

example: specify a condition on an existing breakpoint by using the breakpoint number as a reference

You can also specify a condition on an existing breakpoint by using the breakpoint number as a reference:

cond 3 i == 99
cond 3

Example: break if variable equal value

GDB Conditional Breakpoints中给出的例子:

b Message.cpp:112 if i == 99

我的实践:

b CHQImpl::DealMessage
info locals
cond 1 nFuncNo=107

上述表达的是:当函数CHQImpl::DealMessage的临时变量nFuncNo的值为107时,则break。

GDB: break if variable equal value中给出的例子:

I like to make GDB set a break point when a variable equal some value I set, I tried this example:

#include <stdio.h>
main()
{ 
     int i = 0;
     for(i=0;i<7;++i)
        printf("%d\n", i);

     return 0;
}

A:

(gdb) break iter.c:6 if i == 5
Breakpoint 2 at 0x4004dc: file iter.c, line 6.
(gdb) c
Continuing.
0
1
2
3
4

Breakpoint 2, main () at iter.c:6
6           printf("%d\n", i);

If like me you get tired of line numbers changing, you can add a label then set the breakpoint on the label like so:

#include <stdio.h>
main()
{ 
     int i = 0;
     for(i=0;i<7;++i) {
       looping:
        printf("%d\n", i);
     }
     return 0;
}

(gdb) break main:looping if i == 5

Example: 更加复杂的条件

GDB Conditional Breakpoints中给出的例子:

Pretty much anything you like! Just write the condition exactly as if you were testing for it in your code, e.g.:

(gdb) cond 1 strcmp(message,"earthquake") == 0
//stop if the array message is equal to 'earthquake'
(gdb) cond 2 *p == 'r'
//stop if the char* pointer p points to the letter 'r'
(gdb) cond 3 num < 0.75
//stop while the float num is less than 0.75

5.1.7 Breakpoint Command Lists

NOTE: 这是automatic gdb debug的基础。

You can give any breakpoint (or watchpoint or catchpoint) a series of commands to execute when your program stops due to that breakpoint. For example, you might want to print the values of certain expressions, or enable other breakpoints.

commands [range...]
... command-list ...
end

Example: print variable

For example, here is how you could use breakpoint commands to print the value of x at entry to foo whenever x is positive.

break foo if x>0
commands
silent
printf "x is %d\n",x
cont
end

Example: compensate for one bug

One application for breakpoint commands is to compensate(偿还) for one bug so you can test for another.

Put a breakpoint just after the erroneous line of code, give it a condition to detect the case in which something erroneous has been done, and give it commands to assign correct values to any variables that need them. End with the continue command so that your program does not stop, and start with the silent command so that no output is produced. Here is an example:

break 403
commands
silent
set x = y + 4
cont
end

5.2 Continuing and Stepping

step vs next

单步执行:

step next
step会进入函数 next不进入函数
逐语句 逐过程

单位

  • 以function为单位 next

  • 以statement/source line为单位 step

  • 以instruction为单位 stepinexti

NOTE: 主要用于debug assembly,关于debug assembly,参见Shell-and-tools\Tools\Debug\GDB\Guide\Debug-assembly.md