ImageVerifierCode 换一换
格式:DOC , 页数:35 ,大小:220.50KB ,
资源ID:3142604      下载积分:12 金币
快捷注册下载
登录下载
邮箱/手机:
温馨提示:
快捷下载时,用户名和密码都是您填写的邮箱或者手机号,方便查询和重复下载(系统自动生成)。 如填写123,账号就是123,密码也是123。
特别说明:
请自助下载,系统不会自动发送文件的哦; 如果您已付费,想二次下载,请登录后访问:我的下载记录
支付方式: 支付宝    微信支付   
验证码:   换一换

开通VIP
 

温馨提示:由于个人手机设置不同,如果发现不能下载,请复制以下地址【https://www.zixin.com.cn/docdown/3142604.html】到电脑端继续下载(重复下载【60天内】不扣币)。

已注册用户请登录:
账号:
密码:
验证码:   换一换
  忘记密码?
三方登录: 微信登录   QQ登录  

开通VIP折扣优惠下载文档

            查看会员权益                  [ 下载后找不到文档?]

填表反馈(24小时):  下载求助     关注领币    退款申请

开具发票请登录PC端进行申请

   平台协调中心        【在线客服】        免费申请共赢上传

权利声明

1、咨信平台为文档C2C交易模式,即用户上传的文档直接被用户下载,收益归上传人(含作者)所有;本站仅是提供信息存储空间和展示预览,仅对用户上传内容的表现方式做保护处理,对上载内容不做任何修改或编辑。所展示的作品文档包括内容和图片全部来源于网络用户和作者上传投稿,我们不确定上传用户享有完全著作权,根据《信息网络传播权保护条例》,如果侵犯了您的版权、权益或隐私,请联系我们,核实后会尽快下架及时删除,并可随时和客服了解处理情况,尊重保护知识产权我们共同努力。
2、文档的总页数、文档格式和文档大小以系统显示为准(内容中显示的页数不一定正确),网站客服只以系统显示的页数、文件格式、文档大小作为仲裁依据,个别因单元格分列造成显示页码不一将协商解决,平台无法对文档的真实性、完整性、权威性、准确性、专业性及其观点立场做任何保证或承诺,下载前须认真查看,确认无误后再购买,务必慎重购买;若有违法违纪将进行移交司法处理,若涉侵权平台将进行基本处罚并下架。
3、本站所有内容均由用户上传,付费前请自行鉴别,如您付费,意味着您已接受本站规则且自行承担风险,本站不进行额外附加服务,虚拟产品一经售出概不退款(未进行购买下载可退充值款),文档一经付费(服务费)、不意味着购买了该文档的版权,仅供个人/单位学习、研究之用,不得用于商业用途,未经授权,严禁复制、发行、汇编、翻译或者网络传播等,侵权必究。
4、如你看到网页展示的文档有www.zixin.com.cn水印,是因预览和防盗链等技术需要对页面进行转换压缩成图而已,我们并不对上传的文档进行任何编辑或修改,文档下载后都不会有水印标识(原文档上传前个别存留的除外),下载后原文更清晰;试题试卷类文档,如果标题没有明确说明有答案则都视为没有答案,请知晓;PPT和DOC文档可被视为“模板”,允许上传人保留章节、目录结构的情况下删减部份的内容;PDF文档不管是原文档转换或图片扫描而得,本站不作要求视为允许,下载前可先查看【教您几个在下载文档中可以更好的避免被坑】。
5、本文档所展示的图片、画像、字体、音乐的版权可能需版权方额外授权,请谨慎使用;网站提供的党政主题相关内容(国旗、国徽、党徽--等)目的在于配合国家政策宣传,仅限个人学习分享使用,禁止用于任何广告和商用目的。
6、文档遇到问题,请及时联系平台进行协调解决,联系【微信客服】、【QQ客服】,若有其他问题请点击或扫码反馈【服务填表】;文档侵犯商业秘密、侵犯著作权、侵犯人身权等,请点击“【版权申诉】”,意见反馈和侵权处理邮箱:1219186828@qq.com;也可以拔打客服电话:0574-28810668;投诉电话:18658249818。

注意事项

