linux调试程序利器 GDB学习笔记
来源:互联网 发布:淘宝男鞋排行榜 编辑:程序博客网 时间:2024/06/05 05:29
作为程序员,调试程序是不可避免的,在windows下常用的IDE比如 keil 软件会有集成的debug图形化调试工具,使用起来非常简单易懂。在linux下虽然没有图形化调试工具,但是gdb作为文本界面的调试工具其功能也是非常强大的,在这里简单介绍gdb的用法。
一.调试准备
1.首先我们编写一个测试程序:
[lwn@VM_255_164_centos temp2]$vim gdbtest.c/********************************************************************************* 2 * Copyright: (C) 2017 SCUEC 3 * All rights reserved. 4 * 5 * Filename: gdbtest.c 6 * Description: This file 7 * 8 * Version: 1.0.0(04/01/17) 9 * Author: LI WJNG <liwjng@gmail.com> 10 * ChangeLog: 1, Release initial version on "04/01/17 15:19:12" 11 * 12 ********************************************************************************/ 13 14 #include <stdio.h> 15 16 int func(int n) 17 { 18 int sum=0,i; 19 for(i=0;i<n;i++) 20 { 21 sum += i; 22 } 23 return sum; 24 } 25 26 27 /******************************************************************************** 28 * Description: 29 * Input Args: 30 * Output Args: 31 * Return Value: 32 ********************************************************************************/ 33 int main (int argc, char **argv) 34 { 35 int i; 36 long result = 0; 37 int sum = 0; 38 sum = func(10); 39 for(i=0;i<100;i++) 40 { 41 result += i; 42 } 43 44 printf("the result is add 1 to 100 is %d\n",result); 45 printf("the sum is add 1 to %d is %d\n",10,sum); 46 return 0; 47 } /* ----- End of main() ----- */ 48
2.编译程序
要使用gdb调试,编译的时候一定要加上 -g 选项,如:gcc -g test.c,否则在gdb命令中l的时候会出现:No symbol table is loaded. Use the "file" command.错误提示;
[lwn@VM_255_164_centos temp2]$ gcc -g gdbtest.c -o test[lwn@VM_255_164_centos temp2]$ lsgdbtest.c test
3.使用gdb命令进入调试界面
如果直接使用gdb test 会打印gdb的版本信息等,为了显示简洁一点,使用gdb -q可以不显示版本信息
[lwn@VM_255_164_centos temp2]$ gdb -q testReading symbols from /home/lwn/mysrc/temp2/test...done.(gdb)
二.gdb调试命令:
在gdb调试界面下可以直接使用gdb的调试命令,enter继续执行上条命令。
下面逐条分析:
1.使用list(简写:l) 命令,将看到部分源程序清单。
list: 显示源程序1-10行
list +行号: 显示行号前后若干行
list +函数名: 显示函数前后若干行
这里就不一一列举了,所有有关list的相关操作可以使用 help list 命令进行查看
如:
(gdb) l main29 * Input Args:30 * Output Args:31 * Return Value:32 ********************************************************************************/33 int main (int argc, char **argv)34 {35 int i;36 long result = 0;37 int sum = 0;38 sum = func(10);(gdb) help list //可以看到有关list的命令说明List specified function or line.With no argument, lists ten more lines after or around previous listing."list -" lists the ten lines before a previous ten-line listing.One argument specifies a line, and ten lines are listed around that line.Two arguments with comma between specify starting and ending lines to list.Lines can be specified in these ways: LINENUM, to list around that line in current file, FILE:LINENUM, to list around that line in that file, FUNCTION, to list around beginning of that function, FILE:FUNCTION, to distinguish among like-named static functions. *ADDRESS, to list around the line containing that address.With two args if one is empty it stands for ten lines away from the other arg.
2.运行程序:run(简写:r),break(简写:b) ,continue(简写:c) ,until(简写:u)
run命令可以让程序全速运行,直到遇到断点处才停下来。如果没有设置断点,那么程序将一直运行到程序结束。
break命令用来设置断点,
break +行号:将断点设置在固定某行
break +函数名:将断点设置在函数开始处
info break:列出所有的断点
clear +行号:取消某行设置的断点
contin命令让程序继续运行到下一处断点,如果后面没有断点将一直运行到程序末尾。
until+行号:让程序执行到固定某行,其作用等同于 break+ 行号,再continu;使用until命令的前提是程序已经在运行状态
例如:
(gdb) l main29 * Input Args:30 * Output Args:31 * Return Value:32 ********************************************************************************/33 int main (int argc, char **argv)34 {35 int i;36 long result = 0;37 int sum = 0;38 sum = func(10);(gdb) b main //在main函数开始出设置断点Breakpoint 1 at 0x40056d: file gdbtest.c, line 36.(gdb) b 38 //在第38行设置断点Breakpoint 2 at 0x40057c: file gdbtest.c, line 38.(gdb) i b //命令info break列出所有的断点Num Type Disp Enb Address What1 breakpoint keep y 0x000000000040056d in main at gdbtest.c:36 breakpoint already hit 1 time2 breakpoint keep y 0x000000000040057c in main at gdbtest.c:38 breakpoint already hit 1 time(gdb) r //r命令让程序全速运行Starting program: /home/lwn/mysrc/temp2/testBreakpoint 1, main (argc=1, argv=0x7fffffffe5c8) at gdbtest.c:36 //遇到刚刚设置的第一个断点36行停了下来36 long result = 0;Missing separate debuginfos, use: debuginfo-install glibc-2.17-106.el7_2.8.x86_64(gdb) c //命令contin让程序继续运行Continuing.Breakpoint 2, main (argc=1, argv=0x7fffffffe5c8) at gdbtest.c:38 //运行到设置的第二个断点听了下来38 sum = func(10);(gdb) u 38//让程序执行到固定某一行main (argc=1, argv=0x7fffffffe5c8) at gdbtest.c:3838 sum = func(10);
3.单步运行next(简写:n) 和step(简写:s)
如果希望程序逐条语句地执行程序,不停地b、c太过于麻烦,gdb提供了更加step 和next命令,其作用是运行当前行。区别在于如果当前行设计函数调用,next命令会把函数当做一条语句整体执行完毕,而step命令会进入到函数内部继续单步运行,下面来看例子:
l (gdb) l //列出相关行的源程序31 * Return Value:32 ********************************************************************************/33 int main (int argc, char **argv)34 {35 int i;36 long result = 0;37 int sum = 0;38 sum = func(10);39 for(i=0;i<100;i++)40 {(gdb) b 38 //在调用函数的行设置断点Breakpoint 3 at 0x40057c: file gdbtest.c, line 38.(gdb) rThe program being debugged has been started already.Start it from the beginning? (y or n) yStarting program: /home/lwn/mysrc/temp2/testBreakpoint 3, main (argc=1, argv=0x7fffffffe5c8) at gdbtest.c:3838 sum = func(10);(gdb) n //可以看到使用next命令之后程序跳到了39行执行39 for(i=0;i<100;i++)————————————————————————————————————————————————————————————————————————————————————————————————————Breakpoint 3, main (argc=1, argv=0x7fffffffe5c8) at gdbtest.c:3838 sum = func(10);(gdb) s //同样使用step命令之后可以看到程序进入到了func函数去执行func (n=10) at gdbtest.c:1818 int sum=0,i;
4.打印相关信息info(简写:i),print(简写:p),display(简写:disp)
程序运行到某个位置的时候,我们使用info和print命令可以打印出一些变量的值
info local:打印局部变量的值
p + 变量名:打印该变量的值
display +变量名:每次程序停下来都自动打印该变量的值
来看例子:
(gdb) rStarting program: /home/lwn/mysrc/temp2/testBreakpoint 1, main (argc=1, argv=0x7fffffffe5c8) at gdbtest.c:3636 long result = 0;Missing separate debuginfos, use: debuginfo-install glibc-2.17-106.el7_2.8.x86_64(gdb) p result //打印result变量的值$1 = 140737488348608 //因为第36行语句还没执行,所以现在result还未被初始化,现在是一个垃圾值(gdb) i lo //打印所有局部变量的值i = 0result = 140737488348608sum = 0(gdb) disp result //每次遇到程序停下来都将显示变量result的值1: result = 140737488348608(gdb) cContinuing.Breakpoint 2, main (argc=1, argv=0x7fffffffe5c8) at gdbtest.c:3838 sum = func(10);1: result = 0 //result被初始化为0(gdb) cContinuing.Breakpoint 3, main (argc=1, argv=0x7fffffffe5c8) at gdbtest.c:4444 printf("the result is add 1 to 100 is %d\n",result);1: result = 4950 //result为最终的计算值
5.条件控制断点
在for循环中,有时候我们想让循环变量i为某个固定值的时候停下来查看某一变量,如果一直单步运行工作量有可能会很大。gdb提供了一个命令cond命令
话不多说,来看例子:
39 for(i=0;i<100;i++) 40 { 41 result += i; 42 }
在这个循环中,当i=10的时候我想看看result的值怎么办呢?很好办,往下看
首先在41行设置断点,然后使用cond 2 i==10
(gdb) b 41 //在41行设置断点Breakpoint 1 at 0x400592: file gdbtest.c, line 41.(gdb) cond 1 i==10 //当i等于10的时候程序停下来(gdb) rStarting program: /home/lwn/mysrc/temp2/testBreakpoint 1, main (argc=1, argv=0x7fffffffe5c8) at gdbtest.c:4141 result += i;(gdb) p i$1 = 10(gdb) p result//可以看到当i=10的时候 result 的值为45$2 = 45
在大多数情况下,灵活使用这些命令已经能够高效的调试程序了,如果对于这些gdb命令还有疑问的可以使用help命令获得详细的帮助信息。
1 0
- linux调试程序利器 GDB学习笔记
- GDB使用进阶-Linux程序调试利器
- Linux笔记 程序调试gdb
- GDB程序调试学习笔记
- 【Linux学习】GDB程序调试
- 程序调试的利器GDB
- 程序调试的利器GDB
- 程序调试的利器GDB
- Linux下的c/c++程序调试利器-----gdb/cgdb
- gdb调试利器的学习
- linux 程序调试利器
- linux环境gdb调试工具学习笔记
- linux GDB调试程序
- gdb 调试 linux程序
- Linux GDB调试++程序
- linux gdb调试程序
- linux嵌入式学习(LS2-GDB程序调试之学习笔记)
- 【GDB调试学习笔记】利用core文件调试程序
- STS搭建SVN过程及同步项目(详细)
- 网易机试-工作安排
- 表达式求值
- linux命令随笔(4)
- 关于apache的commons-dbutils如何读取blob类型
- linux调试程序利器 GDB学习笔记
- Android开发之内容提供者——创建自己的ContentProvider(详解)
- mq 消息最大长度 最大是100M
- 表达式求值:从“加减”到“带括号的加减乘除”的实践过程
- 图像用户界面 -- GUI总结
- 文字的输入输出和查找功能
- 12. Integer to Roman
- 有哪些相见恨晚的高效学习方法?
- css