范文健康探索娱乐情感热点
投稿投诉
热点动态
科技财经
情感日志
励志美文
娱乐时尚
游戏搞笑
探索旅游
历史星座
健康养生
美丽育儿
范文作文
教案论文

GDB调试的高级技巧

  GDB是我们平时调试c/c++程序的利器, 查起复杂的bug问题,比打印大法要好得多,但是也不得不说, gdb在默认情况下用起来并不是很好用,最近学习到几个高级点的技巧,分享下: 一 美化打印
  先上个例子: #include   typedef struct {  int i ;  int j;  char * str;  int array[10]; } test_type_t;  int main (int argc, char * argv[]) {   test_type_t t = {1,2,"test a str" ,{1,2,3,4,5,6,7,8,9,10}};   printf("i:%d,j:%d ", t.i,t.j);   return 0; }
  gdb调试: (gdb) n 14   printf("i:%d,j:%d ", t.i,t.j); (gdb) p t $1 = {i = 1, j = 2, str = 0x400710 "test a str", array = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10}} (gdb) set print pretty (gdb) p t $2 = {   i = 1,    j = 2,    str = 0x400710 "test a str",    array = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10} } (gdb)
  set print pretty  通过这个命令可以美化gdb的打印,特别是复杂的数据结构,比较推荐.  set print array-indexes on  打印数组的下标
  这些命令如果记不住怎么办, 类似linux启动,会执行些初始化脚本,gdb也一样,脚本名为:  .gdbinit 将刚才的两个命令加入进去,就不用每次执行这个命令调试.二 动态打印
  一般情况下,我们用gdb调试的时候,先在产生问题的代码的调用逻辑链上设置端点,调试,有时候为了更方便调试,我们会在这些关键地方加上打印语句. 有时候加的打印代码不够全,来回要反复几次. 每次加好打印代码后,需要编译程序,来回折腾几次,确实比较麻烦.
  GDB提供动态打印功能,可以在不修改代码情况下,动态插入打印语句,说的比较抽象,举例说明:   2 #include    3    4 typedef struct {   5  int i ;   6  int j;   7  char * str;   8  int array[10];   9 } test_type_t;  10   11 int main (int argc, char * argv[])  12 {  13   test_type_t t = {1,2,"test a str" ,{1,2,3,4,5,6,7,8,9,10}};  14   printf("i:%d,j:%d ", t.i,t.j);  15   16   for (int k = 0; k <= 10; k++ ) {  17       t.array[k] += 10;  18   }  19   printf("index 0 :%d" ,t.array[0]);  20   return 0;  21 }
  上面位置 k <= 10;  这一行越界,调试下:(gdb) dprintf 17,"k:%d,array[k]:%d ",k,t.array[k] Dprintf 2 at 0x40067f: file 1.c, line 17. (gdb) r Starting program: /test/a.out   Breakpoint 1, main (argc=1, argv=0x7fffffffe648) at 1.c:13 13   test_type_t t = {1,2,"test a str" ,{1,2,3,4,5,6,7,8,9,10}}; Missing separate debuginfos, use: debuginfo-install glibc-2.17-196.el7_4.2.x86_64 libgcc-4.8.5-16.el7_4.2.x86_64 libstdc++-4.8.5-16.el7_4.2.x86_64 (gdb) c Continuing. i:1,j:2 k:0,array[k]:1 k:1,array[k]:2 k:2,array[k]:3 k:3,array[k]:4 k:4,array[k]:5 k:5,array[k]:6 k:6,array[k]:7 k:7,array[k]:8 k:8,array[k]:9 k:9,array[k]:10 k:10,array[k]:0 index 0 :11[Inferior 1 (process 150109) exited normally] (gdb) info b Num     Type           Disp Enb Address            What 1       breakpoint     keep y   0x00000000004005fc in main(int, char**) at 1.c:13  breakpoint already hit 1 time 2       dprintf        keep y   0x000000000040067f in main(int, char**) at 1.c:17  breakpoint already hit 11 times         printf "k:%d,array[k]:%d ",k,t.array[k]
  我们通过 dprintf 17,"k:%d,array[k]:%d ",k,t.array[k]  在17行动态插入打印语句,然后执行的时候会直接打印出来,17 为行号,后面的语法类似printf.
  动态的语句实际是一个断点(通过info b 可以看到),只不过这个断点会自动的恢复,这种动态语句是否可以继续在上面设置端点的,答案是不行的,通过next执行的时候也执行不到这个语句,只是运行到这里面的时候,可以自动打印变量. 三 断点信息的保存和加载
  调试大型程序的时候,往往会设置很多断点,如果需要多次调试,来回敲这些断点信息,也是很烦的,可以通过 save breakpoints filename 的方法,将断点设置信息保存到filename 文件中,GDB启动后,在通过source filename 方式加载:(gdb) save breakpoints break.bp Saved to file "break.bp". (gdb) quit [root@localhost test]# ls 1.c  a.out  break.bp [root@localhost test]# cat break.bp  break main dprintf  /test/1.c:17,"k:%d,array[k]:%d ",k,t.array[k]
  加载: [root@localhost test]# gdb ./a.out  Reading symbols from /test/a.out...done. (gdb) source break.bp Breakpoint 1 at 0x4005fc: file 1.c, line 13. Dprintf 2 at 0x40067f: file 1.c, line 17. (gdb) info b Num     Type           Disp Enb Address            What 1       breakpoint     keep y   0x00000000004005fc in main(int, char**) at 1.c:13 2       dprintf        keep y   0x000000000040067f in main(int, char**) at 1.c:17         printf "k:%d,array[k]:%d ",k,t.array[k]
  是不是很方便那. 四 宏打印
  如下示例代码:  1 #include    2    3 #define MAX(x,y) (x)>=(y)?(x):(y)   4    5 int main(int argc , char * argv[])   6 {   7     char * p = (char*)0x12345;   8     printf("max(3,5):%d ",MAX(3,5));   9     printf("print a test str ");  10     *p = 1;  11     printf("end ");  12 }
  如果通过 -g 选项编译是无法查看宏定义的,可以通过-g3  编译,就可以轻松查看宏定义和宏展开了,如下:[root@localhost test]# gdb ./2 Reading symbols from /test/2...done. (gdb) b main Breakpoint 1 at 0x40064c: file 2.c, line 7. (gdb) r Starting program: /test/./2   Breakpoint 1, main (argc=1, argv=0x7fffffffe648) at 2.c:7 7     char * p = (char*)0x12345; Missing separate debuginfos, use: debuginfo-install glibc-2.17-196.el7_4.2.x86_64 libgcc-4.8.5-16.el7_4.2.x86_64 libstdc++-4.8.5-16.el7_4.2.x86_64 (gdb) n 8     printf("max(3,5):%d ",MAX(3,5)); (gdb) p MAX(3,5) $1 = 5 (gdb) macro expand MAX(3,5) expands to: (3)>=(5)?(3):(5)
  可以直接通过p命令打印宏,也可以进行 macro expand MAX(3,5) 宏展开,调试宏的时候比较有用.五 gdb调试界面
  gdb的调试一般是通过n执行下一条命令,然后通过l查看当前的代码,不够直观,gdb其实也可以类似IDE那样,显示一行行代码执行,简单的直接输入 layout  切换布局:
  再输入n的时候,箭头自动下移一行.
  更棒的是可以同时显示源码和汇编,输入 layout split
  六 Debug汇编
  有时候,比较麻烦的bug,可以需要反编译为汇编(disassemble /m main),然后调试, 还是如上的例子程序,调试如下,汇编模式常需要看寄存器的值,输入 layout regs 可以同时展示汇编和寄存器的值:
  这个模式下好处,可以通过n命令执行一条条看汇编指令.
  我还是更喜欢用以下的方式调试: gdb) disassemble /m main Dump of assembler code for function main(int, char**): 6 {    0x000000000040063d <+0>: push   %rbp    0x000000000040063e <+1>: mov    %rsp,%rbp    0x0000000000400641 <+4>: sub    $0x20,%rsp    0x0000000000400645 <+8>: mov    %edi,-0x14(%rbp)    0x0000000000400648 <+11>: mov    %rsi,-0x20(%rbp)  7     char * p = (char*)0x12345; => 0x000000000040064c <+15>: movq   $0x12345,-0x8(%rbp)  8     printf("max(3,5):%d ",MAX(3,5));    0x0000000000400654 <+23>: mov    $0x5,%esi    0x0000000000400659 <+28>: mov    $0x400720,%edi    0x000000000040065e <+33>: mov    $0x0,%eax    0x0000000000400663 <+38>: callq  0x400510   9     printf("print a test str ");    0x0000000000400668 <+43>: mov    $0x40072d,%edi    0x000000000040066d <+48>: callq  0x400530   10     *p = 1;    0x0000000000400672 <+53>: mov    -0x8(%rbp),%rax    0x0000000000400676 <+57>: movb   $0x1,(%rax)  11     printf("end ");    0x0000000000400679 <+60>: mov    $0x40073e,%edi    0x000000000040067e <+65>: callq  0x400530   12 }    0x0000000000400683 <+70>: mov    $0x0,%eax    0x0000000000400688 <+75>: leaveq     0x0000000000400689 <+76>: retq     End of assembler dump. (gdb) ni 8     printf("max(3,5):%d ",MAX(3,5)); (gdb) ni 0x0000000000400659 8     printf("max(3,5):%d ",MAX(3,5)); (gdb) ni 0x000000000040065e 8     printf("max(3,5):%d ",MAX(3,5)); (gdb) ni 0x0000000000400663 8     printf("max(3,5):%d ",MAX(3,5)); (gdb) ni max(3,5):5 9     printf("print a test str "); (gdb) ni 0x000000000040066d 9     printf("print a test str "); (gdb) ni print a test str 10     *p = 1; (gdb) info register
  通过 disassemble /m main  将源码和汇编一起显示,ni  执行下一条汇编指令. info register 来显示汇编信息,core的位置的指令为: 0x0000000000400676 <+57>: movb $0x1,(%rax)  将1赋值给rax寄存器保存的地址, 我们可以看下rax寄存器,p $rax  直接打印,然后通过x /x 0x12345  来测试下这个地址是否合法,这个地址不是栈的地址,也不是我们申请的堆地址,直接写,就引起的段错误.七 诗词欣赏# 滚滚长江东逝水,浪花淘尽英雄。  出自明代[杨慎]   滚滚长江东逝水,浪花淘尽英雄。 是非成败转头空。青山依旧在,几度夕阳红。 白发渔樵江渚上,惯看秋月春风。 一壶浊酒喜相逢。古今多少事,都付笑谈中。