本文(GCC详解及makefile规则.doc)为本站上传会员【a199****6536】主动上传,咨信网仅是提供信息存储空间和展示预览,仅对用户上传内容的表现方式做保护处理,对上载内容不做任何修改或编辑。 若此文所含内容侵犯了您的版权或隐私,请立即通知咨信网(发送邮件至1219186828@qq.com、拔打电话4009-655-100或【 微信客服】、【 QQ客服】),核实后会尽快下架及时删除,并可随时和客服了解处理情况,尊重保护知识产权我们共同努力。
温馨提示:如果因为网速或其他原因下载失败请重新下载,重复下载【60天内】不扣币。 服务填表

GCC详解及makefile规则.doc

1、 GCC 编译详解 GNU CC(简称为Gcc)是GNU项目中符合ANSI C标准的编译系统,能够编译用C、C++和Object C等语言编写的程序。Gcc不仅功能强大,而且可以编译如C、C++、Object C、Java、Fortran、Pascal、Modula-3和Ada等多种语言,而且Gcc又是一个交叉平台编译器,它能够在当前CPU平台上为多种不同体系结构的硬件平台开发软件,因此尤其适合在嵌入式领域的开发编译。本章中的示例,除非特别注明,否则均采用Gcc版本为4.0.0。 GCC入门基础 表3.6 Gcc所支持后缀名解释 后 缀 名 所对应的语言 后 缀 名 所对应的语

2、言 .c C原始程序 .s/.S 汇编语言原始程序 .C/.cc/.cxx C++原始程序 .h 预处理文件(头文件) .m Objective-C原始程序 .o 目标文件 .i 已经过预处理的C原始程序 .a/.so 编译后的库文件 .ii 已经过预处理的C++原始程序 如本章开头提到的,Gcc的编译流程分为了四个步骤,分别为: · 预处理(Pre-Processing) · 编译(Compiling) · 汇编(Assembling) · 链接(Linking) 下面就具体来查看一下Gcc是如何完成四个步骤的。 首先,有以下hell

3、o.c源代码 #include int main() { printf("Hello! This is our embedded world!n"); return 0; } (1)预处理阶段 在该阶段,编译器将上述代码中的stdio.h编译进来,并且用户可以使用Gcc的选项”-E”进行查看,该选项的作用是让Gcc在预处理结束后停止编译过程。 注意 Gcc指令的一般格式为:Gcc [选项] 要编译的文件 [选项] [目标文件] 其中,目标文件可缺省,Gcc默认生成可执行的文件,命为:编译文件.out [root@localhost Gcc]# Gc

4、c –E hello.c –o hello.i 在此处,选项”-o”是指目标文件,由表3.6可知,”.i”文件为已经过预处理的C原始程序。以下列出了hello.i文件的部分内容: typedef int (*__gconv_trans_fct) (struct __gconv_step *, struct __gconv_step_data *, void *, __const unsigned char *, __const unsigned char **, __const unsigned char *, unsigned char **, size_t *); … #

5、 2 "hello.c" 2 int main() { printf("Hello! This is our embedded world!n"); return 0; } 由此可见,Gcc确实进行了预处理,它把”stdio.h”的内容插入到hello.i文件中。 (2)编译阶段 接下来进行的是编译阶段,在这个阶段中,Gcc首先要检查代码的规范性、是否有语法错误等,以确定代码的实际要做的工作,在检查无误后,Gcc把代码翻译成汇编语言。用户可以使用”-S”选项来进行查看,该选项只进行编译而不进行汇编,生成汇编代码。 [root@localhost Gcc]# Gcc –S he

6、llo.i –o hello.s 以下列出了hello.s的内容,可见Gcc已经将其转化为汇编了,感兴趣的读者可以分析一下这一行简单的C语言小程序是如何用汇编代码实现的。 .file "hello.c" .section .rodata .align 4 .LC0: .string"Hello! This is our embedded world!" .text .globl main .type main, @function main: pushl �p movl %esp, �p subl $8, %esp andl $-16, %esp movl $0,

