linux的gdb总结
来源:互联网 发布:微信朋友圈网络出错 编辑:程序博客网 时间:2024/05/22 22:28
Linux 静态链接库和动态连接库
一:起因
(1)也许我们非常熟悉Windows下的VC6.0 和 CodeBlocks的调试工具 —— 界面化的调试,但是你是否想过你的每一个按键或者快捷键的背后指令是什么,让我们一起走进Linux的gcc动态调试工具GDB
(2)程序调试无非就是:debug(gcc -g -o target source);设置断点(b n);观察变脸(info locals);观察特定值(print expr);执行(start);执行下一行(next);进入子函数(step);执行到当前函数结尾(finish);查看源代码(list)等等操作
(3)gcc 的过程:C程序的编辑 用到vim; 程序的编译和运行用到gcc; 程序的调试用到gdb (kdbg是可视化的调试工具)
二:实例讲解
(1)调试步骤分为两步
1)编译时一定到 加上 -g 产生调试信息,让调试信息包含在可执行文件中exe —— 命令行下:
2)把可执行文件exe加载到调试环境中:
3) gdb为调试命令提示符,即可键入调试命令
(2)调试常用命令
1)基本调试命令(重要)
list 行号:列出产品从第几行开始的源代码; list 函数名:列出某个函数的源代码
start:开始执行程序,停在main函数第一行语句前面等待命令; next(n):执行下一列语句
step(s):执行下一行语句,如果有函数调用则进入到函数中 ;breaktrace(或bt):查看各级函数调用及参数
frame(f) 帧编号:选择栈帧 ; info(i) locals:查看当前栈帧局部变量的值
finish:执行到当前函数返回,然后挺下来等待命令 ; print(p):打印表达式的值,通过表达式可以修改变量的值或者调用函数
set var:修改变量的值 ;quit:退出gdb
2)高级调试命令
break(b) 行号:在某一行设置断点 ;break 函数名:在某个函数开头设置断点 ; break...if...:设置条件断点
continue(或c):从当前位置开始连续而非单步执行程序 ; delete breakpoints:删除所有断点 ;delete breakpoints n:删除序号为n的断点
disable breakpoints:禁用断点 ; enable breakpoints:启用断点
info(或i) breakpoints:参看当前设置了哪些断点; ; run(或r):从开始连续而非单步执行程序
display 变量名:跟踪查看一个变量,每次停下来都显示它的值 ;undisplay:取消对先前设置的那些变量的跟踪
3)格式化输入查看变量 print(p)
输出格式:一般来说,GDB会根据变量的类型输出变量的值。但你也可以自定义GDB的输出的格式。
例如,你想输出一个整数的十六进制,或是二进制来查看这个整型变量的中的位的情况。要
做到这样,你可以使用GDB的数据显示格式:
x 按十六进制格式显示变量。 d 按十进制格式显示变量。
u 按十六进制格式显示无符号整型。 o 按八进制格式显示变量。
t 按二进制格式显示变量。 a 按十六进制格式显示变量。
c 按字符格式显示变量。 f 按浮点数格式显示变量。
Linux编程基础——GDB(设置断点)
启动GDB后,首先就是要设置断点,程序中断后才能调试。在gdb中,断点通常有三种形式:
断点(BreakPoint):
在代码的指定位置中断,这个是我们用得最多的一种。设置断点的命令是break,它通常有如下方式:
- break <function> 在进入指定函数时停住
- break <linenum> 在指定行号停住。
- break +/-offset 在当前行号的前面或后面的offset行停住。offiset为自然数。
- break filename:linenum 在源文件filename的linenum行处停住。
- break ... if <condition> ...可以是上述的参数,condition表示条件,在条件成立时停住。比如在循环境体中,可以设置break if i=100,表示当i为100时停住程序。
可以通过info breakpoints [n]命令查看当前断点信息。此外,还有如下几个配套的常用命令:
- delete 删除所有断点
- delete breakpoint [n] 删除某个断点
- disable breakpoint [n] 禁用某个断点
- enable breakpoint [n] 使能某个断点
观察点(WatchPoint):
在变量读、写或变化时中断,这类方式常用来定位bug。
- watch <expr> 变量发生变化时中断
- rwatch <expr> 变量被读时中断
- awatch <expr> 变量值被读或被写时中断
可以通过info watchpoints [n]命令查看当前观察点信息
捕捉点(CatchPoint):
捕捉点用来补捉程序运行时的一些事件。如:载入共享库(动态链接库)、C++的异常等。通常也是用来定位bug。
捕捉点的命令格式是:catch <event>,event可以是下面的内容
- throw C++抛出的异常时中断
- catch C++捕捉到的异常时中断
- exec 调用系统调用exec时(只在某些操作系统下有用)
- fork 调用系统调用fork时(只在某些操作系统下有用)
- vfork 调用系统调用vfork时(只在某些操作系统下有用)
- load 或 load <libname> 载入共享库时(只在某些操作系统下有用)
- unload 或 unload <libname> 卸载共享库时(只在某些操作系统下有用)
另外,还有一个tcatch <event>,功能类似,不过他只设置一次捕捉点,当程序停住以后,应点被自动删除。
捕捉点信息的查看方式和代码断点的命令是一样的,这里就不多介绍了。
在特定线程中中断
你可以定义你的断点是否在所有的线程上,或是在某个特定的线程。GDB很容易帮你完成这一工作。
- break <linespec> thread <threadno>
- break <linespec> thread <threadno> if ...
linespec指定了断点设置在的源程序的行号。threadno指定了线程的ID,注意,这个ID是GDB分配的,你可以通过"info threads"命令来查看正在运行程序中的线程信息。如果你不指定thread <threadno>则表示你的断点设在所有线程上面。你还可以为某线程指定断点条件。如:
(gdb) break frik.c:13 thread 28 if bartab > lim
当你的程序被GDB停住时,所有的运行线程都会被停住。这方便你你查看运行程序的总体情况。而在你恢复程序运行时,所有的线程也会被恢复运行。那怕是主进程在被单步调试时。
恢复程序运行和单步调试
在gdb中,和调试步进相关的命令主要有如下几条:
- continue 继续运行程序直到下一个断点(类似于VS里的F5)
- next 逐过程步进,不会进入子函数(类似VS里的F10)
- setp 逐语句步进,会进入子函数(类似VS里的F11)
- until 运行至当前语句块结束
- finish 运行至函数结束并跳出,并打印函数的返回值(类似VS的Shift+F11)
PS:这些命令大部分可以简写为第一个字母,在日常使用过程中,往往只会输入第一个字符即可执行该命令,我标红的即是通常的使用方式。这几条命令使用非常频繁,并且可以带一些附加参数以实现高级功能,需要熟练掌握。
(2)对于Segmentfault(段错误)等不提示的信息的调试方法
大概三步走~~~( # ./core_dump_run运行时产生段错误,但是编译阶段gcc –o []不报错)
第一步:设置core文件大小为无限(默认为0,即不产生)如果想让系统在信号中断造成的错误时产生core文件,我们需要在shell中按如下设置:
#设置core文件大小为无限
ulimit -c unlimited
#设置core文件大小为1000kb
ulimit –c 1000
#查看设置的大小
ulimit –c
[@sjs_37_33 t_core_gdb]# ulimit-c
100000
第二步:#gcc(g++)-g -o core_dump_run core_dump_test.c,并运行#./core_dump_run产生core.pid文件
第三步:#gdb core_dump_runcore.pid 即可调试 (gdb)start -à nextà bk直接到错误之处
附加:对于第三步中提示信息太少的,但是提供了错误地址的可以反编译:objdump
#objdump –d core_dump_run
代码:
(3)gdb多线程调试
先介绍一下GDB多线程调试的基本命令。
info threads 显示当前可调试的所有线程,每个线程会有一个GDB为其分配的ID,后面操作线程的时候会用到这个ID。前面有*的是当前调试的线程。
thread ID 切换当前调试的线程为指定ID的线程。
break thread_test.c:123 thread all 在所有线程中相应的行上设置断点
thread apply ID1 ID2 command 让一个或者多个线程执行GDB命令command。
thread apply all command 让所有被调试线程执行GDB命令command。
set scheduler-locking off|on|step 估计是实际使用过多线程调试的人都可以发现,在使用step或者continue命令调试当前被调试线程的时候,其他线程也是同时执行的,怎么只让被调试程序执行呢?通过这个命令就可以实现这个需求。off不锁定任何线程,也就是所有线程都执行,这是默认值。 on只有当前被调试程序会执行。 step在单步的时候,除了next过一个函数的情况(熟悉情况的人可能知道,这其实是一个设置断点然后continue的行为)以外,只有当前线程会执行。
gdb对于多线程程序的调试有如下的支持:
· 线程产生通知:在产生新的线程时, gdb会给出提示信息
(gdb) r
Starting program: /root/thread
[New Thread 1073951360 (LWP 12900)]
[New Thread 1082342592 (LWP 12907)]---以下三个为新产生的线程
[New Thread 1090731072 (LWP 12908)]
[New Thread 1099119552 (LWP 12909)]
· 查看线程:使用info threads可以查看运行的线程。
(gdb) info threads
4 Thread 1099119552 (LWP 12940) 0xffffe002 in ?? ()
3 Thread 1090731072 (LWP 12939) 0xffffe002 in ?? ()
2 Thread 1082342592 (LWP 12938) 0xffffe002 in ?? ()
* 1 Thread 1073951360 (LWP 12931) main (argc=1,argv=0xbfffda04) at thread.c:21
(gdb)
注意,行首的蓝色文字为gdb分配的线程号,对线程进行切换时,使用该该号码,而不是上文标出的绿色数字。
另外,行首的红色星号标识了当前活动的线程
· 切换线程:使用 threadTHREADNUMBER 进行切换,THREADNUMBER 为上文提到的线程号。下例显示将活动线程从 1 切换至 4。
(gdb) info threads
4 Thread 1099119552 (LWP 12940) 0xffffe002 in ?? ()
3 Thread 1090731072 (LWP 12939) 0xffffe002 in ?? ()
2 Thread 1082342592 (LWP 12938) 0xffffe002 in ?? ()
* 1 Thread 1073951360 (LWP12931) main (argc=1, argv=0xbfffda04) at thread.c:21
(gdb) thread 4
[Switching to thread 4 (Thread 1099119552 (LWP 12940))]#0 0xffffe002 in ?? ()
(gdb) info threads
* 4 Thread 1099119552 (LWP12940) 0xffffe002 in ?? ()
3 Thread 1090731072 (LWP 12939) 0xffffe002 in ?? ()
2 Thread 1082342592 (LWP 12938) 0xffffe002 in ?? ()
1 Thread 1073951360 (LWP 12931) main (argc=1,argv=0xbfffda04) at thread.c:21
(gdb)
后面就是直接在你的线程函数里面设置断点,然后continue到那个断点,一般情况下多线程的时候,由于是同时运行的,最好设置 setscheduler-locking on
这样的话,只调试当前线程
三:个人心得
(0)记录个人成长中的收获的点点滴滴,哪怕跌倒再次爬起来,也是一种难得的经验 —— 我一直为自己前几年没有留下成长记忆而苦恼,如今时时刻刻的督促自己写一写自己的声音。
(1)哪怕一周花一到两个小时的时间,整理一下自己当下的心得和学习所得;从短期看:这会加深自己对知识的理解;从长远来看:虽然花费了一两个小时,但是最终你是赚了的。
(2)也许我们都会有类似的经历 —— 我们今天遇到的难题,前几天刚刚遇到过,处理过;但是,遗憾的是,自己忘记如何处理的了,更悲催的是,我们都忘了是哪一个模块里的;仅仅记得刚刚处理过这个问题;纠结纠结 ~~~浪费同样的时间处理一个相似的问题。
- linux的gdb总结
- Linux使用GDB调试总结
- gdb 的使用总结
- gdb的使用总结
- gdb的使用总结
- gdb 的使用总结
- GDB调试器的总结(调试linux c)
- linux gdb的使用方法.
- linux gdb的watchpoint
- Linux 的gcc gdb
- gdb命令的常用总结
- linux 下使用gdb调试总结
- Linux笔记--gcc与gdb总结
- linux 下gdb的使用
- linux下的gdb调试
- arm-linux的gdb移植
- 刚学linux的gdb
- arm-linux的gdb移植
- 冒泡排序
- 关于List集合转化为数组
- 2.4 VB编程基础--常量
- (二十)文本流与数据流
- 使用Jsoup解析网页
- linux的gdb总结
- 产品研发记录05:产品研发人员应当具备的特质
- Android studio2.2.3 支持Java8
- C与C++文件的相互引用
- Python利用openpyxl库遍历Sheet的方法
- 线程池介绍
- 分布式数据访问层(DAL)
- hbase空间清理
- TCP UDP 的区别