快看微信新春彩蛋来了推出拜年红包,领取可获得小老虎头像记者陆柯言每逢传统节日,微信都会适时推出一些彩蛋,春节更不例外。如果你有留意,会发现许多微信好友的昵称旁边多出了一只卡通老虎。这是微信为春节推出的功能拜年红包。将微信升级到最新版本快递公司未经用户允许擅放快递柜最高可罚3万元快递市场管理办法(修订草案)明确快递公司未经用户允许擅放快递柜最高可罚3万元本报讯(周有为)近日,交通运输部就快递市场管理办法(修订草案)(以下简称修订草案)公开征集意见。修订草案年前发福利了,iOS15。3正式版凌晨推送,轻度使用报告来了自从上周iOS15。3rc版发布之后,就一直开始期待15。3正式版的到来,从周二盼到了周四,好在苹果没让大家失望,iOS15。3正式版在凌晨推送。按照惯例,先来看看这个版本的更新内曾放话给大陆赏饭吃的郭台铭,迎2大对手,苹果也变心了提到富士康,相信很多人都很熟悉,因为有苹果撑腰,富士康也得到了快速成长,现在已经是国内最大的手机代工厂了。而郭台铭的性格本来就有些嚣张,在富士康取得了一定成绩后,就逐渐开始飘了,多网宿科技成功抵御2。09TbpsDDoS攻击鞭牛士1月27日消息,据报道,近日,网宿安全平台成功拦截了一次分布式拒绝服务(DDoS)攻击,该攻击带宽峰值高达2。09Tbps,创国内已知最大纪录。据网宿科技首席安全官吕士表透露高中线上学科培训课程集体下架,该如何参照执行双减?记者查沁君编辑高中学科培训将面临从严监管。据晚点财经1月26日报道,北京市教委本周已约谈猿辅导作业帮高途(NYSEGOTU)网易有道(NYSEDAO)等多家头部在线教育公司,要求后罗总和乐视网的故事大家书应该都收到了吧结合书的知识,年前唯一的干货来了讲下罗总当年重仓乐视网的故事超级大妖的捕捉故事,真实发生2012年9月,乐视推出颠覆性的产品,超级电视,罗总作为一个半导体设备行华为不懂合理避税?利润比阿里少787亿,纳税却是阿里的3。5倍为何很多中国的科技巨头,利润更多,反而纳税更少呢?2020年,阿里巴巴的净利润为1433亿元,华为的净利润为646亿元。不过,同期华为的纳税总额却达到1010亿元,是阿里的3。5倍从BOOXNote3到Lumi2,大屏的好处不止一点点本文转自贴吧用户柳絮池塘淡淡风对BOOXNoteX的评测,已征得作者授权发布。MaxLumi2是买的第二个文石出品的电纸书设备,其实在今年年初的时候刚买过一个Note3的机子,20没体验过冰雪运动?中国移动5G云游戏满足你!还有大奖可拿滑爬犁拉雪橇打雪仗泼水成冰,还有巨型雪人超级冰滑梯这个冬天,有网友感叹整个朋友圈都去玩雪了!2022冰雪盛会的临近,再度点燃了大家对于冰雪运动的热情,也让这个冬天的氛围感瞬间拉满。你的朋友圈小老虎领养了吗,原来微信还可以这么玩儿?今天,好多微信好友都发来截图炫耀,说是微信升级后,不但可以发个性红包封面,还可以领取一只小老虎!看着呆呆萌萌的小老虎头像,还真是怪可爱的!还在等什么?动手吧,你也领养一只小老虎,回
小米civi手机的销量,有没有超越你的想象?感谢您的阅读!我去体验店感受了一下这款手机。说句实话,我觉得这款手机的外观设计还是比较有特点的,而且它的整体的重量确实很轻,也改变了我对于小米的一些看法,在整款手机的研制设计上,小大项目成了烂尾楼?招商如何避免高科技项目陷阱科技创新是当前的热点话题,一些自带高科技光环的科技创新投资项目更成为各地竞相招引的香饽饽。然而,高处不胜寒,投资巨大科技成果转化周期长的高科技项目往往伴随着高风险。近期,一些地方也关于苹果手机和华为手机选择的立场问题我们不应当用政治的观点和立场来分析和作为市场经济对于商品的选择。我们老百姓就是支持质优价廉的商品,让市场来调节和选择,这才是符合社会发展规律的。用爱国的头脑来对待国产和区别进口,那一些地方曝出高科技项目烂尾如何避免落入陷阱?来源经济日报招商高科技须防烂尾本报记者王金虎科技创新是当前的热点话题,一些自带高科技光环的科技创新投资项目更成为各地竞相招引的香饽饽。然而,高处不胜寒,投资巨大科技成果转化周期长的报告显示明朝万达科创能力位列小巨人企业前五近日,科创情报SaaS服务商智慧芽发布了2021专精特新小巨人企业专利能力和科创力报告(以下简称报告)。其中,报告对专精特新小巨人企业进行了科创能力排名,北京明朝万达科技股份有限公坑人的支付宝,坑人的淘票票cp坑人的支付宝,坑人的淘票票。我9月17号在支付宝淘票票花48。5圆购买了9月30日两张电影长津湖的电影票。突然,淘票票取消了电影票,也退款了。我要求换场次。淘票票不说可以,也不机器人产业发展的关键在人才来源人民网人民日报海外版机器人产业发展日益受到重视,十四五规划和2035年远景目标纲要强调推动机器人产业创新发展。作为深入实施制造强国战略的重要一环,机器人产业正吸引着越来越多人的同力日升(605286。SH)拟获取北京天启鸿源新能源科技51股权10月8日起停牌格隆汇9月30日丨同力日升(605286。SH)公布,公司拟通过向北京天启鸿源新能源科技有限公司(标的公司)增资,并通过向其股东北京合汇创赢新能源合伙企业(有限合伙)玖盛熙华(珠海Hive和Pig的区别Hive的替代工具中最有名的就是Pig了(httppig。apache。org)。Pig是由Yahoo开发完成的,而同时期Fackbook正在开发Hive。因此Pig现在同样也是一苹果AirPods值得购买吗?感谢邀请AirPods确实是一款体验极佳的蓝牙耳机,之前觉得一个普通的蓝牙耳机差不多卖100左右,AirPods的售价再次挑战普通消费者对于蓝牙耳机售价的认知,售价高达12XX!在买二手相机镜头,淘宝和闲鱼哪个更靠谱?还是摄影论坛交流好?作为一名摄影爱好者,由于自身经济条件的限制,对摄影器材的选择是非常谨慎的,除了第一部相机是买的全新的外,其他的镜头之类的基本都是在咸鱼网上买的。咸鱼和淘宝有啥不同?我把我这几年二手