7、 �x addl $15, �x addl $15, �x shrl $4, �x sall $4, �x subl �x, %esp subl $12, %esp pushl $.LC0 call puts addl $16, %esp movl $0, �x leave ret .size main, .-main .ident "GCC: (GNU) 4.0.0 20050519 (Red Hat 4.0.0-8)" .section .note.GNU-stack,"",@progbits (3)汇编阶段 汇编阶段是把编译阶段生成的”.s”文件转成目标

8、文件,读者在此可使用选项”-c”就可看到汇编代码已转化为”.o”的二进制目标代码了。如下所示: [root@localhost Gcc]# Gcc –c hello.s –o hello.o (4)链接阶段 在成功编译之后,就进入了链接阶段。在这里涉及到一个重要的概念:函数库。 读者可以重新查看这个小程序,在这个程序中并没有定义”printf”的函数实现,且在预编译中包含进的”stdio.h”中也只有该函数的声明,而没有定义函数的实现,那么,是在哪里实现”printf”函数的呢?最后的答案是:系统把这些函数实现都被做到名为libc.so.6的库文件中去了,在没有特别指定时,Gcc会到系

9、统默认的搜索路径”/usr/lib”下进行查找,也就是链接到libc.so.6库函数中去,这样就能实现函数”printf”了,而这也就是链接的作用。 函数库一般分为静态库和动态库两种。静态库是指编译链接时,把库文件的代码全部加入到可执行文件中,因此生成的文件比较大,但在运行时也就不再需要库文件了。其后缀名一般为”.a”。动态库与之相反,在编译链接时并没有把库文件的代码加入到可执行文件中,而是在程序执行时由运行时链接文件加载库,这样可以节省系统的开销。动态库一般后缀名为”.so”,如前面所述的libc.so.6就是动态库。Gcc在编译时默认使用动态库。 完成了链接之后,Gcc就可以生成可执行

10、文件,如下所示。 [root@localhost Gcc]# Gcc hello.o –o hello 运行该可执行文件,出现正确的结果如下。 [root@localhost Gcc]# ./hello Hello! This is our embedded world! Gcc编译选项分析 Gcc有超过100个的可用选项,主要包括总体选项、告警和出错选项、优化选项和体系结构相关选项。以下对每一类中最常用的选项进行讲解。 (1)总体选项 Gcc的总结选项如表3.7所示,很多在前面的示例中已经有所涉及。 表3.7 Gcc总体选项列表 后缀名 所对应的语言 -c 只是编译

11、不链接,生成目标文件“.o” -S 只是编译不汇编,生成汇编代码 -E 只进行预编译,不做其他处理 -g 在可执行程序中包含标准调试信息 -o file 把输出文件输出到file里 -v 打印出编译器内部编译各过程的命令行信息和编译器的版本 -I dir 在头文件的搜索路径列表中添加dir目录 -L dir 在库文件的搜索路径列表中添加dir目录 -static 链接静态库 -llibrary 连接名为library的库文件 对于“-c”、“-E”、“-o”、“-S”选项在前一小节中已经讲解了其使用方法,在此主要讲解另外两个非常常用的库依赖选项“-I di

12、r”和“-L dir”。 · “-I dir” 正如上表中所述,“-I dir”选项可以在头文件的搜索路径列表中添加dir目录。由于Linux中头文件都默认放到了“/usr/include/”目录下,因此,当用户希望添加放置在其他位置的头文件时,就可以通过“-I dir”选项来指定,这样,Gcc就会到相应的位置查找对应的目录。 比如在“/root/workplace/Gcc”下有两个文件: #include int main() { printf(“Hello!!n”); return 0; } #include 这样,就可在Gcc命令行中加

13、入“-I”选项: [root@localhost Gcc] Gcc hello1.c –I /root/workplace/Gcc/ -o hello1 这样,Gcc就能够执行出正确结果。 小知识 在include语句中,“<>”表示在标准路径中搜索头文件,““””表示在本目录中搜索。故在上例中,可把hello1.c的“#include”改为“#include “my.h””,就不需要加上“-I”选项了。 · “-L dir” 选项“-L dir”的功能与“-I dir”类似,能够在库文件的搜索路径列表中添加dir目录。例如有程序hello_sq.c需要用到目录“/ro

