《嵌入式 Linux C 语言应用程序设计(修订版)》——2.4 嵌入式Linux调试器GDB的使用...

    xiaoxiao2023-09-06  158

    本节书摘来异步社区《嵌入式 Linux C 语言应用程序设计(修订版)》一书中的第2章,第2.4节,作者:华清远见嵌入式培训中心,孙琼,更多章节内容可以访问云栖社区“异步社区”公众号查看

    2.4 嵌入式Linux调试器GDB的使用

    嵌入式 Linux C 语言应用程序设计(修订版)在程序编译通过生成可执行文件之后,就进入了程序的调试环节。调试一直来是程序开发中的重中之重,如何使程序员能够迅速找到错误的原因是一款调试器的目标。

    GDB是GNU开源组织发布的一个强大的Linux下的程序调试工具,它是一种强大的命令行调试工具。

    一个出色的调试器需要有以下几项功能。

    能够运行程序,设置所有能影响程序运行的参数。能够让程序让指定的条件下停止。能够在程序停止时检查所有参数的情况。能够根据指定条件改变程序的运行。

    2.4.1 GDB使用实例

    下面通过一个简单的实例使读者对GDB有一个感性的认识,这里所介绍的指令都是GDB中最为基本也是最为常用的指令,希望读者能够动手操作,掌握GDB的使用方法。 首先,有以下程序段。

    #include <stdio.h> /*子函数add:将自然数从1~m相加*/ int add(int m) { int i,n=0; for(i=1; i<=m;i++) n += i; printf("The sum of 1-%d in add is %d\n", m,n); } int main() { int i,n=0; add(50); for(i=1; i<=50; i++) n += i; printf("The sum of 1-50 is %d \n", n ); }``` 注意将此程序用GCC进行编译时要加上“-g”选项。 1.进入GDB 进入GDB只需输入GDB和要调试的可执行文件即可,如下所示:

    [root@localhost gdb]# gdb testGNU gdb Red Hat Linux (6.3.0.0-1.21rh)Copyright 2004 Free Software Foundation, Inc.GDB is free software, covered by the GNU General Public License, and you arewelcome to change it and/or distribute copies of it under certain conditions.Type "show copying" to see the conditions.There is absolutely no warranty for GDB. Type "show warranty" for details.This GDB was configured as "i386-redhat-linux-gnu"...Using host libthread_db library "/lib/libthread_db.so.1".(gdb)`可以看出,在GDB的启动画面中指出了GDB的版本号、使用的库文件等信息,接下来就进入了由“(gdb)”开头的命令行界面了。

    2.查看文件在GDB中键入‘l’(list)就可以查看所载入的文件,如下所示:

    (gdb) l 4 { 5 int i,n=0; 6 for(i=1; i<=m;i++) 7 n += i; 8 printf("The sum of 1-%d in add is %d\n", m,n); 9 } 10 11 int main() 12 { 13 int i,n=0; (gdb) l 14 add(50); 15 for(i=1; i<=50; i++) 16 { 17 n += i; 18 } 19 printf("The sum of 1-50 is %d \n", n ); 20 21 } 22``` 可以看出,GDB列出的源代码中明确地给出了对应的行号,这样可以大大地方便代码的定位。 注意 在一般情况下,源代码中的行号与用户书写程序中的行号是一致的,但有时由于用户的某些编译选项会导致行号不一致的情况,因此,一定要查看在GDB中的行号。 3.设置断点 设置断点可以使程序到一定位置暂停它的运行,程序员在该位置处可以方便地查看变量的值、堆栈情况等,从而找出代码的症结所在。 在GDB中设置断点非常简单,只需在“b”后加入对应的行号即可(这是最常用的方式,另外还有其他方式设置断点),其命令如下所示:

    (gdb) b 6Breakpoint 1 at 0x804846d: file test.c, line 6.`要注意的是,在GDB中利用行号设置断点是指代码运行到对应行之前暂停,如上例中,代码运行到第5行之前暂停(并没有运行第5行)。

    4.查看断点处情况在设置完断点之后,用户可以键入“info b”来查看设置断点情况,在GDB中可以设置多个断点。

    (gdb) info b Num Type Disp Enb Address What 1 breakpoint keep y 0x0804846d in main at test.c:6``` 5.运行代码 接下来就可运行代码了,GDB默认从首行开始运行代码,可键入“r”(run)即可,在“r”后面加上行号即可从程序中指定行开始运行。

    (gdb) rStarting program: /home/yul/book/test

    Breakpoint 1, add (m=50) at test.c:66 for(i=1; i<=m;i++)`可以看到,程序运行到断点处就停止了。

    6.查看变量值在程序停止运行之后,程序员需要查看断点处的相关变量值。在GDB中只需键入“p+变量值”即可,如下所示:

    (gdb) p n $1 = 0 (gdb) p i $2 = 134518440``` 在此处,为什么变量“i”的值为如此奇怪的一个数字呢?原因就在于程序是在断点设置的对应行之前停止的,那么在此时,并没有把“i”的数值赋为0,而只是一个随机的数字。但变量“n”是在第5行赋值的,故在此时已经为0。 小技巧 GDB在显示变量值时都会在对应值之前加上“$N”标记,它是当前变量值的引用标记,所以以后若想再次引用此变量就可以直接写作“$N”,而无需写冗长的变量名。 7.观察变量 在某一循环处,程序员往往希望能够观察一个变量的变化情况,这时就可以键入命令“watch”来观察变量的变化情况,如下所示:

    (gdb) watch nHardware watchpoint 2: n`可以看到,GDB在“n”设置了观察点。

    注意 在此处必须键入完整的命令“watch”,因为在GDB中有不少以‘w’开头的命令,如“where”、“while”等。8.单步运行单步运行是指一次只运行一条语句,这样可以方便程序员来查看程序运行的结果,在此处只需键入“n”(next)即可。

    (gdb) n 7 n += i; (gdb) n Hardware watchpoint 2: n Old value = 15 New value = 21``` 可以看到,随着程序的单步运行,当“n”的值发生变化时,GDB就会自动显示出n的变化情况。 9.程序继续运行 命令“c”(continue)可以使GDB继续运行以下的程序,程序在再次遇到断点时停止,如下所示:

    (gdb) cContinuing.The sum of 1-50 is 1275

    Program exited with code 031.`10.退出GDB退出GDB只需使用指令“q”(quit)即可,如下所示:

    (gdb) q [root@localhost gcc]``` 到此为止,使用GDB的整体过程已经结束了。以上所讲述的命令是GDB中最为常见的命令,下面几节将会详细讲解GDB的命令。 ####2.4.2 设置/删除断点 GDB中有丰富的断点设置、删除命令,可以满足用户各个方面的需求。表2.8列出了GDB中常见的断点设置及删除命令。 <div style="text-align: center"><img src="https://yqfile.alicdn.com/a56468a016c6d970fe2232b3bbd7b5cc2aaab282.png" width="" height=""> </div> 小知识 在多线程的程序中,观察点的作用很有限,gdb只能观察在一个线程中的表达式的值。如果用户确信表达式只被当前线程所存取,那么使用观察点才有效。gdb不能注意一个非当前线程对表达式值的改变。 ####2.4.3 数据相关命令 在GDB中也有丰富的数据显示相关命令,他们可以使用户可以以各种形式显示所要查看的数据,数据相关命令如表2.9所示。 <div style="text-align: center"><img src="https://yqfile.alicdn.com/4f4452e2fdb008919d83e14f8e00e20857a92db7.png" width="" height=""> </div> 小技巧 在使用print命令时,可以对变量按指定格式进行输出,其命令格式为:print /变量名+格式其中格式有以下几种方式。 X:十六进制;d:十进制;u:无符号数;o:八进制; T:二进制;a:十六进制打印;c:字符格式;f:浮点数。 ####2.4.4 调试运行环境相关命令 在GDB中控制程序的运行也是非常方便地,用户可以自行设定变量值、调用函数等,其具体命令如表2.10所示。 <div style="text-align: center"><img src="https://yqfile.alicdn.com/08416332779a2fabc91ab5d82f7397328bb6b619.png" width="" height=""> </div> ####2.4.5 堆栈相关命令 gdb中也提供了多种堆栈相关的命令,可以查看堆栈的情况、寄存器的情况等,其具体命令如表2.11所示。 <div style="text-align: center"><img src="https://yqfile.alicdn.com/70cb1439a654cc7dc877ad398b9c98f72bbd3bb2.png" width="" height=""> 相关资源:《嵌入式Linux应用程序开发标准教程》(第2版全)[高清版]附源码.rar
    最新回复(0)