Linux调试.docx
- 文档编号:26005540
- 上传时间:2023-06-17
- 格式:DOCX
- 页数:26
- 大小:30.43KB
Linux调试.docx
《Linux调试.docx》由会员分享,可在线阅读,更多相关《Linux调试.docx(26页珍藏版)》请在冰豆网上搜索。
Linux调试
在Linux下调试程序一般用GDB来执行。
这里简要介绍一下是否gdb调试程序的方法:
(1)进入gdb调试:
gdb+已经编译通过的可执行程序-》就进入调试模式。
例如:
gdbMiddlePublisher
(2)r+运行时的参数 -》开始运行可执行程序。
例如r-lxml2-frefile
(3)b+断点 -》设置调试的断点。
两种:
一种是:
bCMSTask.cpp:
200 表示在CMSTask.cpp文件的第200行设置断点。
另一种:
bTaskManager:
:
buildPubWinTask表示在执行buildPubWinTask这个函数的时候停止。
(4)取消断点:
dis1 表示取消第一个断点
dis2 表示取消第二个断点
(5)查看设置断点信息:
info b
(6)在断点停止处查看所在代码的详细信息:
l
(7)可以在gdb中直接编译,然后再重新运行时,gdb会直接执行新编译好的可执行程序。
例如:
直接在gdb下执行make后再重庆运行。
(8)跟进一个函数:
s
如果设置的断点是在一个函数入口。
到达该断点时,键入s就可以进入该函数内部进行调试。
如果有多个函数就多次键入S来进入内部的函数。
(9)单步执行:
n
例如:
直接在gdb下键入n,进行单步执行
(10)继续执行:
c
例如:
直接在gdb键入c,可以在断点停止后继续执行。
如果断点是一个循环,则可以继续执行一个循环,再停止断点上面。
PS:
1、在SecureCRT远程登录界面上开启多个窗口。
在窗口之间切换时用:
Alt+1,Alt+2.....表示切换到第1个,第2个窗口。
2、同样在在SecureCRT远程登录界面上要粘贴复制好的内容用:
Shift+Insert
3、vim一个文件的妙用:
(1)首先用vim打开一个文件,再在命令行下键入“:
vsplit***”在同一个窗口打开另一个文件。
×××表示另一个文件。
(2)打开后,用Ctrl+W按两次在两个窗口之间切换。
(3)如果要关掉一个其中一个窗口,就切换到那个窗口,键入“:
close”就可以了。
(4)复制某一行,先按y1,再转到复制目的地按p。
如果复制多行先在复制源地第一行按y2,然后回车,再把光标移动到最后一行,按回车。
最后到复制目的地按p,就可以了。
GDB 概述
————
GDB 是 GNU 开源组织发布的一个强大的 UNIX 下的程序调试工具。
或许,各位比较喜欢那种图形界面方式的,像 VC、 BCB 等 IDE 的调试,但如果你是在 UNIX 平台下做软件,你会发现 GDB 这个调试工具有比 VC 、 BCB 的图形化调试器更强大的功能。
所谓 “ 寸有所长,尺有所短 ” 就是这个道理。
一般来说, GDB 主要帮忙你完成下面四个方面的功能:
1 、启动你的程序,可以按照你的自定义的要求随心所欲的运行程序。
2 、可让被调试的程序在你所指定的调置的断点处停住。
(断点可以是条件表达式)
3 、当程序被停住时,可以检查此时你的程序中所发生的事。
4 、动态的改变你程序的执行环境。
从上面看来, GDB 和一般的调试工具没有什么两样,基本上也是完成这些功能,不过在细节上,你会发现 GDB 这个调试工具的强大,大家可能比较习惯了图形化的调试工具,但有时候,命令行的调试工具却有着图形化工具所不能完成的功能。
让我们一一看来。
一个调试示例
——————
源程序:
tst.c
1#include
2
3intfunc(intn)
4{
5 intsum=0,i;
6 for(i=0;i 7 { 8 sum+=i; 9 } 10 returnsum; 11} 12 13 14main() 15{ 16 inti; 17 longresult=0; 18 for(i=1;i<=100;i++) 19 { 20 result+=i; 21 } 22 23 printf("result[1-100]=%d/n",result); 24 printf("result[1-250]=%d/n",func(250)); 25} 编译生成执行文件: ( Linux 下) hchen/test>cc-gtst.c-otst 使用 GDB 调试: hchen/test>gdbtst <---------- 启动 GDB GNUgdb5.1.1 Copyright2002FreeSoftwareFoundation,Inc. GDBisfreesoftware,coveredbytheGNUGeneralPublicLicense,andyouare welcometochangeitand/ordistributecopiesofitundercertainconditions. Type"showcopying"toseetheconditions. ThereisabsolutelynowarrantyforGDB. Type"showwarranty"fordetails. ThisGDBwasconfiguredas"i386-suse-linux"... (gdb)l <--------------------l 命令相当于 list ,从第一行开始例出原码。 1 #include 2 3 intfunc(intn) 4 { 5 intsum=0,i; 6 for(i=0;i 7 { 8 sum+=i; 9 } 10 returnsum; (gdb) <-------------------- 直接回车表示,重复上一次命令 11 } 12 13 14 main() 15 { 16 inti; 17 longresult=0; 18 for(i=1;i<=100;i++) 19 { 20 result+=i; (gdb)break16 <-------------------- 设置断点,在源程序第 16 行处。 Breakpoint1at0x8048496: filetst.c,line16. (gdb)breakfunc <-------------------- 设置断点,在函数 func() 入口处。 Breakpoint2at0x8048456: filetst.c,line5. (gdb)infobreak <-------------------- 查看断点信息。 NumType DispEnbAddress What 1 breakpoint keepy 0x08048496inmainattst.c: 16 2 breakpoint keepy 0x08048456infuncattst.c: 5 (gdb)r <--------------------- 运行程序, run 命令简写 Startingprogram: /home/hchen/test/tst Breakpoint1,main()attst.c: 17 <---------- 在断点处停住。 17 longresult=0; (gdb)n <--------------------- 单条语句执行, next 命令简写。 18 for(i=1;i<=100;i++) (gdb)n 20 result+=i; (gdb)n 18 for(i=1;i<=100;i++) (gdb)n 20 result+=i; (gdb)c <--------------------- 继续运行程序, continue 命令简写。 Continuing. result[1-100]=5050 <---------- 程序输出。 Breakpoint2,func(n=250)attst.c: 5 5 intsum=0,i; (gdb)n 6 for(i=1;i<=n;i++) (gdb)pi <--------------------- 打印变量 i 的值, print 命令简写。 $1=134513808 (gdb)n 8 sum+=i; (gdb)n 6 for(i=1;i<=n;i++) (gdb)psum $2=1 (gdb)n 8 sum+=i; (gdb)pi $3=2 (gdb)n 6 for(i=1;i<=n;i++) (gdb)psum $4=3 (gdb)bt <--------------------- 查看函数堆栈。 #0 func(n=250)attst.c: 5 #1 0x080484e4inmain()attst.c: 24 #2 0x400409edin__libc_start_main()from/lib/libc.so.6 (gdb)finish <--------------------- 退出函数。 Runtillexitfrom#0 func(n=250)attst.c: 5 0x080484e4inmain()attst.c: 24 24 printf("result[1-250]=%d/n",func(250)); Valuereturnedis$6=31375 (gdb)c <--------------------- 继续运行。 Continuing. result[1-250]=31375 <---------- 程序输出。 Programexitedwithcode027.<-------- 程序退出,调试结束。 (gdb)q <--------------------- 退出 gdb 。 hchen/test> 好了,有了以上的感性认识,还是让我们来系统地认识一下 gdb 吧。 使用 GDB ———— 一般来说 GDB 主要调试的是 C/C++ 的程序。 要调试 C/C++ 的程序,首先在编译时,我们必须要把调试信息加到可执行文件中。 使用编译器( cc/gcc/g++ )的 -g 参数可以做到这一点。 如: >cc-ghello.c-ohello >g++-ghello.cpp-ohello 如果没有 -g ,你将看不见程序的函数名、变量名,所代替的全是运行时的内存地址。 当你用 -g 把调试信息加入之后,并成功编译目标代码以后,让我们来看看如何用 gdb 来调试他。 启动 GDB 的方法有以下几种: 1 、 gdb program 也就是你的执行文件,一般在当然目录下。 2 、 gdb 用 gdb 同时调试一个运行程序和 core 文件, core 是程序非法执行后 coredump 后产生的文件。 3 、 gdb 如果你的程序是一个服务程序,那么你可以指定这个服务程序运行时的进程 ID 。 gdb 会自动 attach 上去,并调试他。 program 应该在 PATH 环境变量中搜索得到。 GDB 启动时,可以加上一些 GDB 的启动开关,详细的开关可以用 gdb-help 查看。 我在下面只例举一些比较常用的参数: -symbols -s 从指定文件中读取符号表。 -sefile 从指定文件中读取符号表信息,并把他用在可执行文件中。 -core -c 调试时 coredump 的 core 文件。 -directory -d 加入一个源文件的搜索路径。 默认搜索路径是环境变量中 PATH 所定义的路径。 GDB 的命令概貌 ——————— 启动 gdb 后,就你被带入 gdb 的调试环境中,就可以使用 gdb 的命令开始调试程序了, gdb 的命令可以使用 help命令来查看,如下所示: /home/hchen>gdb GNUgdb5.1.1 Copyright2002FreeSoftwareFoundation,Inc. GDBisfreesoftware,coveredbytheGNUGeneralPublicLicense,andyouare welcometochangeitand/ordistributecopiesofitundercertainconditions. Type"showcopying"toseetheconditions. ThereisabsolutelynowarrantyforGDB. Type"showwarranty"fordetails. ThisGDBwasconfiguredas"i386-suse-linux". (gdb)help Listofclassesofcommands: aliases--Aliasesofothercommands breakpoints--Makingprogramstopatcertainpoints data--Examiningdata files--Specifyingandexaminingfiles internals--Maintenancecommands obscure--Obscurefeatures running--Runningtheprogram stack--Examiningthestack status--Statusinquiries support--Supportfacilities tracepoints--Tracingofprogramexecutionwithoutstoppingtheprogram user-defined--User-definedcommands Type"help"followedbyaclassnameforalistofcommandsinthatclass. Type"help"followedbycommandnameforfulldocumentation. Commandnameabbreviationsareallowedifunambiguous. (gdb) gdb 的命令很多, gdb 把之分成许多个种类。 help 命令只是例出 gdb 的命令种类,如果要看种类中的命令,可以使用 help helpbreakpoints ,查看设置断点的所有命令。 也可以直接 help gdb 中,输入命令时,可以不用打全命令,只用打命令的前几个字符就可以了,当然,命令的前几个字符应该要标志着一个唯一的命令,在 Linux 下,你可以敲击两次 TAB 键来补齐命令的全称,如果有重复的,那么 gdb 会把其例出来。 示例一: 在进入函数 func 时,设置一个断点。 可以敲入 breakfunc ,或是直接就是 bfunc (gdb)bfunc Breakpoint1at0x8048458: filehello.c,line10. 示例二: 敲入 b 按两次 TAB 键,你会看到所有 b 打头的命令: (gdb)b backtrace break bt (gdb) 示例三: 只记得函数的前缀,可以这样: (gdb)bmake_< 按 TAB 键 > (再按下一次 TAB 键,你会看到 : ) make_a_section_from_file make_environ make_abs_section make_function_type make_blockvector make_pointer_type make_cleanup make_reference_type make_command make_symbol_completion_list (gdb)bmake_ GDB 把所有 make 开头的函数全部例出来给你查看。 示例四: 调试 C++ 的程序时,有可以函数名一样。 如: (gdb)b'bubble(M-? bubble(double,double) bubble(int,int) (gdb)b'bubble( 你可以查看到 C++ 中的所有的重载函数及参数。 (注: M-? 和 “ 按两次 TAB 键 ” 是一个意思) 要退出 gdb 时,只用发 quit 或命令简称 q 就行了。 GDB 中运行 UNIX 的 shell 程序 ———————————— 在 gdb 环境中,你可以执行 UNIX 的 shell 的命令,使用 gdb 的 shell 命令来完成: shell 调用 UNIX 的 shell 来执行 /bin/sh 。 (在Windows 中使用 C 或 cmd.exe ) 还有一个 gdb 命令是 make : make 可以在 gdb 中执行 make 命令来重新 build 自己的程序。 这个命令等价于 “shellmake 在 GDB 中运行程序 ———————— 当以 gdb 如要确认 gdb 是否读到源文件,可使用 l 或 list 命令,看看 gdb 是否能列出源代码。 在 gdb 中,运行程序使用 r 或是 run 命令。 程序的运行,你有可能需要设置下面四方面的事。 1 、程序运行参数。 setargs 可指定运行时参数。 (如: setargs1020304050 ) showargs 命令可以查看设置好的运行参数。 2 、运行环境。 path showpaths 查看程序的运行路径。 setenvironmentvarname[=value] 设置环境变量。 如: setenvUSER=hchen showenvironment[varname] 查看环境变量。 3 、工作目录。 cd
pwd 显示当前的所在目录。
4 、程序的输入输出。
infoterminal 显示你程序用到的终端的模式。
使用重定向控制程序输出。
如:
run>outfile
tty 命令可以指写输入输出的终端设备。
如:
tty/dev/ttyb
调试已运行的程序
————————
两种方法:
1 、在 UNIX 下用 ps 查看正在运行的程序的 PID (进程 ID ),然后用 gdb
2 、先用 gdb
并用detach 来取消挂接的进程。
暂停 / 恢复程序运行
—————————
调试程序中,暂停程序运行是必须的, GDB 可以方便地暂停程序的运行。
你可以设置程序的在哪行停住,在什么条件下停住,在收到什么信号时停往等等。
以便于你查看运行时的变量,以及运行
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- Linux 调试