14、ot/workplace/Gcc/lib”下的一个动态库libsunq.so,则只需键入如下命令即可: [root@localhost Gcc] Gcc hello_sq.c –L /root/workplace/Gcc/lib –lsunq –o hello_sq 需要注意的是,“-I dir”和“-L dir”都只是指定了路径,而没有指定文件,因此不能在路径中包含文件名。 另外值得详细解释一下的是“-l”选项,它指示Gcc去连接库文件libsunq.so。由于在Linux下的库文件命名时有一个规定:必须以lib三个字母开头。因此在用-l选项指定链接的库文件名时可以省去lib三个字母。

15、也就是说Gcc在对”-lsunq”进行处理时,会自动去链接名为libsunq.so的文件。 (2)告警和出错选项 Gcc的告警和出错选项如表3.8所示。 表3.8 Gcc总体选项列表 选项 含义 -ansi 支持符合ANSI标准的C程序 -pedantic 允许发出ANSI C标准所列的全部警告信息 选项 含义 -pedantic-error 允许发出ANSI C标准所列的全部错误信息 -w 关闭所有告警 -Wall 允许发出Gcc提供的所有有用的报警信息 -werror 把所有的告警信息转化为错误信息,并在告警发生时终止编译过程 下面结合实例对这几个告

16、警和出错选项进行简单的讲解。 如有以下程序段: #include void main() { long long tmp = 1; printf(“This is a bad code!n”); return 0; } 这是一个很糟糕的程序,读者可以考虑一下有哪些问题? · “-ansi” 该选项强制Gcc生成标准语法所要求的告警信息,尽管这还并不能保证所有没有警告的程序都是符合ANSI C标准的。运行结果如下所示: [root@localhost Gcc]# Gcc –ansi warning.c –o warning warning.c: 在函数

17、main”中: warning.c:7 警告:在无返回值的函数中,“return”带返回值 warning.c:4 警告:“main”的返回类型不是“int” 可以看出,该选项并没有发现”long long”这个无效数据类型的错误。 · “-pedantic” 允许发出ANSI C标准所列的全部警告信息,同样也保证所有没有警告的程序都是符合ANSI C标准的。其运行结果如下所示: [root@localhost Gcc]# Gcc –pedantic warning.c –o warning warning.c: 在函数“main”中: warning.c:5 警告:ISO

18、C90不支持“long long” warning.c:7 警告:在无返回值的函数中,“return”带返回值 warning.c:4 警告:“main”的返回类型不是“int” 可以看出,使用该选项查看出了”long long”这个无效数据类型的错误。 · “-Wall” 允许发出Gcc能够提供的所有有用的报警信息。该选项的运行结果如下所示: [root@localhost Gcc]# Gcc –Wall warning.c –o warning warning.c:4 警告:“main”的返回类型不是“int” warning.c: 在函数”main”中: warning

19、c:7 警告:在无返回值的函数中,”return”带返回值 warning.c:5 警告:未使用的变量“tmp” 使用“-Wall”选项找出了未使用的变量tmp,但它并没有找出无效数据类型的错误。 另外,Gcc还可以利用选项对单独的常见错误分别指定警告,有关具体选项的含义感兴趣的读者可以查看Gcc手册进行学习。 (3)优化选项 Gcc可以对代码进行优化,它通过编译选项“-On”来控制优化代码的生成,其中n是一个代表优化级别的整数。对于不同版本的Gcc来讲,n的取值范围及其对应的优化效果可能并不完全相同,比较典型的范围是从0变化到2或3。 不同的优化级别对应不同的优化处理工作。如使

20、用优化选项“-O”主要进行线程跳转(Thread Jump)和延迟退栈(Deferred Stack Pops)两种优化。使用优化选项“-O2”除了完成所有“-O1”级别的优化之外,同时还要进行一些额外的调整工作,如处理器指令调度等。选项“-O3”则还包括循环展开和其他一些与处理器特性相关的优化工作。 虽然优化选项可以加速代码的运行速度,但对于调试而言将是一个很大的挑战。因为代码在经过优化之后,原先在源程序中声明和使用的变量很可能不再使用,控制流也可能会突然跳转到意外的地方,循环语句也有可能因为循环展开而变得到处都有,所有这些对调试来讲都将是一场噩梦。所以笔者建议在调试的时候最好不使用任何优

