启动GDB调试 Link to heading
一般来说,GDB主要有四个方面的功能:
1、按照自定义的方式启动运行需要调试的程序。 2、可以使用指定位置和条件表达式的方式来设置断点。 3、程序暂停时的值的监视。 4、动态改变程序的执行环境。
GCC编译器的常用选项
-g:产生符号调试工具(GNU 的 gdb)所必要的符号信息,要想对源代码进行调试,我们就必须加入这个选项,
-g
默认为-g2
。
选项 | 描述 |
---|---|
g1 | 级别1(-g1)不包含局部变量和与行号有关的调试信息,因此只能够用于回溯跟踪和堆栈转储之用。回溯跟踪指的是监视程序在运行过程中的函数调用历史,堆栈转储则是一种以原始的十六进制格式保存程序执行环境的方法,两者都是经常用到的调试手段 |
g2 | 这是默认的级别,此时产生的调试信息包括扩展的符号表、行号、局部或外部变量信息 |
g3 | 包含级别2中的所有调试信息,以及源代码中定义的宏 |
-O:对程序进行优化编译、链接,采用这个选项,整个源代码会在编译、链接过程中进行优化处理,这样产 生的可执行文件的执行效率可以提高,但是,编译、链接的速度就相应地要慢一些。 -O2:比-O 更好的优化编译、链接,当然整个编译、链接过程会更慢。
GDB指令说明 Link to heading
1root@baolong:~/gdb_test# gdb --help
2This is the GNU debugger. Usage:
3
4 gdb [options] [executable-file [core-file or process-id]]
5 gdb [options] --args executable-file [inferior-arguments ...]
6
7Selection of debuggee and its files:
8
9❗ --args Arguments after executable-file are passed to inferior
10❗ --core=COREFILE Analyze the core dump COREFILE.
11 --exec=EXECFILE Use EXECFILE as the executable.
12❗ --pid=PID Attach to running process PID.
13 --directory=DIR Search for source files in DIR.
14 --se=FILE Use FILE as symbol file and executable file.
15 --symbols=SYMFILE Read symbols from SYMFILE.
16 --readnow Fully read symbol files on first access.
17 --readnever Do not read symbol files.
18 --write Set writing into executable and core files.
19
20Initial commands and command files:
21
22 --command=FILE, -x Execute GDB commands from FILE.
23 --init-command=FILE, -ix
24 Like -x but execute commands before loading inferior.
25 --eval-command=COMMAND, -ex
26 Execute a single GDB command.
27 May be used multiple times and in conjunction
28 with --command.
29 --init-eval-command=COMMAND, -iex
30 Like -ex but before loading inferior.
31 --nh Do not read ~/.gdbinit.
32 --nx Do not read any .gdbinit files in any directory.
33
34Output and user interface control:
35
36 --fullname Output information used by emacs-GDB interface.
37 --interpreter=INTERP
38 Select a specific interpreter / user interface
39 --tty=TTY Use TTY for input/output by the program being debugged.
40 -w Use the GUI interface.
41 --nw Do not use the GUI interface.
42 --dbx DBX compatibility mode.
43❗ -q, --quiet, --silent
44 Do not print version number on startup.
45
46Operating modes:
47
48 --batch Exit after processing options.
49 --batch-silent Like --batch, but suppress all gdb stdout output.
50 --return-child-result
51 GDB exit code will be the child's exit code.
52 --configuration Print details about GDB configuration and then exit.
53 --help Print this message and then exit.
54 --version Print version information and then exit.
55
56Remote debugging options:
57
58 -b BAUDRATE Set serial port baud rate used for remote debugging.
59 -l TIMEOUT Set timeout in seconds for remote debugging.
60
61Other options:
62
63 --cd=DIR Change current directory to DIR.
64 --data-directory=DIR, -D
65 Set GDB's data-directory to DIR.
66
67At startup, GDB reads the following init files and executes their commands:
68
69For more information, type "help" from within GDB, or consult the
70GDB manual (available as on-line info or a printed manual).
71Report bugs to "<http://www.gnu.org/software/gdb/bugs/>".
启动gdb后,就你被带入gdb的调试环境中,就可以使用gdb的命令开始调试程序了,gdb的命令可以使用help命令来查看,如下所示:
1(gdb) help
2List of classes of commands:
3
4aliases -- Aliases of other commands
5breakpoints -- Making program stop at certain points
6data -- Examining data
7files -- Specifying and examining files
8internals -- Maintenance commands
9obscure -- Obscure features
10running -- Running the program
11stack -- Examining the stack
12status -- Status inquiries
13support -- Support facilities
14tracepoints -- Tracing of program execution without stopping the program
15user-defined -- User-defined commands
16
17Type "help" followed by a class name for a list of commands in that class.
18Type "help all" for the list of all commands.
19Type "help" followed by command name for full documentation.
20Type "apropos word" to search for commands related to "word".
21Command name abbreviations are allowed if unambiguous.
gdb的命令很多,gdb把之分成许多个种类。help命令只是例出gdb的命令种类,如果要看种类中的命令,可以使用help 命令,如:help breakpoints,查看设置断点的所有命令。也可以直接help 来查看命令的帮助。
gdb中,输入命令时,可以不用打全命令,只用打命令的前几个字符就可以了,当然,命令的前几个字符应该要标志着一个唯一的命令,在Linux下,你可以敲击两次TAB键来补齐命令的全称,如果有重复的,那么gdb会把其例出来。
启动程序调试 Link to heading
(1)一般程序调试
1# gdb -q myprogram // -q 不打印GDB的版本信息
直接运行gdb调试程序。
1(gdb)file myprogram
运行gdb之后再加载待调试程序。
file Link to heading
装载指定的可执行文件进行调试,读取程序的symbols信息。
1(gdb) file calwin.out
2Reading symbols from calwin.out...
(2)调试正在运行的进程
GDB可以对正在执行的程序进行调度,它允许开发人员中断程序并查看其状态,之后还能让这个程序正常地继续执行。GDB提供了两种方式来调试正在运行的进程:一种是在GDB命令行上指定进程的PID,另一种是在GDB中使用“attach”命令。
1# gdb -p PID // myprogram PID
指定PID的进程程序调试
1(gdb)attach PID // myprogram PID
运行gdb之后再绑定OID的进程程序调试
attach Link to heading
执行attach pid即可调试正在运行的进程号为PID的程序。
detach Link to heading
在完成调试之后,执行detach命令断开连接,让被调试的进程可以继续正常运行。
一般调试指令 Link to heading
shell Link to heading
1(gdb) shell <command string>
在gdb环境中,可以执行Linux的shell命令。调用Linux的shell来执行,默认使用标准shell(/bin/sh)。
1(gdb) shell ps
2 PID TTY TIME CMD
3 211 ttyLP0 00:00:00 autologin
4 220 ttyLP0 00:00:00 login
5 222 ttyLP0 00:00:00 sh
6 283 ttyLP0 00:00:00 gdb
7 289 ttyLP0 00:00:00 ps
list Link to heading
查看源码,不加参数时,向下显示源码,加参数-l时,向上显示源码,默认显示10行。命令缩写是l
目前list指令只能显示代码的行号,不显示具体代码,不知道为啥??
edit Link to heading
编辑当前所在的行,也可以编辑某个函数的源码(规则同list)。命令缩写是e
disassemble Link to heading
1、不带参数:默认的反汇编范围是所选择地址附近的汇编代码; 2、单个参数:当然也可以是函数名,因为函数名也是一个 地址; 3、两个参数:就是内存地址范围;
1(gdb) disassemble captureAll
2Dump of assembler code for function ImageProvider::captureAll():
3 0x0000aaaaaaab2b00 <+0>: stp x29, x30, [sp, #-32]!
4...
5<ImageProvider::captureAll()+88>
6 0x0000aaaaaaab2b3c <+60>: ldr x0, [x19]
7 0x0000aaaaaaab2b40 <+64>: cbz x0, 0xaaaaaaab2b58 <ImageProvider::captureAll()+88>
8=> 0x0000aaaaaaab2b44 <+68>: bl 0xaaaaaaab6190 <V4L2Camera::grabFrame()>
9 0x0000aaaaaaab2b48 <+72>: cbz w0, 0xaaaaaaab2bf4 <ImageProvider::captureAll()+244>
10 0x0000aaaaaaab2b4c <+76>: cmn w0, #0x1
11 0x0000aaaaaaab2b50 <+80>: b.eq 0xaaaaaaab2d3c <ImageProvider::captureAll()+572> // b.none
12...
13 0x0000aaaaaaab2d8c <+652>: b 0xaaaaaaab2b58 <ImageProvider::captureAll()+88>
14End of assembler dump.
程序运行控制 Link to heading
run Link to heading
重新开始运行文件(run-text:加载文本文件,run-bin:加载二进制文件),命令缩写为r
run argv[1] argv[2] 调试时命令行传参。
run > outfile 使用重定向控制程序输出。
start Link to heading
单步执行,运行程序,停在第一执行语句。
continue Link to heading
继续执行,直接运行结束,或者到下一个断点处。命令缩写为c
next/step Link to heading
next [N]: 单步调试(跳过函数调用),命令缩写为n
step [N]: 单步调试(进入函数调用),命令缩写为s
nexti/stepi Link to heading
汇编代码逐行运行,执行下一行源代码中的一条汇编指令。同next、step
nexti [N]:单步调试(跳过函数调用),命令缩写为ni
stepi [N]:单步调试(进入函数调用),命令缩写为si
call Link to heading
1call <expr>
表达式中可以一是函数,以此达到强制调用函数的目的。并显示函数的返回值,如果函数返回值是void,那么就不显示。
call function(),可以调用某个函数直接执行,调用函数时需要添加()
1(gdb) call reopenCameras()
print function(),也可以实现上面的功能。print和call的不同是,如果函数返回void,call则不显示,print则显示函数返回值,并把该值存入历史数据中。
调用abort函数时产生此信号。进程异常终止。
1(gdb) call abort
2$3 = {void (void)} 0xfffff673ce58 <__GI_abort>
3(gdb) call abort()
4====== App ====== readMax9286_event => retval = 0 [ 8052.400313]
5[ 8052.400313] /******************* max9286_dev_read return 0x00 *********************/
6[ 8052.400313]
7
8====== App ====== readMax9286_event!!!
9
10Thread 1 "calwin.out" received signal SIGABRT, Aborted.
11__GI_raise (sig=sig@entry=6) at ../sysdeps/unix/sysv/linux/raise.c:50
1250 ../sysdeps/unix/sysv/linux/raise.c: No such file or directory.
13The program being debugged was signaled while in a function called from GDB.
14GDB remains in the frame where the signal was received.
15To change this behavior use "set unwindonsignal on".
16Evaluation of the expression containing the function
17(__GI_abort) will be abandoned.
18When the function is done executing, GDB will silently stop.
继续执行,可以看到程序“sig=6 ”
1(gdb) c
2Continuing.[ 8167.171029] audit: type=1701 audit(1590545030.676:2): auid=4294967295 uid=0 gid=0 ses=4294967295 pid=280 comm="calwin.out" exe="/home/root/gdb_test/calwin.out" sig=6 res=1
3
4Unable to fetch general registers.: No such process.
5Unable to fetch general registers.: No such process.[ 8167.207995] max9286_set_power:1870: close video device -- 4 --
6
7(gdb) [Thread 0xffffda05b190 (LWP 290) exited]
8[Thread 0xffffeb732190 (LWP 288) exited]
9[Thread 0xffffebfcc190 (LWP 287) exited]
10[T[ 8167.241648] ###### max9286_dev_close
11hread 0xffffec7cd190 (LWP 286) exited]
12[Thread 0xfffff4f21530 (LWP 280) exited]
13
14Cannot execute this command without a live selected thread.
until Link to heading
当你厌倦了在一个循环体内单步跟踪时,这个命令可以运行程序直到退出循环体。命令缩写为u
1until location
until 命令还可以后跟某行代码的行号,以指示 GDB 调试器直接执行至指定位置后停止。
finish Link to heading
继续执行并结束当前函数,返回到函数调用点。
return Link to heading
1return <expression>
使用return命令取消当前函数的执行,并立即返回,如果指定了
<expression>
,那么该表达式的值会被认作函数的返回值。
kill Link to heading
终止当前调试的程序。
quit Link to heading
1(gdb) q
退出gdb,命令缩写为q。
Ctrl+D
也可以退出gdb调试。
设置查看变量值 Link to heading
whatis Link to heading
显示变量类型。
1(gdb) whatis m_needReopen
2type = bool
3(gdb) whatis m_frontCam
4type = V4L2Camera *
ptype Link to heading
1ptype[/FLAGS] TYPE | EXPRESSION
显示变量类型,比whatis功能更强,可以提供一个结构的定义。
1(gdb) ptype m_needReopen
2type = bool
3(gdb) ptype m_frontCam
4type = class V4L2Camera {
5 private:
6 video_channel *m_video_ch;
7 g2d_surface *m_src;
8 g2d_surface *m_dst;
9 void *m_g2dHandle;
10 bool m_buffer_NULL_status;
11 public:
12 bool m_running;
13
14 V4L2Camera(const char *, void *, int);
15 ~V4L2Camera();
16 bool checkCameraState(int &);
17 bool init(g2d_buf *, int, int, int);
18 int startCapture(void);
19 int grabFrame(void);
20 void returnFrame(void);
21 void stopCapture(void);
22 void copyToRgba(int);
23 void cacheLastFrame(int);
24 bool isGreenFrame(unsigned char *, int);
25 v_buffer * getVideoBuffer(void);
26
27 private:
28 bool isOpen(void);
29} *
info Link to heading
查看程序运行的状态,例如info args显示传递给函数的参数,info registers显示当前使用的寄存器,info breakpoints显示断点信息,可以用help info查看其支持的子命令。命令缩写为i
1info locals // 显示当前堆栈框架的局部变量列表及其值。
2info args // 显示当前函数的参数名及其值。
3info registers //显示处理器的寄存器信息。
4info all-registers // 显示所有寄存器的情况。(包括浮点寄存器)
5info signals
6info handle // 显示有哪些信号在被GDB检测中。
7info program //显示程序的是否在运行,进程号,被暂停的原因。
set Link to heading
设置变量的值,命令缩写为s
show Link to heading
set命令设置完之后,用show查看,可以单独查看某个变量的设置情况。
1set print address <on/off>
打开/关闭地址输出,当程序显示函数信息时,GDB会显出函数的参数地址。系统默认为打开的。
1show print address
查看当前地址显示选项是否打开。
1set print array off
打开数组显示,打开后当数组显示时,每个元素占一行,如果不打开的话,每个元素则以逗号分隔。这个选项默认是关闭的。
1set print elements <number-of-elements>
这个选项主要是设置数组的,如果你的数组太大了,那么就可以指定一个
<number-of-elements>
来指定数据显示的最大长度,当到达这个长度时,GDB就不再往下显示了。如果设置为0,则表示不限制。
1set print null-stop <on/off>
如果打开了这个选项,那么当显示字符串时,遇到结束符则停止显示。这个选项默认为off。
1set step-mode on
打开step-mode模式。在进行单步跟踪时,程序不会因为没有debug信息而不停住。这个参数有很利于查看机器码。
1set print sevenbit-strings <on/off>
设置字符显示,是否按“/nnn”的格式显示。
1set print pretty <on/off>
如果打开printf pretty这个选项,那么当GDB显示结构体时会比较漂亮。
1set print union <on/off>
设置显示结构体时,是否显式其内的联合体数据。
1set print object <on/off>
在C++中,如果一个对象指针指向其派生类,如果打开这个选项,GDB会自动按照虚方法调用的规则显示输出,如果关闭这个选项的话,GDB就不管虚函数表了。这个选项默认是off。
print Link to heading
1print <expression>
打印变量或表达式,命令缩写为p
1x 按十六进制格式显示变量。
2d 按十进制格式显示变量。
3u 按十六进制格式显示无符号整型。
4o 按八进制格式显示变量。
5t 按二进制格式显示变量。
6a 按十六进制格式显示变量。
7c 按字符格式显示变量。
8f 按浮点数格式显示变量。
print与set都可以设置变量的值。
1set var m_needReopen=true
2set m_needReopen=true // 也是可以的
3print m_needReopen=true
在某些时候,很有可能你的变量和GDB中的参数冲突。使用set var格式的GDB命令,告知变量不是GDB的参数,而是程序的变量名,这样严谨一些。
打印数组或者指针变量:静态数组,直接打印,动态数组是,base@length。
1(gdb) p sBlackScreenBuffer
2$2 = (unsigned char *) 0xffff92471010 "\200"
3(gdb) p *sBlackScreenBuffer@10
4$3 = "\200\000\200\000\200\000\200\000\200"
5(gdb) p/x *sBlackScreenBuffer@10
6$4 = {0x80, 0x0, 0x80, 0x0, 0x80, 0x0, 0x80, 0x0, 0x80, 0x0}
7(gdb) p/x *sBlackScreenBuffer@15
8$5 = {0x80, 0x0, 0x80, 0x0, 0x80, 0x0, 0x80, 0x0, 0x80, 0x0, 0x80, 0x0, 0x80, 0x0, 0x80}
print实现gdb内嵌操作
1p sizeof(int) // 查看 int 类型所占字节数。
2p sizeof(name) // 查看结构体变量name所占字节数
3p strlen(name) // 查看字符串name长度
4p strcmp(name1, name2) // 比较name1和name2为字符串的大小
5p strcpy(p.name, "Soft") // 字符串拷贝, name是结构体p的数据成员。
1(gdb) p sizeof(m_needReopen)
2$1 = 1
3(gdb) p m_front_g2d_buffer
4$4 = (g2d_buf *) 0x0
5(gdb) p sizeof(m_front_g2d_buffer)
6$5 = 8
x Link to heading
查看内存
如:x/20xw 显示20个单元,16进制,4字节每单元。
1(gdb) help x
2Examine memory: x/FMT ADDRESS.
3ADDRESS is an expression for the memory address to examine.
4FMT is a repeat count followed by a format letter and a size letter.
5Format letters are o(octal), x(hex), d(decimal), u(unsigned decimal),
6 t(binary), f(float), a(address), i(instruction), c(char), s(string)
7 and z(hex, zero padded on the left).
8Size letters are b(byte), h(halfword), w(word), g(giant, 8 bytes).
9The specified number of objects of the specified size are printed
10according to the format. If a negative number is specified, memory is
11examined backward from the address.
12
13Defaults for format and size letters are those previously used.
14Default count is 1. Default address is following last thing printed
15
16with this command or "print".
1(gdb) p m_frontCam
2$1 = (V4L2Camera *) 0xffffd40029d0
1(gdb) x m_frontCam
20xffffd40029d0: -16 '\360'
display Link to heading
使用 display 命令查看变量或表达式的值,每当程序暂停执行(例如单步执行)时,GDB 调试器都会自动帮我们打印出来,而 print 命令则不会。
1 display <expr>
2 display/<fmt> <expr>
3 display/<fmt> <addr>
expr是一个表达式,fmt表示显示的格式,addr表示内存地址,当你用display设定好了一个或多个表达式后,只要你的程序被停下来,GDB会自动显示你所设置的这些表达式的值。
1info display
显示添加的display信息。
undisplay Link to heading
1 undisplay <dnums...>
取消display编号对应的监控。
查看堆栈信息 Link to heading
backtrace Link to heading
查看函数的调用的栈帧和层级关系,命令缩写为bt
backtrace full: 查看更全的信息,命令缩写bt f
1(gdb) bt
2#0 ImageProvider::captureAll (this=0xaaaadc88f890) at ../src/imageprovider.cpp:534
3#1 0x0000aaaac3e25f50 in VideoWidget::paintGL (this=0xaaaadc97c9e0) at ../src/videowidget.cpp:83
4#2 0x0000ffffac883550 in ?? () from /usr/lib/libQt5Widgets.so.5
5#3 0x0000ffffac861fa8 in QWidget::event(QEvent*) () from /usr/lib/libQt5Widgets.so.5
6#4 0x0000ffffac81ed3c in QApplicationPrivate::notify_helper(QObject*, QEvent*) () from /usr/lib/libQt5Widgets.so.5
7...
8#22 0x0000ffffabbcb2f0 in QCoreApplication::exec() () from /usr/lib/libQt5Core.so.5
9#23 0x0000aaaac3e23784 in main (argc=<optimized out>, argv=<optimized out>) at ../src/main.cpp:40
frame Link to heading
切换函数的栈帧,命令缩写为f
1(gdb) f 1
2#1 0x0000aaaac3e25f50 in VideoWidget::paintGL (this=0xaaaadc97c9e0) at ../src/videowidget.cpp:83
383 ../src/videowidget.cpp: No such file or directory.
info frame Link to heading
显示当前堆叠帧的信息。
1(gdb) info frame
2Stack level 1, frame at 0xfffff3eda220:
3 pc = 0xaaaac3e25f50 in VideoWidget::paintGL (../src/videowidget.cpp:83); saved pc = 0xffffac883550
4 called by frame at 0xfffff3eda270, caller of frame at 0xfffff3eda1f0
5 source language c++.
6 Arglist at 0xfffff3eda1f0, args: this=0xaaaadc97c9e0
7 Locals at 0xfffff3eda1f0, Previous frame's sp is 0xfffff3eda220
8 Saved registers:
9 x19 at 0xfffff3eda200, x20 at 0xfffff3eda208, x21 at 0xfffff3eda210, x29 at 0xfffff3eda1f0, x30 at 0xfffff3eda1f8
10(gdb) info frame
11Stack level 1, frame at 0xfffff3eda220:
12 pc = 0xaaaac3e25f50 in VideoWidget::paintGL (../src/videowidget.cpp:83); saved pc = 0xffffac883550
13 called by frame at 0xfffff3eda270, caller of frame at 0xfffff3eda1f0
14 source language c++.
15 Arglist at 0xfffff3eda1f0, args: this=0xaaaadc97c9e0
16 Locals at 0xfffff3eda1f0, Previous frame's sp is 0xfffff3eda220
17 Saved registers:
18 x19 at 0xfffff3eda200, x20 at 0xfffff3eda208, x21 at 0xfffff3eda210, x29 at 0xfffff3eda1f0, x30 at 0xfffff3eda1f8
设置断点 Link to heading
普通断点:作用于程序中的某一行,当程序运行至此行时停止执行;
观察断点:作用于某一变量或表达式,当该变量(表达式)的值发生改变时,程序暂停;
捕捉断点:监控程序中某一事件的发生,例如程序发生某种异常时、某一动态库被加载时等等,一旦目标时间发生,则程序停止执行。
设置普通断点 Link to heading
break Link to heading
1 break … if condition
添加断点,condition表示条件,在条件成立时停住。命令缩写为b
thbreak Link to heading
添加临时断点((只可使用一次),命令缩写为tb
指定文件加断点:
1break filename:linenum
在源文件filename的linenum行处停住。
1(gdb) b ../src/imageprovider.cpp:542
2Breakpoint 3 at 0xaaaaaaab2b18: file ../src/imageprovider.cpp, line 542.
当前所在文件加断点:
(gdb) b 555
1Note: breakpoint 2 also set at pc 0xaaaaaaab2b48.
2Breakpoint 4 at 0xaaaaaaab2b48: file ../src/imageprovider.cpp, line 555.
指定函数加断点:
1break filename:function
在源文件filename的function函数的入口处停住。
1(gdb) b captureAll
2Breakpoint 5 at 0xaaaaaaab2b00: file ../src/imageprovider.cpp, line 534.
指定C++函数加断点:
1(gdb) b V4L2Camera::grabFrame
2
3Breakpoint 9 at 0xaaaaaaab6190: file ../src/v4l2camera.cpp, line 170.
1(gdb) tb 565
2
3Temporary breakpoint 6 at 0xaaaaaaab2b58: file ../src/imageprovider.cpp, line 567.
1info breakpoints
显示添加的断点信息,命令缩写为i b
1(gdb) i b
2Num Type Disp Enb Address What
31 breakpoint keep y <PENDING> 555
42 breakpoint keep y 0x0000aaaaaaab2b18 in ImageProvider::captureAll() at ../src/imageprovider.cpp:542
5 breakpoint already hit 1 time
63 breakpoint keep y 0x0000aaaaaaab2b48 in ImageProvider::captureAll() at ../src/imageprovider.cpp:555
74 breakpoint keep y 0x0000aaaaaaab2b00 in ImageProvider::captureAll() at ../src/imageprovider.cpp:534
85 breakpoint keep y 0x0000aaaaaaab6190 in V4L2Camera::grabFrame() at ../src/v4l2camera.cpp:170
96 breakpoint del y 0x0000aaaaaaab2b58 in ImageProvider::captureAll() at ../src/imageprovider.cpp:567
disable/enable Link to heading
1 disable/enable breakpointNum
屏蔽/使能断点
(gdb) disable 6
1(gdb) i b
2Num Type Disp Enb Address What
31 breakpoint keep y <PENDING> 555
42 breakpoint keep y 0x0000aaaaaaab2b18 in ImageProvider::captureAll() at ../src/imageprovider.cpp:542
5 breakpoint already hit 1 time
63 breakpoint keep y 0x0000aaaaaaab2b48 in ImageProvider::captureAll() at ../src/imageprovider.cpp:555
74 breakpoint keep y 0x0000aaaaaaab2b00 in ImageProvider::captureAll() at ../src/imageprovider.cpp:534
85 breakpoint keep y 0x0000aaaaaaab6190 in V4L2Camera::grabFrame() at ../src/v4l2camera.cpp:170
9 breakpoint already hit 1 time
106 breakpoint del n 0x0000aaaaaaab2b58 in ImageProvider::captureAll() at ../src/imageprovider.cpp:567
clear Link to heading
1clear location
删除指定位置处的所有断点。参数 location 通常为某一行代码的行号或者某个具体的函数名。当 location 参数为某个函数的函数名时,表示删除位于该函数入口处的所有断点。
1clear <function>
清除所有设置在函数上的断点。
1clear <linenum>
清除所有设置在指定行上的断点。
delete Link to heading
1delete [breakpoints] [num]
通常用来删除所有断点,也可以删除指定编号的各类型断点。其中,breakpoints 参数可有可无,num 参数为指定断点的编号,其可以是 delete 删除某一个断点,而非全部。
1(gdb) delete 6
2
3(gdb) i b
4Num Type Disp Enb Address What
51 breakpoint keep y <PENDING> 555
62 breakpoint keep y 0x0000aaaaaaab2b18 in ImageProvider::captureAll() at ../src/imageprovider.cpp:542
7 breakpoint already hit 1 time
83 breakpoint keep y 0x0000aaaaaaab2b48 in ImageProvider::captureAll() at ../src/imageprovider.cpp:555
94 breakpoint keep y 0x0000aaaaaaab2b00 in ImageProvider::captureAll() at ../src/imageprovider.cpp:534
105 breakpoint keep y 0x0000aaaaaaab6190 in V4L2Camera::grabFrame() at ../src/v4l2camera.cpp:170
11 breakpoint already hit 1 time
ignore Link to heading
1ignore N count
忽视断点多少次。ignore 命令可以使目标断点暂时失去作用,当断点失效的次数超过指定次数时,断点的功能会自动恢复。
1(gdb) ignore 2 5
2Will ignore next 5 crossings of breakpoint 2.
设置观察断点 Link to heading
观察点(watchpoint)和断点(breakpoint)类似,但是断点是程序运行前设置,观察点是运行中设置,而且只能是变量或者表达式。
watch Link to heading
1watch [-l|-location] expression
expression指的是监控的变量或表达式。只有当被监控变量(表达式)的值发生改变,程序停止运行。
rwatch Link to heading
只要程序中出现读取目标变量(表达式)的值的操作,程序停止运行
awatch Link to heading
只要程序中出现读取目标变量(表达式)的值或者改变值的操作,程序停止运行
注意:
当监控的为局部变量(表达式)时,一旦局部变量(表达式)失效,则监控操作也随即失效;
如果监控的是一个指针变量(例如 *p),则 watch *p 和 watch p 是有区别的,前者监控的是 p 所指数据的变化情况,而后者监控的是 p 指针本身有没有改变指向;
这 3 个监控命令还可以用于监控数组中元素值的变化情况,例如对于 a[10] 这个数组,watch a 表示只要 a 数组中存储的数据发生改变,程序就会停止执行。
局部变量超出作用域,断点失效并被删除。
1(gdb) c
2Continuing.
3Error evaluating expression for watchpoint 4
4current stack frame does not contain a variable named `this'
5Watchpoint 4 deleted.
6[Switching to Thread 0xffffe94c1190 (LWP 245)]
7ioctl () at ../sysdeps/unix/sysv/linux/aarch64/ioctl.S:27
827 ../sysdeps/unix/sysv/linux/aarch64/ioctl.S: No such file or directory.
awatch 和 rwatch 命令只能设置硬件观察点,如果系统不支持或者借助如上命令禁用,则 GDB 调试器会打印如下信息:
1(gdb) rwatch m_needReopen
2Expression cannot be implemented with read/access watchpoint.
disable/enable Link to heading
1disable/enable watchpointsNum
屏蔽/使能观察点。
1(gdb) watch ImageProvider::m_ip
2Hardware watchpoint 14: ImageProvider::m_ip
3(gdb) watch m_needReopen
4Watchpoint 15: m_needReopen
5
6(gdb) i b
7Num Type Disp Enb Address What
82 breakpoint keep y 0x0000aaaaaaab2b18 in ImageProvider::captureAll() at ../src/imageprovider.cpp:542
9 breakpoint already hit 16 times
103 breakpoint keep n 0x0000aaaaaaab2b48 in ImageProvider::captureAll() at ../src/imageprovider.cpp:555
11 breakpoint already hit 3 times
124 breakpoint keep n 0x0000aaaaaaab2b00 in ImageProvider::captureAll() at ../src/imageprovider.cpp:534
13 breakpoint already hit 3 times
145 breakpoint keep n 0x0000aaaaaaab6190 in V4L2Camera::grabFrame() at ../src/v4l2camera.cpp:170
15 breakpoint already hit 1 time
1614 hw watchpoint keep y ImageProvider::m_ip
1715 watchpoint keep y m_needReopen
设置捕捉断点 Link to heading
用捕捉断点监控某一事件的发生,等同于在程序中该事件发生的位置打普通断点。
catch Link to heading
可设置捕捉点来补捉程序运行时的一些事件。当event发生时,程序就会暂停执行。
1catch <event>
2
3Set catchpoints to catch events.
4
5List of catch subcommands:
6
7catch assert -- Catch failed Ada assertions
8catch catch -- Catch an exception 一个C++捕捉到的异常
9catch throw -- Catch an exception 一个C++抛出的异常
10catch rethrow -- Catch an exception
11catch exception -- Catch Ada exceptions
12catch handlers -- Catch Ada exceptions
13catch exec -- Catch calls to exec
14catch fork -- Catch calls to fork 调用系统调用fork时
15catch vfork -- Catch calls to vfork
16catch load -- Catch loads of shared libraries 载入共享库(动态链接库)时
17catch unload -- Catch unloads of shared libraries 卸载共享库(动态链接库)时
18catch signal -- Catch signals by their names and/or numbers
19catch syscall -- Catch system calls by their names
如监控共享库libmax9286-camera.so.1的加载:
1root@baolong:~/gdb_test# gdb -q calwin.out
2Reading symbols from calwin.out...
3(gdb) catch load libmax9286-camera.so.1
4Catchpoint 1 (load)
5(gdb) r
6Starting program: /home/root/gdb_test/calwin.out
7[Thread debugging using libthread_db enabled]
8Using host libthread_db library "/lib/libthread_db.so.1".
9
10Catchpoint 1
11 Inferior loaded /usr/lib/libg2d.so.1.5
12 /usr/lib/libmax9286-camera.so.1
13 /usr/lib/libQt5Widgets.so.5
14 /usr/lib/libQt5Gui.so.5
15 /usr/lib/libQt5SerialPort.so.5
16 /usr/lib/libQt5Test.so.5
17 /usr/lib/libQt5Core.so.5
18 /usr/lib/libEGL.so.1
19 /lib/libpthread.so.0
20 /usr/lib/libstdc++.so.6
21 /lib/libgcc_s.so.1
22 /lib/libc.so.6
23 /usr/lib/libdrm.so.2
24 /usr/lib/libOpenCL.so.1
25 /lib/libm.so.6
26 /usr/lib/libGLESv2.so.2
27 /usr/lib/libpng16.so.16
28 /lib/libz.so.1
29 /lib/libudev.so.1
30 /usr/lib/libpcre2-16.so.0
31 /lib/libdl.so.2
32 /usr/lib/libglib-2.0.so.0
33 /usr/lib/libGAL.so
34 /usr/lib/libwayland-server.so.0
35 /usr/lib/libwayland-client.so.0
36 /usr/lib/libgbm.so
37 /usr/lib/libgbm_viv.so
38 /usr/lib/libVSC.so
39--Type <RET> for more, q to quit, c to continue without paging--
40 /lib/librt.so.1
41 /usr/lib/libpcre.so.1
42 /usr/lib/libffi.so.7
43__GI__dl_debug_state () at dl-debug.c:74
4474 dl-debug.c: No such file or directory.
tcatch Link to heading
1catch <event>
只设置一次捕捉点,当程序停住以后,断点被自动删除。
1info catch
显示出当前的函数中的异常处理信息。
条件断点 Link to heading
condition Link to heading
1condition N <expression>
2condition N // 用于删除编号N断点的条件表达式,使其变成普通的无条件断点
修改断点编号为N的停止条件为expression。(只有break 和 watch命令支持if,catch目前暂不支持if)。
condition 与break if类似,只是condition只能用在已存在的断点上。
设置快照 Link to heading
gdb可以在程序执行的过程中保留快照(状态)信息,称之为checkpoint,可以在进来返回到该处再次查看当时的信息,比如内存、寄存器以及部分系统状态。通过设置checkpoint,万一调试的过程中错误发生了但是已经跳过了错误发生的地方,就可以快速返回checkpoint再开始调试,而不用重启程序重新来过。
此外,checkpoint的作用还在于断点、观测点不是什么情况下都可用的情况下,因为Linux系统有时候为了安全考虑,会随机化新进程的地址空间,这样重启调试程序会导致之前使用绝对地址设置的断点、观测点不可用。
checkpoint Link to heading
1checkpoint // 无参数
创建一个快照,包含当前调试的所有信息。同时会输出这个checkpoint的信息。
1restart N
回退到指定checkpoint的快照。
在调试calwin时添加快照,提示多线程不能设置快照。
1(gdb) info inferiors
2 Num Description Executable
3* 1 process 373 /home/root/gdb_test/calwin.out
4(gdb) checkpoint
5checkpoint: can't checkpoint multiple threads.
多线程调试 Link to heading
info inferiors Link to heading
1info inferiors
查询正在调试的进程。
inferior Link to heading
1inferior infno
使inferior号infno成为当前inferior。
info threads Link to heading
命令缩写是info thr, 显示当前可调试的所有线程,每个线程会有一个gdb为其分配的ID,后面操作线程的时候会用这个ID,前面有*的是当前调试的线程。
1(gdb) info threads
2 Id Target Id Frame
3
4* 1 Thread 0xffff9755f530 (LWP 265) "calwin.out" ImageProvider::captureAll (
5 this=0xaaaacbd8a890) at ../src/imageprovider.cpp:534
6 2 Thread 0xffff8ee0b190 (LWP 266) "calwin.out" ioctl ()
7 at ../sysdeps/unix/sysv/linux/aarch64/ioctl.S:25
8 3 Thread 0xffff8e60a190 (LWP 267) "calwin.out" ioctl ()
9 at ../sysdeps/unix/sysv/linux/aarch64/ioctl.S:25
10 4 Thread 0xffff8dd70190 (LWP 268) "calwin.out" ioctl ()
11 at ../sysdeps/unix/sysv/linux/aarch64/ioctl.S:25
12 5 Thread 0xffff8c906190 (LWP 269) "QThread" __libc_read (nbytes=4,
13 buf=0xffff8c905884, fd=12) at ../sysdeps/unix/sysv/linux/read.c:26
14 6 Thread 0xffff7f1ef190 (LWP 270) "calwin.out" ioctl ()
15 at ../sysdeps/unix/sysv/linux/aarch64/ioctl.S:25
thread Link to heading
1thread threadID
切换调试程序的线程。
1thread apply <threadno/all> bt
打开指定/所有线程的堆栈信息。
1set scheduler-locking <off/on/step>
在调试多线程程序时,使用step或者continue命令调试当前线程时,其它线程也在并发执行,这个命令可以通过off|on|step来控制线程的执行,即:
off:不锁定任何线程,即所有线程都执行,这是默认值。
on:只有当前被调试程序会被执行。
step:在单步的时候,除了next过一个函数的情况以外,只有当前线程会执行
1set print thread-events <on/off>
用于设定是否提示线程启动或停止时的信息。
1set follow-fork-mode <parent/child>
在fork或vfork产生子进程时,选择跟踪父/ 子进程: parent :默认情况,当一个程序fork时,GDB仍继续调试原进程,子进程的运行没有任何影响。 child :GDB调试新进程,父进程不受影响的运行。
coredump调试 Link to heading
Coredump叫做核心转储,它是进程运行时在突然崩溃的那一刻的一个内存快照。操作系统在程序发生异常而异常在进程内部又没有被捕获的情况下,会把进程此刻内存、寄存器状态、运行堆栈等信息转储保存在一个文件里。一般coredump文件产生的原因有空指针、数组越界、多线程多次释放、堆栈溢出等等。
1、相关gdb指令 Link to heading
generate-core-file Link to heading
生成core文件,生成与否受core file size 的资源限制。
1# myprogram
2Segmentation fault (core dumped)
3# gdb myprogram
4...
5(gdb) generate-core-file core
6(gdb) core-file core
7...
core-file Link to heading
加载core文件,有点类似于file,但是file指令不能加载core文件。
1(gdb) file core_calwin
2"/home/root/gdb_test/core_calwin": not in executable format: file format not recognized
2、core文件设置 Link to heading
2.1、设置core文件生成 Link to heading
使用ulimit -c命令可查看core文件的生成开关,若结果为0,则便是关闭了此功能,不会生成core文件。这个限制默认为 0,需要调节 ulimit 中对 core file size 的资源限制。
(1)使用命令ulimit -c filesize命令
若ulimit -c unlimited 则标识此core文件的大小不受限制;若指定filesize,如果生成的信息超过此大小,将会被裁剪,最终生成一个不完整的core文件,在调试此core文件时,gdb会提示错误。
(2)但是若想整个系统中生效则在 shell里面设置是不行的,方法如下:
修改 /root/.bash_profile文件,在其中加入ulitmit -S -c unlimited
source /root/.bash_profile
实现永久修改,打开**/etc/security/limits.conf** 文件,在该文件的最后加上两行:
1# vi /etc/security/limits.conf
2@root soft core unlimited
3@root hard core unlimited
2.2、设置core文件格式 Link to heading
(1)/proc/sys/kernel/core_uses_pid
可以控制core文件的问价名是否添加PID作为扩展,文件的内容为1,标识添加PID作为扩展,生成的core文件格式为core.XXXX;为0则表示生成的core文件统一命名为core。
可通过一下命令修改此文件:
1echo 1 > /proc/sys/kernel/core_uses_pid
(2)/proc/sys/kernel/core_pattern
可以设置文件的保存位置和文件名格式,以下是core_pattern参数列表:
1 %p - insert pid into filename 添加pid
2 %u - insert current uid into filename 添加当前uid
3 %g - insert current gid into filename 添加当前gid
4 %s - insert signal that caused the coredump into the filename 添加导致产生core的信号
5 %t - insert UNIX time that the coredump occurred into filename 添加core文件生成的unix时间
6 %h - insert hostname where the coredump happened into filename 添加主机名
7 %e - insert coredumping executable name into filename 添加命令名
如下命令可以将core文件统一生成到/usr/core_file目录下,产生的文件名为core_filename_time_pid格式。
1echo /var/core_log/core_%e_%t_%p > /proc/sys/kernel/core_pattern
设置完成之后,coredump文件就不会被覆盖了。
1root@baolong:~/gdb_test# ls /var/core_log/ -l
2total 111652
3-rw------- 1 root root 70430720 May 27 02:38 core_QThread_1590547134_398
4-rw------- 1 root root 70430720 May 27 02:39 core_QThread_1590547142_406
5-rw------- 1 root root 75239424 May 27 02:39 core_QThread_1590547146_412
6-rw------- 1 root root 75149312 May 27 02:39 core_QThread_1590547149_418
实现永久修改,打开**/etc/sysctl.conf** 文件,在该文件的最后加上两行:
1# vi /etc/sysctl.conf
2kernel.core_pattern = /var/core_log/core_%e_%t_%p
3kernel.core_uses_pid = 0
可以使用以下命令,使修改结果马上生效。
1# sysctl –p
3、关于gdb调试core文件显示问号的问题 Link to heading
(1)core file size设置小了,导致生成的core文件不全;
(2)调试的程序没有被载入,或者载入的程序没有调试信息;
3.1、core文件不全 Link to heading
(1)设置core file size为10240个block大小。
1root@baolong:~/gdb_test# ulimit -c 10240
2root@baolong:~/gdb_test# gdb -q calwin.out core
3Reading symbols from calwin.out...
4BFD: warning: /home/root/gdb_test/core is truncated: expected core file size >= 70430720, found: 5836800
5
6warning: exec file is newer than core file.
7[New LWP 255]
8[New LWP 252]
9[New LWP 256]
10[New LWP 251]
11[New LWP 253]
12[New LWP 254]
13Cannot access memory at address 0xffff8b78c170
14Cannot access memory at address 0xffff8b78c168
15Failed to read a valid object file image from memory.
16Core was generated by `./calwin.out'.
17Program terminated with signal SIGSEGV, Segmentation fault.
18#0 0x0000ffff8b712db4 in ?? ()
19[Current thread is 1 (LWP 255)]
20(gdb)
可以看到core file被缩短,定位的错误位置显示“??”,没有显示具体定位。
(2)设置core file size为10240个block大小。
1root@baolong:~/gdb_test# ulimit -c 102400
2root@baolong:~/gdb_test# gdb -q calwin.out core
3Reading symbols from calwin.out...
4
5warning: exec file is newer than core file.
6[New LWP 285]
7[New LWP 282]
8[New LWP 286]
9[New LWP 283]
10[New LWP 284]
11[New LWP 281]
12[Thread debugging using libthread_db enabled]
13Using host libthread_db library "/lib/libthread_db.so.1".
14Core was generated by `./calwin.out'.
15Program terminated with signal SIGSEGV, Segmentation fault.
16#0 memset (__len=88, __ch=0, __dest=0x40) at /opt/fsl-imx-xwayland/5.4-zeus/sysroots/aarch64-poky-linux/usr/include/bits/string_fortified.h:71
1771 /opt/fsl-imx-xwayland/5.4-zeus/sysroots/aarch64-poky-linux/usr/include/bits/string_fortified.h: No such file or directory.
18[Current thread is 1 (Thread 0xffff7b1ef190 (LWP 285))]
19(gdb)
可以看到“core is truncated”的错误没有了,段错误定位到的函数位置不是显示“??”,而是直接定位到出错的函数“
memset (__len=88, __ch=0, __dest=0x40)
”,及对应的文件位置。
查看函数回溯:
1(gdb) bt
2#0 memset (__len=88, __ch=0, __dest=0x40)
3 at /opt/fsl-imx-xwayland/5.4-zeus/sysroots/aarch64-poky-linux/usr/include/bits/string_fortified.h:71
4#1 V4l2DevBufferPrepare (video_ch=0xffff640051f0)
5 at ..//source/v4l2/multi_plane/src_v4l2.c:264
6#2 V4L2DevStreamOn (video_ch=0xffff640051f0)
7 at ..//source/v4l2/multi_plane/src_v4l2.c:507
8#3 0x0000aaaab0a05190 in V4L2Camera::startCapture (this=<optimized out>)
9 at ../src/v4l2camera.cpp:156
10#4 0x0000aaaab0a01184 in ImageProvider::openCameras (
11 this=this@entry=0xaaaaea5d2890, camera=<optimized out>)
12 at ../src/imageprovider.cpp:232
13#5 0x0000aaaab0a01704 in ImageProvider::openMax9286 (this=0xaaaaea5d2890)
14 at ../src/imageprovider.cpp:432
15#6 0x0000aaaab0a02318 in CameraMonitorThread::run (this=0xaaaaea6b4630)
16 at ../src/imageprovider.cpp:28
17#7 0x0000ffff84868340 in ?? () from /usr/lib/libQt5Core.so.5
18#8 0x0000ffff8470c8f8 in start_thread (arg=0xfffffe432866)
19 at pthread_create.c:479
20#9 0x0000ffff84464a7c in thread_start ()
21 at ../sysdeps/unix/sysv/linux/aarch64/clone.S:78
可以定位到错误位置为:
..//source/v4l2/multi_plane/src_v4l2.c:264
文件的 **V4l2DevBufferPrepare
**函数。
查看对应源码:
1static int V4l2DevBufferPrepare(struct video_channel *video_ch)
2{
3 int fd = video_ch->v4l2_fd;
4
5 struct v4l2_buffer *buf;
6 for (unsigned int i=0; i<video_ch->buffer_num; i++)
7 {
8 buf = &video_ch->v4l_buffers[i].capture_buffer;
9 memset(buf, 0, sizeof(struct v4l2_buffer)); // 错误所在264行
10...
最终定位**
video_ch->v4l_buffers
** 没有初始化导致空指针段错误。问题原因:应用代码不够严谨,未对**
V4L2Camera::init()
**的返回值进行判断。
上述段错误复现方法:
1root@baolong:~/gdb_test# ./calwin.out & // 第一次后台执行
2...
3[1590546352 : 583] ========= open finished =======
4
5====== App ====== readMax9286_event!!!
6root@baolong:~/gdb_test# ./calwin.out // 第二次没有kill上一次运行的calwin进程,继续执行一次
7...
8[ 9557.898687] isi-capture 58100000.isi:cap_device: drivers/staging/media/imx/imx8-isi-cap.c: mxc_isi_cap_s_fmt_mplane: vb2_queue has no buffers allocated.
9...
10OpenV4L2Dev: open camera /dev/video3 successfully
11 ------- V4L2Camera::init /dev/video3 ----- start
12 ------- InitV4L2Dev /dev/video3 ----- start
13VIDIOC_S_FMT: width=1280, height=720, pixelformat=YUYV
14/dev/video3 VIDIOC_S_FMT error: format YUYV not supported
15Init V4L2 Device fail
16====================== startCaptureCameras front
17 ------- V4L2DevStreamOn /dev/video0 ----- start
18[ 9558.294810] max9286_set_power:1870: close video device -- 4 --
19[ 9558.301323] ###### max9286_dev_close
20Segmentation fault (core dumped)
21root@baolong:~/gdb_test#
3.2、程序未加载 Link to heading
(1)手动生成core文件并调试,段错误可以正常定位。
1...
2Thread 5 "QThread" received signal SIGSEGV, Segmentation fault.
3[Switching to Thread 0xffffe94b8190 (LWP 321)]
4V4l2DevBufferPrepare (video_ch=0xffffd40051f0) at ..//source/v4l2/multi_plane/src_v4l2.c:264
5264 ..//source/v4l2/multi_plane/src_v4l2.c: No such file or directory.
6(gdb) generate-core-file core_calwin
7Saved corefile core_calwin
8(gdb) core-file core_calwin
9A program is being debugged already. Kill it? (y or n) y
10[ 1359.267865] max9286_set_power:1870: close video device -- 4 --
11[ 1359.275308] ###### max9286_dev_close
12warning: exec file is newer than core file.
13[New LWP 321]
14[New LWP 315]
15[New LWP 318]
16[New LWP 319]
17[New LWP 320]
18[New LWP 322]
19[Thread debugging using libthread_db enabled]
20Using host libthread_db library "/lib/libthread_db.so.1".
21Core was generated by `/home/root/gdb_test/calwin.out'.
22Program terminated with signal SIGSEGV, Segmentation fault.
23#0 memset (__len=88, __ch=0, __dest=0x40) at /opt/fsl-imx-xwayland/5.4-zeus/sysroots/aarch64-poky-linux/usr/include/bits/string_fortified.h:71
2471 /opt/fsl-imx-xwayland/5.4-zeus/sysroots/aarch64-poky-linux/usr/include/bits/string_fortified.h: No such file or directory.
25[Current thread is 1 (Thread 0xffffe94b8190 (LWP 321))]
26(gdb)
27root@baolong:~/gdb_test# ls -l calwin.out
28-rwxr-xr-x 1 root root 2869584 Apr 15 2022 calwin.out
(2)直接调试core文件,会显示“??”,因为没有对应的调试信息。
1(gdb) core-file core_calwin
2[New LWP 321]
3[New LWP 315]
4[New LWP 318]
5[New LWP 319]
6[New LWP 320]
7[New LWP 322]
8Core was generated by `/home/root/gdb_test/calwin.out'.
9Program terminated with signal SIGSEGV, Segmentation fault.
10#0 0x0000fffff7f85db4 in ?? ()
11[Current thread is 1 (LWP 321)]
(3)重新加载core_calwin对应的程序后,再调试core_calwin文件,对应的"??“解决。
1(gdb) file calwin.out
2warning: exec file is newer than core file.
3Reading symbols from calwin.out...
4(gdb)
5(gdb) core-file core_calwin
6warning: exec file is newer than core file.
7[New LWP 321]
8[New LWP 315]
9[New LWP 318]
10[New LWP 319]
11[New LWP 320]
12[New LWP 322]
13[Thread debugging using libthread_db enabled]
14Using host libthread_db library "/lib/libthread_db.so.1".
15Core was generated by `/home/root/gdb_test/calwin.out'.
16Program terminated with signal SIGSEGV, Segmentation fault.
17#0 memset (__len=88, __ch=0, __dest=0x40) at /opt/fsl-imx-xwayland/5.4-zeus/sysroots/aarch64-poky-linux/usr/include/bits/string_fortified.h:71
1871 /opt/fsl-imx-xwayland/5.4-zeus/sysroots/aarch64-poky-linux/usr/include/bits/string_fortified.h: No such file or directory.
19[Current thread is 1 (Thread 0xffffe94b8190 (LWP 321))]
参考资料: Link to heading
GDB文档下载:GDB: The GNU Project Debugger
网页版书籍:Debugging with GDB
编程工具专栏文章之《用GDB调试程序》系列
makefile和gdb学习专栏文章之《gdb学习》系列