gdb调试时调用函数、设置观察点以及GDB的宏
程序员文章站
2022-07-14 12:33:54
...
Table of Contents
调试是一项复杂的任务。开发人员大部分时间都花在调试上,因此熟悉许多调试工具很重要
在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 = 95
观察点
GDB的主要功能之一是能够在更改某些内容时中断。它可以是变量,地址或寄存器:
(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();
GDB宏
使用.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:28
https://devarea.com/10-things-you-can-only-do-with-gdb/#.X3roCkUzaUk
上一篇: Python中的函数装饰器和闭包原理
下一篇: (4.2.50)一种业务控件实现的方式