21、化选项,只有当程序在最终发行的时候才考虑对其进行优化。 (4)体系结构相关选项 Gcc的体系结构相关选项如表3.9所示。 表3.9Gcc体系结构相关选项列表 选项 含义 -mcpu=type 针对不同的CPU使用相应的CPU指令。可选择的type有i386、i486、pentium及i686等 -mieee-fp 使用IEEE标准进行浮点数的比较 -mno-ieee-fp 不使用IEEE标准进行浮点数的比较 -msoft-float 输出包含浮点库调用的目标代码 -mshort 把int类型作为16位处理,相当于short int -mrtd 强行将函数参数个

22、数固定的函数用ret NUM返回,节省调用函数的一条指令 这些体系结构相关选项在嵌入式的设计中会有较多的应用,读者需根据不同体系结构将对应的选项进行组合处理。在本书后面涉及到具体实例会有针对性的讲解。 Gdb调试器 调试是所有程序员都会面临的问题。如何提高程序员的调试效率,更好更快地定位程序中的问题从而加快程序开发的进度,是大家共同面对的。就如读者熟知的Windows下的一些调试工具,如VC自带的如设置断点、单步跟踪等,都受到了广大用户的赞赏。那么,在Linux下有什么很好的调试工具呢? 本文所介绍的Gdb调试器是一款GNU开发组织并发布的UNIX/Linux下的程序调试工具。虽然,它

23、没有图形化的友好界面,但是它强大的功能也足以与微软的VC工具等媲美。下面就请跟随笔者一步步学习Gdb调试器。 Gdb使用流程 首先,笔者给出了一个短小的程序,由此带领读者熟悉一下Gdb的使用流程。强烈建议读者能够实际动手操作。 首先,打开Linux下的编辑器Vi或者Emacs,编辑如下代码。(由于为了更好地熟悉Gdb的操作,笔者在此使用Vi编辑,希望读者能够参见3.3节中对Vi的介绍,并熟练使用Vi)。 #include int sum(int m); int main() { int i,n=0; sum(50); for(i=1; i<=50; i+

24、) { n += i; } printf("The sum of 1-50 is %d n", n ); } int sum(int m) { int i,n=0; for(i=1; i<=m;i++) n += i; printf("The sum of 1-m is %dn", n); } 在保存退出后首先使用Gcc对test.c进行编译,注意一定要加上选项”-g”,这样编译出的可执行代码中才包含调试信息,否则之后Gdb无法载入该可执行文件。 [root@localhost Gdb]# gcc -g test.c -o test 虽然这段程序没有错误,但调试

25、完全正确的程序可以更加了解Gdb的使用流程。接下来就启动Gdb进行调试。注意,Gdb进行调试的是可执行文件,而不是如”.c”的源代码,因此,需要先通过Gcc编译生成可执行文件才能用Gdb进行调试。 [root@localhost Gdb]# gdb test GNU 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 are wel

26、come 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.

27、so.1". (gdb) 可以看出,在Gdb的启动画面中指出了Gdb的版本号、使用的库文件等信息,接下来就进入了由“(gdb)”开头的命令行界面了。 (1)查看文件 在Gdb中键入”l”(list)就可以查看所载入的文件,如下所示: 注意 在Gdb的命令中都可使用缩略形式的命令,如“l”代便“list”,“b”代表“breakpoint”,“p”代表“print”等,读者也可使用“help”命令查看帮助信息。 (Gdb) l 1 #include 2 int sum(int m); 3 int main() 4 { 5 int i,n=0; 6

28、 sum(50); 7 for(i=1; i<=50; i++) 8 { 9 n += i; 10 } (Gdb) l 11 printf("The sum of 1~50 is %d n", n ); 12 13 } 14 int sum(int m) 15 { 16 int i,n=0; 17 for(i=1; i<=m;i++) 18 n += i; 19 printf("The sum of 1~m is = %dn", n); 20 } 可以看出,Gdb列出的源代码中明确地给出了对应的行号,这样就可以大大地方便代码的定位。 (2)设置断点 设置断点

