gdb调试命令可以重新回到上一句吗

博客访问: 3976828
博文数量: 1023
博客积分: 19333
博客等级: 上将
技术积分: 11209
注册时间:
IT168企业级官微
微信号:IT168qiye
系统架构师大会
微信号:SACC2013
gdb基本命令&
本文介绍使用gdb调试程序的常用命令。&
主要内容:&
=============&
GDB是GNU开源组织发布的一个强大的UNIX下的程序调试工具。如果你是在 UNIX平台下做软件,你会发现GDB这个调试工具有比VC、BCB的图形化调试器更强大的功能。同时GDB也具有例如ddd这样的图形化的调试端。&
一般来说,GDB主要完成下面四个方面的功能:&
(1)启动你的程序,可以按照你的自定义的要求随心所欲的运行程序。&
(2)可让被调试的程序在你所指定的调置的断点处停住。(断点可以是条件表达式)&
(3)当程序被停住时,可以检查此时你的程序中所发生的事。&
(4)动态的改变你程序的执行环境。&
兴趣是最好的老师,这里先整理总结一下在调试的过程中经常遇到的问题。带着这些问题进行学习和实践可以有助于加深印象。 再往后是本人实践过程中总结的常见命令,如有什么问题或者建议,都可以联系我,谢谢!^_^&
(1)如何打印变量的值?(print var)&
(2)如何打印变量的地址?(print &var)&
(3)如何打印地址的数据值?(print *address)&
(4)如何查看当前运行的文件和行?(backtrace)&
(5)如何查看指定文件的代码?(list file:N)&
(6)如何立即执行完当前的函数,但是并不是执行完整个应用程序?(finish)&
(7)如果程序是多文件的,怎样定位到指定文件的指定行或者函数?(list file:N)&
(8)如果循环次数很多,如何执行完当前的循环?(until)&
(9)多线程如何调试?(???)&
作者:QuietHeart&
Email: quiet_&
=============&
这样可以和gdb进行交互了。&
*启动gdb,并且分屏显示源代码:&
$gdb -tui&
这样,使用了'-tui'选项,启动可以直接将屏幕分成两个部分,上面显示源代码,比用list方便多了。这时候使用上下方向键可以查看源代码,想要命令行使用上下键就用[Ctrl]n和[Ctrl]p.&
*启动gdb调试指定程序app:&
这样就在启动gdb之后直接载入了app可执行程序,需要注意的是,载入的app程序必须在编译的时候有gdb调试选项,例如'gcc -g app app.c',注意,如果修改了程序的源代码,但是没有编译,那么在gdb中显示的会是改动后的源代码,但是运行的是改动前的程序,这样会导致跟踪错乱的。&
*启动程序之后,再用gdb调试:&
$gdb &program& &PID&&
这里,&program&是程序的可执行文件名,&PID&是要调试程序的PID.如果你的程序是一个服务程序,那么你可以指定这个服务程序运行时的进程ID。gdb会自动attach上去,并调试他。program应该在PATH环境变量中搜索得到。&
*启动程序之后,再启动gdb调试:&
$gdb &PID&&
这里,程序是一个服务程序,那么你可以指定这个服务程序运行时的进程ID,&PID&是要调试程序的PID.这样gdb就附加到程序上了,但是现在还没法查看源代码,用file命令指明可执行文件就可以显示源代码了。&
**启动gdb之后的交互命令:&
交互命令支持[Tab]补全。&
*显示帮助信息:&
(gdb) help&
*载入指定的程序:&
(gdb) file app&
这样在gdb中载入想要调试的可执行程序app。如果刚开始运行gdb而不是用gdb app启动的话可以这样载入app程序,当然编译app的时候要加入-g调试选项。&
*重新运行调试的程序:&
(gdb) run&
要想运行准备调试的程序,可使用run命令,在它后面可以跟随发给该程序的任何参数,包括标准输入和标准输出说明符(&和& )和shell通配符(*、?、[、])在内。&
*修改发送给程序的参数:&
(gdb) set args no&
这里,假设我使用"r yes"设置程序启动参数为yes,那么这里的set args会设置参数argv[1]为no。&
*显示缺省的参数列表:&
(gdb) show args&
*列出指定区域(n1到n2之间)的代码:&
(gdb) list n1 n2&
这样,list可以简写为l,将会显示n1行和n2行之间的代码,如果使用-tui启动gdb,将会在相应的位置显示。如果没有n1和n2参数,那么就会默认显示当前行和之后的10行,再执行又下滚10行。另外,list还可以接函数名。&
一般来说在list后面可以跟以下这们的参数:&
&linenum& & 行号。&
&+offset& & 当前行号的正偏移量。&
&-offset& & 当前行号的负偏移量。&
&filename:linenum& &哪个文件的哪一行。&
&function& &函数名。&
&filename:function& 哪个文件中的哪个函数。&
&*address& &程序运行时的语句在内存中的地址。&
*执行下一步:&
(gdb) next&
这样,执行一行代码,如果是函数也会跳过函数。这个命令可以简化为n.&
*执行N次下一步:&
(gdb) next N&
*执行上次执行的命令:&
(gdb) [Enter]&
这里,直接输入回车就会执行上次的命令了。&
*单步进入:&
(gdb) step&
这样,也会执行一行代码,不过如果遇到函数的话就会进入函数的内部,再一行一行的执行。&
*执行完当前函数返回到调用它的函数:&
(gdb) finish&
这里,运行程序,直到当前函数运行完毕返回再停止。例如进入的单步执行如果已经进入了某函数,而想退出该函数返回到它的调用函数中,可使用命令finish.&
*指定程序直到退出当前循环体:&
(gdb) until&
或(gdb) u&
这里,发现需要把光标停止在循环的头部,然后输入u这样就自动执行全部的循环了。&
*跳转执行程序到第5行:&
(gdb) jump 5&
这里,可以简写为"j 5"需要注意的是,跳转到第5行执行完毕之后,如果后面没有断点则继续执行,而并不是停在那里了。&
另外,跳转不会改变当前的堆栈内容,所以跳到别的函数中就会有奇怪的现象,因此最好跳转在一个函数内部进行,跳转的参数也可以是程序代码行的地址,函数名等等类似list。&
*强制返回当前函数:&
(gdb) return&
这样,将会忽略当前函数还没有执行完毕的语句,强制返回。return后面可以接一个表达式,表达式的返回值就是函数的返回值。&
*强制调用函数:&
(gdb) call &expr&&
这里,&expr&可以是一个函数,这样就会返回函数的返回值,如果函数的返回类型是void那么就不会打印函数的返回值,但是实践发现,函数运行过程中的打印语句还是没有被打印出来。&
*强制调用函数2:&
(gdb) print &expr&&
这里,print和call的功能类似,不同的是,如果函数的返回值是void那么call不会打印返回值,但是print还是会打印出函数的返回值并且存放到历史记录中。&
*在当前的文件中某一行(假设为6)设定断点:&
(gdb) break 6&
*设置条件断点:&
(gdb) break 46 if testsize==100&
这里,如果testsize==100就在46行处断点。&
*检测表达式变化则停住:&
(gdb) watch i != 10&
这里,i != 10这个表达式一旦变化,则停住。watch &expr& 为表达式(变量)expr设置一个观察点。一量表达式值有变化时,马上停住程序(也是一种断点)。&
*在当前的文件中为某一函数(假设为func)处设定断点:&
(gdb) break func&
*给指定文件(fileName)的某个行(N)处设置断点:&
(gdb) break fileName:N&
这里,给某文件中的函数设置断点是同理的。&
*显示当前gdb断点信息:&
(gdb) info breakpoints&
这里,可以简写为info break.会显示当前所有的断点,断点号,断点位置等等。&
*删除N号断点:&
(gdb) delete N&
*删除所有断点:&
(gdb) delete&
*清除行N上面的所有断点:&
(gdb) clear N&
*继续运行程序直接运行到下一个断点:&
(gdb) continue&
这里,如果没有断点就一直运行。&
*显示当前调用函数堆栈中的函数:&
(gdb) backtrace&
命令产生一张列表,包含着从最近的过程开始的所有有效过程和调用这些过程的参数。当然,这里也会显示出当前运行到了哪里(文件,行)。&
*查看当前调试程序的语言环境:&
(gdb) show language&
这里,如果gdb不能识别你所调试的程序,那么默认是c语言。&
*查看当前函数的程序语言:&
(gdb) info frame&
*显示当前的调试源文件:&
(gdb) info source&
这样会显示当前所在的源代码文件信息,例如文件名称,程序语言等。&
*手动设置当前的程序语言为c++:&
(gdb) set language c++&
这里,如果gdb没有检测出你的程序语言,你可以这样设置。&
*查看可以设置的程序语言:&
(gdb) set language&
这里,使用没有参数的set language可以查看gdb中可以设置的程序语言。&
*终止一个正在调试的程序:&
(gdb) kill&
这里,输入kill就会终止正在调试的程序了。&
*print显示变量(var)值:&
(gdb) print var&
这里,print可以简写为p,print 是gdb的一个功能很强的命令,利用它可以显示被调试的语言中任何有效的表达式。表达式除了包含你程序中的变量外,还可以包含函数调用,复杂数据结构和历史等等。&
*用16进制显示(var)值:&
(gdb) print /x var&
这里可以知道,print可以指定显示的格式,这里用'/x'表示16进制的格式。&
可以支持的变量显示格式有:&
x &按十六进制格式显示变量。&
d &按十进制格式显示变量。&
u &按十六进制格式显示无符号整型。&
o &按八进制格式显示变量。&
t &按二进制格式显示变量。&
a &按十六进制格式显示变量。&
c &按字符格式显示变量。&
f &按浮点数格式显示变量。&
*如果a是一个数组,10个元素,如果要显示则:&
(gdb) print *a@10&
这样,会显示10个元素,无论a是double或者是int的都会正确地显示10个元素。&
*修改运行时候的变量值:&
(gdb) print x=4&
这里,x=4是C/C++的语法,意为把变量x值改为4,如果你当前调试的语言是Pascal,那么你可以使用Pascal的语法:x:=4。&
*显示一个变量var的类型:&
(gdb) whatis var&
*以更详细的方式显示变量var的类型:&
(gdb) ptype var&
这里,会打印出var的结构定义。&
=============&
*在Qt4.x环境中打印QS的msg变量:&
步骤如下:&
1)定义一个宏printqstring&
define printqstring&
& & printf "(QString)0x%x (length=%i): \"",&$arg0,$arg0.d-&size&
& & set $i=0&
& & while $i & $arg0.d-&size&
& & & & set $c=$arg0.d-&data[$i++]&
& & & & if $c & 32 || $c & 127&
& & & & & & & & printf "\\u0x%04x", $c&
& & & & else&
& & & & & & & & printf "%c", (char)$c&
& & & & end&
& & printf "\"\n"&
2)(gdb) printqstring msg&
这里,这个宏可以在gdb中直接定义,据说也可以写到$HOME/.gdbinit,这样每次启动自动加载。&
*调试同时指明生成core文件:&
$gdb &program& core&
用gdb同时调试一个运行程序和core文件,core是程序非法执行后core dump后产生的文件。当程序非法崩溃的时候会产生一个core文件,然后使用这个命令,会直接定位到发生程序崩溃的位置。注意:有时需要设置系统命令“ulimit -c unlimited”才能产生core文件。&
**没有实践过的&
*print显示存储块,如显示h后面的10个整数:&
print h@10&
阅读(39256) | 评论(2) | 转发(11) |
相关热门文章
给主人留下些什么吧!~~
(gdb)&call&schedBreak(1000000)warn:&need&to&stop&all&queues(gdb)&continueContinuing.gem5&Simulator&System.&&http://gem5.orggem5&is&copyrighted&&use&the&--copyright&option&for&details.
(gdb)&call&schedBreak(1000000)warn:&need&to&stop&all&queues(gdb)&continueContinuing.gem5&Simulator&System.&&http://gem5.orggem5&is&copyrighted&&use&the&--copyright&option&for&details.
请登录后评论。拒绝访问 |
| 百度云加速
请打开cookies.
此网站 () 的管理员禁止了您的访问。原因是您的访问包含了非浏览器特征(3a6d95f-ua98).
重新安装浏览器,或使用别的浏览器gdb调试从入门到精通_百度文库
两大类热门资源免费畅读
续费一年阅读会员,立省24元!
gdb调试从入门到精通
&&从0起点讲解gdb调试工具,保证使你从一个门外汉变成一个调试高手
阅读已结束,下载文档到电脑
想免费下载更多文档?
定制HR最喜欢的简历
下载文档到电脑,方便使用
还剩47页未读,继续阅读
定制HR最喜欢的简历
你可能喜欢2197人阅读
linux应用开发与busybox(10)
为什么使用gdb调试正在运行的程序?
& & &因为有时候bug很难复现、或者环境搭建起来比较困难,所以在出现bug的时候可以使用gdb的attach功能调试正在运行的GCC编译出来的程序,注意编译选项要加-g,否则没有符号表。
调试步骤?
& & &1. 编译时候带-g选项。
& & &2. 运行程序。
& & &3. ps找到进程号。
& & &4. 启动gdb,使用attach选项,这时gdb会停止在程序的某处。
& & &5. 按照GDB调试方法调试。当程序退出之后,依然可以使用run命令重启程序。
用gdb可以调试当前的程序的使用情况,读出他的参数。
以下用一个简单的程序做为例子:来说明gdb的调试。
第一步& 编译一个死循环程序。&
/* File name malloc.c*/
#include & &stdio.h& &&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&
#include&& &stdlib.h&
#include&& &string.h&
void getmem(void **p, int num){
&&& *p = (void *)malloc(num);
void test(void){
&&& char *str = NULL;
&&& getmem((void **)&str, 100);
&&&&&&& strcpy(str, &Hello&);
&&& printf(&%s/n&, str);
int main(void){
&&& int i = 0;
&&& while(1){
&&&&&&& if (i == 1){&
&&&&&&&&&&& test();
&&&&&&&&&&& return 1;
&&&&&&& }&&&
&&& return 0;
}&&&&&&&&&&&&&&&&&
我们可以看出,这个程序就是malloc一段内存空间,用来供strcpy使用,由于只是调试一下,就没有在test程序中加上一些关于strcpy的正确性判断语句。
函数的正常退出的情况是i==1,但是程序运行过程中根本无法使i==1成立。i的变量的值将会在使用gdb时用到。
$gcc -g malloc.c&
得用gdb,加上-g还是需要的。生成的可执行文件为a.out
第二步& 让gdb连接到正在执行的进程上去&
首先运行程序。
明显的,是一个死循环。
重新开一个shell
我的机器的运行情况如下所示:
Warning: bad ps syntax, perhaps a bogus '-'? See http://procps.sf.net/faq.html
USER&&&&&& PID %CPU %MEM&&& VSZ&& RSS TTY&&&&& STAT START&& TIME COMMAND
wyc&&&&&& & 0.1&&
pts/8&&& Ss&& 10:24&& 0:00 bash
wyc&&&&&& & 0.1&&
pts/9&&& Ss&& 10:27&& 0:00 bash
wyc&&&&&& & 0.3& 1 pts/9&&& S+&& 10:28&& 0:00 gdb
wyc&&&&&& & 0.0&& 1652&& 284 pts/8&&& R+&& 10:42&& 0:13 ./a.out
看到没有? ./a.out的进程号是8347。
现在启动gdb
由于是调试运行的进程,不是可执行文件,后面不需要跟任何参数。在用 gdb调试运行状态下的程序时,最核心的就是gdb内部的attach命令
&(gdb) attach&
这是我的机器上的例子:
GNU gdb (GDB) 7.1.50.
Copyright (C) 2010 Free Software Foundation, Inc.
License GPLv3+: GNU GPL version 3 or later&
This is free software: you are free to change and redistribute it.
There is NO WARRANTY, to the extent permitted by law.& Type &show copying&
and &show warranty& for details.
This GDB was configured as &i686-pc-linux-gnu&.
For bug reporting instructions, please see:
(gdb) attach 8347
Attaching to process 8347
Reading symbols from /home/wyc/desktop/my_program/review/a.out...done.
Reading symbols from /lib/tls/i686/cmov/libc.so.6...(no debugging symbols found)...done.
Loaded symbols for /lib/tls/i686/cmov/libc.so.6
Reading symbols from /lib/ld-linux.so.2...(no debugging symbols found)...done.
Loaded symbols for /lib/ld-linux.so.2
main () at malloc.c:19
19&&& &&& &&& if (i == 1){
(gdb) set i=1
Ambiguous set command &i=1&: .
Undefined info command: &=1&.& Try &help info&.
(gdb) set i=1
Ambiguous set command &i=1&: .
(gdb) set var i=1
16&&& int main(void){
17&&& &&& int i = 0;
18&&& &&& while(1){
19&&& &&& &&& if (i == 1){
20&&& &&& &&& &&& test();
21&&& &&& &&& &&& return 1;
22&&& &&& &&& }
23&&& &&& }
20&&& &&& &&& &&& test();
21&&& &&& &&& &&& return 1;
0xb7f47775 in __libc_start_main () from /lib/tls/i686/cmov/libc.so.6
Single stepping until exit from function __libc_start_main,&
which has no line number information.
Program exited with code 01.
在运行到第20行命令的时候,可以看一下到运行./a.out的那个shell,应该hello字符串在标准输出上了。当gdb中显示进程退出时,./a.out的shell应该结束了当前进程了。
在gdb中用set var i=1&来修改变量i的值(用set i=1不能识别命令),使程序能够正常退出。
在调试时,当前程序调用的所有库也全部都出来了。这个例子中的
Reading symbols from /home/wyc/desktop/my_program/review/a.out...done.
Reading symbols from /lib/tls/i686/cmov/libc.so.6...(no debugging symbols found)...done.
Loaded symbols for /lib/tls/i686/cmov/libc.so.6
Reading symbols from /lib/ld-linux.so.2...(no debugging symbols found)...done.
Loaded symbols for /lib/ld-linux.so.2
是a.out程序所调用的全部库。可以用这种办法分析当前运行的程序的库的调用情况。
千万不要关掉gdb,以下调试更精彩:
第三步 在gdb中重启程序&
在上面已经知道了程序正常退出了,但是gdb还没有退出,这时在gdb中运行run效果如何?
(gdb) run&
Starting program: /home/wyc/desktop/my_program/review/a.out&
下面是死循环了...
接下Ctrl+c,给gdb发个SIGINT的信号。
Program received signal SIGINT, Interrupt.
main () at malloc.c:19
19&&& &&& &&& if (i == 1){
(gdb) set var i=1
20&&& &&& &&& &&& test();
21&&& &&& &&& &&& return 1;
0xb7e7b775 in __libc_start_main () from /lib/tls/i686/cmov/libc.so.6
Single stepping until exit from function __libc_start_main,&
which has no line number information.
Program exited with code 01.
可以看出,用gdb连接进程后,他会找到运行这个进程所需的全部文件,当前进程关闭后,仍然可以在gdb中启动这个程序。
不得不佩服GDB的调试功能的强大
gdb中的其它命令,就看你分析程序时是否用到了,例如下面的一些简单的命令:
常用的bt, p , p/x , setp, info registers, break , jump ......
&&相关文章推荐
* 以上用户言论只代表其个人观点,不代表CSDN网站的观点或立场
访问:147205次
积分:3448
积分:3448
排名:第10154名
原创:182篇
转载:157篇
评论:11条
(15)(19)(23)(28)(5)(9)(1)(4)(8)(39)(9)(27)(27)(8)(14)(15)(12)(2)(1)(1)(10)(10)(8)(23)(27)
(window.slotbydup = window.slotbydup || []).push({
id: '4740881',
container: s,
size: '200,200',
display: 'inlay-fix'}

我要回帖

更多关于 gdb core 调试 的文章

更多推荐

版权声明:文章内容来源于网络,版权归原作者所有,如有侵权请点击这里与我们联系,我们将及时删除。

点击添加站长微信