Table of Contents
调试时调用函数
观察点
GDB宏
调试是一项复杂的任务。开发人员大部分时间都花在调试上,因此熟悉许多调试工具很重要
在Linux中,本机调试器是GDB,它是基于命令行的,看起来丑陋而原始。许多开发人员,尤其是那些从Windows移走并使用Visual Studio等工具的开发人员,都没有给GDB一个机会。
GDB是基于命令行的,您需要学习命令,并且看起来像在80年代进行调试,但是有些任务只能用GDB来完成
我们将使用以下代码:
#include<stdio.h> #define addnum(a,b) ((a)+(b)) #define max(a,b) (a)>(b)?(addnum(a,100)):(addnum(b,50)) int a1=10,a2=20; void f2() { printf("X"); } void print_dbg() { char buf[15]; printf("a1=%d a2=%d \n",a1,a2); strcpy(buf, "hello world"); } int add(int a, int b) { int c; c= max(a+90,b+20); c+=b; return c; } void f1() { int i; int *p=NULL; print_dbg(); i=add(80,90); for(i=0;i<100;i++) { if(i % 20 == 0) a1++; f2(); } *p=100; } int arr[1000]; void main() { arr[0]=1; f1(); printf("hello %d\n",arr[0]); }当GDB在断点处停止或执行代码时,您可以调用带有或不带有参数的函数。
(gdb) b add Breakpoint 1 at 0x400654: file ./a.c, line 21. (gdb) r Starting program: myapp a1=10 a2=20 Breakpoint 1, add (a=80, b=90) at ./a.c:21 21 int c= a+90; (gdb) call print_dbg() a1=10 a2=20 (gdb) delete breakpoints Delete all breakpoints? (y or n) y (gdb) b a.c:34 Breakpoint 2 at 0x4006bd: file ./a.c, line 34. (gdb) c Continuing. Breakpoint 2, f1 () at ./a.c:34 34 a1++; (gdb) call add(2,3) $1 = 95GDB的主要功能之一是能够在更改某些内容时中断。它可以是变量,地址或寄存器:
(gdb) watch a1 Hardware watchpoint 1: a1 (gdb) r Starting program: /home/developer/examples/debuggingExamples/debugtests/app a1=10 a2=20 Hardware watchpoint 1: a1 Old value = 10 New value = 11 f1 () at ./a.c:35 35 f2();观看地址变更
我们首先打印数组地址:
(gdb) p &arr $1 = (int (*)[1000]) 0x601080 <arr>然后要求GDB在该地址的内容更改时停止
(gdb) watch *0x601080 Hardware watchpoint 1: *0x601080 (gdb) r Starting program: /home/developer/examples/debuggingExamples/debugtests/app Hardware watchpoint 1: *0x601080 Old value = 0 New value = 1 main () at ./a.c:43 43 f1();观察点注册变更
使用寄存器也可以这样做。
(gdb) watch $rax Watchpoint 1: $rax (gdb) c Continuing. Watchpoint 1: $rax Old value = 4196067 New value = 0 0x00000000004006f6 in main () at ./a.c:43 43 f1();
使用.gdbinit文件,您还可以为调试会话定义新命令(宏)。例如,如果您将以下内容写入.gdbinit:
define irg info registers info threads end define pdb print a1 print a2 call print_dbg() end它定义了两个可以使用的新宏– pdb,irg
(gdb) pdb $2 = 10 $3 = 20 a1=10 a2=20 (gdb) irg rax 0x0 0 rbx 0x0 0 rcx 0x6f77206f6c6c6568 8031924123371070824 rdx 0x7ffff7dd3780 140737351858048 rsi 0x5a 90 rdi 0x50 80 rbp 0x7fffffffdb50 0x7fffffffdb50 rsp 0x7fffffffdb50 0x7fffffffdb50 r8 0x0 0 r9 0xd 13 r10 0x0 0 r11 0x246 582 r12 0x4004e0 4195552 r13 0x7fffffffdc60 140737488346208 r14 0x0 0 r15 0x0 0 rip 0x400654 0x400654 <add+10> eflags 0x246 [ PF ZF IF ] cs 0x33 51 ss 0x2b 43 ds 0x0 0 es 0x0 0 fs 0x0 0 gs 0x0 0 Id Target Id Frame * 1 process 35330 "app" add (a=80, b=90) at ./a.c:28https://devarea.com/10-things-you-can-only-do-with-gdb/#.X3roCkUzaUk