29、是调试程序中是一个非常重要的手段,它可以使程序到一定位置暂停它的运行。因此,程序员在该位置处可以方便地查看变量的值、堆栈情况等,从而找出代码的症结所在。 在Gdb中设置断点非常简单,只需在”b”后加入对应的行号即可(这是最常用的方式,另外还有其他方式设置断点)。如下所示: (Gdb) b 6 Breakpoint 1 at 0x804846d: file test.c, line 6. 要注意的是,在Gdb中利用行号设置断点是指代码运行到对应行之前将其停止,如上例中,代码运行到第五行之前暂停(并没有运行第五行)。 (3)查看断点情况 在设置完断点之后,用户可以键入”info b”来

30、查看设置断点情况,在Gdb中可以设置多个断点。 (Gdb) info b Num Type Disp Enb Address What 1 breakpoint keep y 0x0804846d in main at test.c:6 (4)运行代码 接下来就可运行代码了,Gdb默认从首行开始运行代码,可键入”r”(run)即可(若想从程序中指定行开始运行,可在r后面加上行号)。 (Gdb) r Starting program: /root/workplace/Gdb/test Reading symbols from shared object read from tar

31、get memory...done. Loaded system supplied DSO at 0x5fb000 Breakpoint 1, main () at test.c:6 6 sum(50); 可以看到,程序运行到断点处就停止了。 (5)查看变量值 在程序停止运行之后,程序员所要做的工作是查看断点处的相关变量值。在Gdb中只需键入”p”+变量值即可,如下所示: (Gdb) p n $1 = 0 (Gdb) p i $2 = 134518440 在此处,为什么变量”i”的值为如此奇怪的一个数字呢?原因就在于程序是在断点设置的对应行之前停止的,那么在此时,并没有把

32、i”的数值赋为零,而只是一个随机的数字。但变量”n”是在第四行赋值的,故在此时已经为零。 小技巧 Gdb在显示变量值时都会在对应值之前加上”$N”标记,它是当前变量值的引用标记,所以以后若想再次引用此变量就可以直接写作”$N”,而无需写冗长的变量名。 (6)单步运行 单步运行可以使用命令”n”(next)或”s”(step),它们之间的区别在于:若有函数调用的时候,”s”会进入该函数而”n”不会进入该函数。因此,”s”就类似于VC等工具中的”step in”,”n”类似与VC等工具中的”step over”。它们的使用如下所示: (Gdb) n The sum of 1-m is

33、 1275 7 for(i=1; i<=50; i++) (Gdb) s sum (m=50) at test.c:16 16 int i,n=0; 可见,使用”n”后,程序显示函数sum的运行结果并向下执行,而使用”s”后则进入到sum函数之中单步运行。 (7)恢复程序运行 在查看完所需变量及堆栈情况后,就可以使用命令”c”(continue)恢复程序的正常运行了。这时,它会把剩余还未执行的程序执行完,并显示剩余程序中的执行结果。以下是之前使用”n”命令恢复后的执行结果: (Gdb) c Continuing. The sum of 1-50 is :1275 Prog

34、ram exited with code 031. 可以看出,程序在运行完后退出,之后程序处于“停止状态”。 小知识 在Gdb中,程序的运行状态有“运行”、“暂停”和“停止”三种,其中“暂停”状态为程序遇到了断点或观察点之类的,程序暂时停止运行,而此时函数的地址、函数参数、函数内的局部变量都会被压入“栈”(Stack)中。故在这种状态下可以查看函数的变量值等各种属性。但在函数处于“停止”状态之后,“栈”就会自动撤销,它也就无法查看各种信息了。 Gdb基本命令 Gdb的命令可以通过查看help进行查找,由于Gdb的命令很多,因此Gdb的help将其分成了很多种类(class),用户可以

35、通过进一步查看相关class找到相应命令。如下所示: (gdb) help List of classes of commands: aliases -- Aliases of other commands breakpoints -- Making program stop at certain points data -- Examining data files -- Specifying and examining files internals -- Maintenance commands … Type "help" followed by a class nam

36、e for a list of commands in that class. Type "help" followed by command name for full documentation. Command name abbreViations are allowed if unambiguous. 上述列出了Gdb各个分类的命令,注意底部的加粗部分说明其为分类命令。接下来可以具体查找各分类种的命令。如下所示: (gdb) help data Examining data. List of commands: call -- Call a function in the

