欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

gdb调试时调用函数、设置观察点以及GDB的宏

程序员文章站 2022-07-14 12:33:54
...

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 = 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

 

相关标签: 【基础知识】