hchen/test> gdb tst <---------- 启动GDB GNU gdb 5.1.1 Copyright 2002 Free Software Foundation, Inc. GDB is free software, covered by the GNU General Public License, and you are welcome to change it and/or distribute copies of it under certain conditions. Type "show copying" to see the conditions. There is absolutely no warranty for GDB. Type "show warranty" for details. This GDB was configured as "i386-SUSE-linux"... (gdb) l <-------------------- l命令相当于list,从第一行开始例出原码。 1 #include <stdio.h> 2 3 int func(int n) 4 { 5 int sum=0,i; 6 for(i=0; i<n; i++) 7 { 8 sum+=i; 9 } 10 return sum; (gdb) <-------------------- 直接回车表示,重复上一次命令 11 } 12 13 14 main() 15 { 16 int i; 17 long result = 0; 18 for(i=1; i<=100; i++) 19 { 20 result += i; (gdb) break 16 <-------------------- 设置断点,在源程序第16行处。 Breakpoint 1 at 0x8048496: file tst.c, line 16. (gdb) break func <-------------------- 设置断点,在函数func()入口处。 Breakpoint 2 at 0x8048456: file tst.c, line 5. (gdb) info break <-------------------- 查看断点信息。 Num Type Disp Enb Address What 1 breakpoint keep y 0x08048496 in main at tst.c:16 2 breakpoint keep y 0x08048456 in func at tst.c:5 (gdb) r <--------------------- 运行程序,run命令简写 Starting program: /home/hchen/test/tst
Breakpoint 1, main () at tst.c:17 <---------- 在断点处停住。 17 long result = 0; (gdb) n <--------------------- 单条语句执行,next命令简写。 18 for(i=1; i<=100; i++) (gdb) n 20 result += i; (gdb) n 18 for(i=1; i<=100; i++) (gdb) n 20 result += i; (gdb) c <--------------------- 继续运行程序,continue命令简写。 Continuing. result[1-100] = 5050 <----------程序输出。
Breakpoint 2, func (n=250) at tst.c:5 5 int sum=0,i; (gdb) n 6 for(i=1; i<=n; i++) (gdb) p i <--------------------- 打印变量i的值,print命令简写。 $1 = 134513808 (gdb) n 8 sum+=i; (gdb) n 6 for(i=1; i<=n; i++) (gdb) p sum $2 = 1 (gdb) n 8 sum+=i; (gdb) p i $3 = 2 (gdb) n 6 for(i=1; i<=n; i++) (gdb) p sum $4 = 3 (gdb) bt <--------------------- 查看函数堆栈。 #0 func (n=250) at tst.c:5 #1 0x080484e4 in main () at tst.c:24 #2 0x400409ed in __libc_start_main () from /lib/libc.so.6 (gdb) finish <--------------------- 退出函数。 Run till exit from #0 func (n=250) at tst.c:5 0x080484e4 in main () at tst.c:24 24 printf("result[1-250] = %d /n", func(250) ); Value returned is $6 = 31375 (gdb) c <--------------------- 继续运行。 Continuing. result[1-250] = 31375 <----------程序输出。
Program exited with code 027. <--------程序退出,调试结束。 (gdb) q <--------------------- 退出gdb。 hchen/test>
好了,有了以上的感性认识,还是让我们来系统地认识一下gdb吧。
基本gdb命令:
GDB常用命令 格式 含义 简写 list List [开始,结束] 列出文件的代码清单 l prit Print 变量名 打印变量内容 p break Break [行号或函数名] 设置断点 b continue Continue [开始,结束] 继续运行 c info Info 变量名 列出信息 i next Next 下一行 n step Step 进入函数(步入) S display Display 变量名 显示参数 file File 文件名(可以是绝对路径和相对路径) 加载文件 run Run args 运行程序 r
四、GDB实战
下面是一个使用了上述命令的实战例子:
[root@www.linuxidc.com bufbomb]# gdb bufbomb GNU gdb (GDB) Red Hat Enterprise Linux (7.2-75.el6) Copyright (C) 2010 Free Software Foundation, Inc. License GPLv3+: GNU GPL version 3 or later <http:///licenses/gpl.html> This is free software: you are free to change and redistribute it. There is NO WARRANTY, to the extent permitted by law. Type "show copying" and "show warranty" for details. This GDB was configured as "x86_64-RedHat-linux-gnu". For bug reporting instructions, please see: <http://www./software/gdb/bugs/>... Reading symbols from /root/Temp/bufbomb/bufbomb...done. (gdb) b getbuf Breakpoint 1 at 0x8048ad6 (gdb) run -t cdai Starting program: /root/Temp/bufbomb/bufbomb -t cdai Team: cdai Cookie: 0x5e5ee04e
Breakpoint 1, 0x08048ad6 in getbuf () Missing separate debuginfos, use: debuginfo-install glibc-2.12-1.149.el6_6.4.i686
(gdb) bt #0 0x08048ad6 in getbuf () #1 0x08048db2 in test () #2 0x08049085 in launch () #3 0x08049257 in main () (gdb) info frame 0 Stack frame at 0xffffb540: eip = 0x8048ad6 in getbuf; saved eip 0x8048db2 called by frame at 0xffffb560 Arglist at 0xffffb538, args: Locals at 0xffffb538, Previous frame's sp is 0xffffb540 Saved registers: ebp at 0xffffb538, eip at 0xffffb53c (gdb) info registers eax 0xc 12 ecx 0xffffb548 -19128 edx 0xc8c340 13157184 ebx 0x0 0 esp 0xffffb510 0xffffb510 ebp 0xffffb538 0xffffb538 esi 0x804b018 134524952 edi 0xffffffff -1 eip 0x8048ad6 0x8048ad6 <getbuf+6> eflags 0x282 [ SF IF ] cs 0x23 35 ss 0x2b 43 ds 0x2b 43 es 0x2b 43 fs 0x0 0 gs 0x63 99 (gdb) x/10x $sp 0xffffb510: 0xf7ffc6b0 0x00000001 0x00000001 0xffffb564 0xffffb520: 0x08048448 0x0804a12c 0xffffb548 0x00c8aff4 0xffffb530: 0x0804b018 0xffffffff
(gdb) si 0x08048ad9 in getbuf () (gdb) si 0x08048adc in getbuf () (gdb) si 0x080489c0 in Gets () (gdb) n Single stepping until exit from function Gets, which has no line number information. Type string:123 0x08048ae1 in getbuf () (gdb) si 0x08048ae2 in getbuf () (gdb) c Continuing. Dud: getbuf returned 0x1 Better luck next time
[root@www.linuxidc.com bufbomb]# gdb bufbomb GNU gdb (GDB) Red Hat Enterprise Linux (7.2-75.el6) Copyright (C) 2010 Free Software Foundation, Inc. License GPLv3+: GNU GPL version 3 or later <http:///licenses/gpl.html> This is free software: you are free to change and redistribute it. There is NO WARRANTY, to the extent permitted by law. Type "show copying" and "show warranty" for details. This GDB was configured as "x86_64-redhat-linux-gnu". For bug reporting instructions, please see: <http://www./software/gdb/bugs/>... Reading symbols from /root/Temp/bufbomb/bufbomb...done.
(gdb) b getbuf Breakpoint 1 at 0x8048ad6 (gdb) b main Breakpoint 2 at 0x80490c6
(gdb) run -t cdai The program being debugged has been started already. Start it from the beginning? (y or n) y
Breakpoint 2, 0x080490c6 in main () (gdb) record (gdb) c Continuing. Team: cdai Cookie: 0x5e5ee04e
Breakpoint 1, 0x08048ad6 in getbuf ()
(gdb) rn Single stepping until exit from function getbuf, which has no line number information. 0x08048dad in test () (gdb) rn Single stepping until exit from function test, which has no line number information. 0x08049080 in launch () (gdb) rn Single stepping until exit from function launch, which has no line number information. 0x08049252 in main ()
4.2VSCode+GDB+Qemu调试ARM64 linux内核
linux kernel是一个非常复杂的系统,初学者会很难入门。如果有一个方便的调试环境,学习效率至少能有5-10倍的提升。
# bryant @ ubuntu in ~/Downloads/busybox-1.33.1/_install [1:02:17] $ mkdir etc dev lib # bryant @ ubuntu in ~/Downloads/busybox-1.33.1/_install [1:02:17] $ ls bin dev etc lib linuxrc sbin usr
config SERIAL_AMBA_PL011_CONSOLE bool "Support for console on AMBA serial port" depends on SERIAL_AMBA_PL011=y select SERIAL_CORE_CONSOLE select SERIAL_EARLYCON help Say Y here if you wish to use an AMBA PrimeCell UART as the system console (the system console is the device which receives all kernel messages and warnings and which allows logins in single user mode).
Even if you say Y here, the currently visible framebuffer console (/dev/tty0) will still be used as the system console by default, but you can alter that using a kernel command line option such as "console=ttyAMA0". (Try "man bootparam" or see the documentation of your boot loader (lilo or loadlin) about how to pass options to the kernel at boot time.)