37、 program delete display -- Cancel some expressions to be displayed when program stops delete mem -- Delete memory region disable display -- Disable some expressions to be displayed when program stops … Type "help" followed by command name for full documentation. Command name abbreViations are

38、allowed if unambiguous. 至此,若用户想要查找call命令,就可键入“help call”。 (gdb) help call Call a function in the program. The argument is the function name and arguments, in the notation of the current working language. The result is printed and saved in the value history, if it is not void. 当然,若用户已知命令名,直接键入

39、help [command]”也是可以的。 Gdb中的命令主要分为以下几类:工作环境相关命令、设置断点与恢复命令、源代码查看命令、查看运行数据相关命令及修改运行参数命令。以下就分别对这几类的命令进行讲解。 1.工作环境相关命令 Gdb中不仅可以调试所运行的程序,而且还可以对程序相关的工作环境进行相应的设定,甚至还可以使用shell中的命令进行相关的操作,其功能极其强大。表3.10所示列出了Gdb常见工作环境相关命令。 表3.10 Gdb工作环境相关命令 命 令 格 式 含义 set args运行时的参数 指定运行时参数,如:set args 2 show args 查看设

40、置好的运行参数 path dir 设定程序的运行路径 show paths 查看程序的运行路径 set enVironment var [=value] 设置环境变量 show enVironment [var] 查看环境变量 cd dir 进入到dir目录,相当于shell中的cd命令 pwd 显示当前工作目录 shell command 运行shell的command命令 2.设置断点与恢复命令 Gdb中设置断点与恢复的常见命令如表3.11所示。 表3.11 Gdb设置断点与恢复相关命令 命 令 格 式 含义 bnfo b 查看所设断点 brea

41、k 行号或函数名 <条件表达式> 设置断点 tbreak 行号或函数名 <条件表达式> 设置临时断点,到达后被自动删除 delete [断点号] 删除指定断点,其断点号为”info b”中的第一栏。若缺省断点号则删除所有断点 disable [断点号]] 停止指定断点,使用”info b”仍能查看此断点。同delete一样,省断点号则停止所有断点 enable [断点号] 激活指定断点,即激活被disable停止的断点 condition [断点号] <条件表达式> 修改对应断点的条件 ignore [断点号] 在程序执行中,忽略对应断点num次 step

42、 单步恢复程序运行,且进入函数调用 next 单步恢复程序运行,但不进入函数调用 finish 运行程序,直到当前函数完成返回 c 继续执行函数,直到函数结束或遇到新的断点 由于设置断点在Gdb的调试中非常重要,所以在此再着重讲解一下Gdb中设置断点的方法。 Gdb中设置断点有多种方式:其一是按行设置断点,设置方法在3.5.1节已经指出,在此就不重复了。另外还可以设置函数断点和条件断点,在此结合上一小节的代码,具体介绍后两种设置断点的方法。 ① 函数断点 Gdb中按函数设置断点只需把函数名列在命令”b”之后,如下所示: (gdb) b sum Breakpoint 1

43、 at 0x80484ba: file test.c, line 16. (gdb) info b Num Type Disp Enb Address What 1 breakpoint keep y 0x080484ba in sum at test.c:16 要注意的是,此时的断点实际是在函数的定义处,也就是在16行处(注意第16行还未执行)。 ② 条件断点 Gdb中设置条件断点的格式为:b 行数或函数名 if 表达式。具体实例如下所示: (gdb) b 8 if i==10 Breakpoint 1 at 0x804848c: file test.c, line 8.

44、gdb) info b Num Type Disp Enb Address What 1 breakpoint keep y 0x0804848c in main at test.c:8 stop only if i == 10 (gdb) r Starting program: /home/yul/test The sum of 1-m is 1275 Breakpoint 1, main () at test.c:9 9 n += i; (gdb) p i $1 = 10 可以看到,该例中在第8行(也就是运行完第7行的for循环)设置了一个“i==0”的条件断点,在

