【软件调试】gdb初识

1.学习链接

pstack使用和原理 

xiaofei0859的《编译链接》专栏-质量高

Linux程序分析工具介绍—ldd,nm

软件调试

推荐阅读1

GDB设置显示选项

一篇适合入门

写的非常好,全面

GDB调整动态库

GDB十个常用的命令

gdb官方学习文档链接

LINUX下GDB的使用方法(简单说说)

GDB基础和高级部分的内容都有的链接

引用阅读-写的超级好,就是排版有点乱,嘻嘻

gdb调试程序时跳进函数和跳出函数

多进程和多线程调试

超级好文

断点原理与实现

一次性打印出所有线程的堆栈信息

gdb用watch来追踪变量值的变化

2.gdb的一些参数

GDB 调试主要有三种方式:
1. gdb filename  直接调试目标程序
2. gdb attach pid 附加进程
3. gdb filename corename 调试 core 文件


finish --执行完当前函数并回到函数调用点(如果在循环体内执行,则执行完整个循环,不一定会执行完当前函数)
return --停止执行当前函数并回到函数调用点
thread apply all bt 一次性答应出所有线程的信息(或thr app all bt)

3.gdb的TUI

推荐链接1

GDB中的TUI的官方说明文档

4.GDB-COMMANDS

演示代码:
#include <stdio.h>


struct book {
  //   char a;
     char *name;
     int year;
     int price;
}bk;

static int func(int n){

    int sum = 0,i;
     for(i = 0;i< n;i++)
     {
       sum += i;
     }
     return sum;
}

static void modify_book(void)
{
     int i = 0;
     while(1){
             bk.name = "Linux device driver";
             bk.year = i;
             bk.price = i;
             i++;
             printf("%d\n",i);
             sleep(1);
    };
}

int main(int argc ,char **argv)
{
     int i;
     int result = 0;
     for(i = 1;i<=100;i++)
     {
         result +=1;
     }
     printf("result[1-100]=%d \n ",result);
     printf("result[1-250]=%d \n ",func(250));

     modify_book();// 假设此行设置了断点且运行到此处停下来了,如果此时在此处如果敲s的话,会进入这个函数里面执行;如果敲n的话,会将这句话执行完.

     return 0;

}



调试过程:
[root@localhost 0028-gdb]# gdb main.debug -q
Reading symbols from /home/muten/C/0028-gdb/main.debug...done.
(gdb) b 45
Breakpoint 1 at 0x401221: file 001-main.c, line 45.
(gdb) r
Starting program: /home/muten/C/0028-gdb/main.debug 
result[1-100]=100 
 result[1-250]=31125 

Breakpoint 1, main (argc=1, argv=0x7fffffffdb68) at 001-main.c:45
45	     modify_book();// 假设此行设置了断点且运行到此处停下来了,如果此时在此处如果敲s的话,会进入这个函数里面执行;如果敲n的话,会将这句话执行完.
Missing separate debuginfos, use: debuginfo-install glibc-2.17-317.el7.x86_64
(gdb) s【单步运行】
modify_book () at 001-main.c:23
(gdb) layout src
(gdb) bt【查看函数调用信息(堆栈)】
#0  modify_book () at 001-main.c:23
#1  0x0000000000401226 in main (argc=1,	argv=0x7fffffffdb68) at 001-main.c:45
(gdb) p	bk【查看bk的值】
$1 = {name = 0x0, year = 0, price = 0}
(gdb) p	bk.year=2010【将bk.year的值改成2010】
$2 = 2010
(gdb) p	bk【再次查看bk的值】
$3 = {name = 0x0, year = 2010, price = 0}
(gdb) p	&bk【查看结构体的基地址】
$4 = (struct book *) 0x404050 <bk>
(gdb) x/3w 0x404050
0x404050 <bk>:	0	0	2010
(gdb) x/8w 0x404050
0x404050 <bk>:	0	0	2010	0
0x404060:	0	0	0	0
(gdb) x/16w 0x404050
0x404050 <bk>:	0	0	2010	0
0x404060:	0	0	0	0
0x404070:	0	0	0	0
0x404080:	0	0	0	0
(gdb) x/16x 0x404050【以16进制(x)看以0x404050为起始地址的16个word的地址】
0x404050 <bk>:	0x00000000	0x00000000	0x000007da	0x00000000
0x404060:	0x00000000	0x00000000	0x00000000	0x00000000
0x404070:	0x00000000	0x00000000	0x00000000	0x00000000
0x404080:	0x00000000	0x00000000	0x00000000	0x00000000
0x404050 <bk>:	0x00000000	0x00000000	0x000007da	0x00000000
0x404060:	0x00000000	0x00000000	0x00000000	0x00000000
(gdb) set *(int*)0x404058=2019【更改0x404058处对应的int类型的变量的值】
(gdb) p	bk
$3 = {name = 0x0, year = 2019, price = 0}
继续运行,之后CTRL+C,TUI中看不到源码的时候说明函数进内核态了,TUI显示的代码是运行的代码,
此时运行bt
(gdb) bt                                                                                                                                                     Line: 24   PC: 0x4011c3 
#0  0x00007ffff7ad2840 in __nanosleep_nocancel () from /lib64/libc.so.6
#1  0x00007ffff7ad26f4 in sleep () from /lib64/libc.so.6
#2  0x00000000004011c3 in modify_book () at 001-main.c:30
#3  0x0000000000401226 in main (argc=1,	argv=0x7fffffffdb68) at 001-main.c:45
(gdb) finish【将#0运行完】
Run till exit from #0  0x00007ffff7ad2840 in __nanosleep_nocancel () from /lib64/libc.so.6
0x00007ffff7ad26f4 in sleep () from /lib64/libc.so.6
(gdb) finish【将#1运行完】
Run till exit from #0  0x00007ffff7ad26f4 in sleep () from /lib64/libc.so.6
modify_book () at 001-main.c:24
(gdb) bt
#0  modify_book () at 001-main.c:24
#1  0x0000000000401226 in main (argc=1,	argv=0x7fffffffdb68) at 001-main.c:45
(gdb) watch bk.year
Hardware watchpoint 2: bk.year

一些图片:

5.strace+addr2line调试

strace+addr2line调试
strace 是一个集诊断、调试、统计与一体的工具,我们可以使用strace,对应用的系统调用和信号传递的跟踪结果,来对应用进行分析,以达到解决问题,或者是了解应用工作过程的目的。

strace 的简单的用法就是,执行一个指定的命令,在指定的命令结束之后,它也就退出了。
在命令执行的过程中,strace 会记录和解析命令进程的所有系统调用,以及这个进程所接收到的,所有的信号值。

-c ,统计每一系统调用的所执行的时间,次数和出错的次数等
-p ,指定进程pid
-i ,输出系统调用的入口指针

linux 下操作过程(省略部分加载信息):
strace -i ./a.out 找到段错误的地址
addr2line -e a.out 地址

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值