45、程序运行之后可以看出,程序确实在i为10时暂停运行。 3.Gdb中源码查看相关命令 在Gdb中可以查看源码以方便其他操作,它的常见相关命令如表3.12所示: 表3.12 Gdb源码查看相关相关命令 命 令 格 式 含义 list <行号>|<函数名> 查看指定位置代码 file [文件名] 加载指定文件 forward-search 正则表达式 源代码前向搜索 reverse-search 正则表达式 源代码后向搜索 dir dir 停止路径名 show directories 显示定义了的源文件搜索路径 info line 显示加载到Gdb内存中的代码

46、 4.Gdb中查看运行数据相关命令 Gdb中查看运行数据是指当程序处于“运行”或“暂停”状态时,可以查看的变量及表达式的信息,其常见命令如表3.13所示: 表3.13 Gdb查看运行数据相关命令 命 令 格 式 含义 print 表达式|变量 查看程序运行时对应表达式和变量的值 x 查看内存变量内容。其中n为整数表示显示内存的长度,f表示显示的格式,u表示从当前地址往后请求显示的字节数 display 表达式 设定在单步运行或其他情况中,自动显示的对应表达式的内容 5.Gdb中修改运行参数相关命令 Gdb还可以修改运行时的参数,并使该变量按照用户当前输入

47、的值继续运行。它的设置方法为:在单步执行的过程中,键入命令“set 变量=设定值”。这样,在此之后,程序就会按照该设定的值运行了。下面,笔者结合上一节的代码将n的初始值设为4,其代码如下所示: (Gdb) b 7 Breakpoint 5 at 0x804847a: file test.c, line 7. (Gdb) r Starting program: /home/yul/test The sum of 1-m is 1275 Breakpoint 5, main () at test.c:7 7 for(i=1; i<=50; i++) (Gdb) set n=4 (

48、Gdb) c Continuing. The sum of 1-50 is 1279 Program exited with code 031. 可以看到,最后的运行结果确实比之前的值大了4。 Gdb的使用切记点: · 在Gcc编译选项中一定要加入”-g”。 · 只有在代码处于“运行”或“暂停”状态时才能查看变量值。 · 设置断点后程序在指定行之前停止。 Make工程管理器 到此为止,读者已经了解了如何在Linux下使用编辑器编写代码,如何使用Gcc把代码编译成可执行文件,还学习了如何使用Gdb来调试程序,那么,所有的工作看似已经完成了,为什么还需要Make这个工程管理

49、器呢? 所谓工程管理器,顾名思义,是指管理较多的文件的。读者可以试想一下,有一个上百个文件的代码构成的项目,如果其中只有一个或少数几个文件进行了修改,按照之前所学的Gcc编译工具,就不得不把这所有的文件重新编译一遍,因为编译器并不知道哪些文件是最近更新的,而只知道需要包含这些文件才能把源代码编译成可执行文件,于是,程序员就不能不再重新输入数目如此庞大的文件名以完成最后的编译工作。 但是,请读者仔细回想一下本书在3.1.2节中所阐述的编译过程,编译过程是分为编译、汇编、链接不同阶段的,其中编译阶段仅检查语法错误以及函数与变量的声明是否正确声明了,在链接阶段则主要完成是函数链接和全局变量的链接

50、因此,那些没有改动的源代码根本不需要重新编译,而只要把它们重新链接进去就可以了。所以,人们就希望有一个工程管理器能够自动识别更新了的文件代码,同时又不需要重复输入冗长的命令行,这样,Make工程管理器也就应运而生了。 实际上,Make工程管理器也就是个“自动编译管理器”,这里的“自动”是指它能够根据文件时间戳自动发现更新过的文件而减少编译的工作量,同时,它通过读入Makefile文件的内容来执行大量的编译工作。用户只需编写一次简单的编译语句就可以了。它大大提高了实际项目的工作效率,而且几乎所有Linux下的项目编程均会涉及到它,希望读者能够认真学习本节内容。 Makefile基本结构

移动网页_全站_页脚广告1

关于我们      便捷服务       自信AI       AI导航        抽奖活动

©2010-2025 宁波自信网络信息技术有限公司  版权所有

客服电话:0574-28810668  投诉电话:18658249818

gongan.png浙公网安备33021202000488号   

icp.png浙ICP备2021020529号-1  |  浙B2-20240490  

关注我们 :微信公众号    抖音    微博    LOFTER 

客服