文章详情

短信预约-IT技能 免费直播动态提醒

请输入下面的图形验证码

提交验证

短信预约提醒成功

【Linux】调试器 gdb 及 ‘\r‘ 的使用

2023-09-05 21:22

关注

目录

前言

gdb

断点

打断点

查看、删除断点

断点使能

调试

显示数据

其他指令

‘\r’的使用

行缓冲区

小程序


🥑在 Linux 下我们可以通过 gcc 进行编译,但与 vs 相比若想对代码进行调试,我们还需要学会使用调试器 gdb 

🥑我们都知道程序的发布方式有两种,release 版本和 debug 版本,而 release 版本是无法进行调试的,在 VS 之中默认为 debug 版本,并且可以通过选取来直接更改程序的不同版本。

🥑但在 Linux gcc/g++ 出来的二进制程序,默认是 release 模式,因此无法调试。若想转换成 debug 版本,则必须在源代码生成二进制程序的时候, 加上 -g 选项。

gcc -g -o text text.c

🥑同时我们也注意到,debug 版本的可执行程序明显占的空间较大,这是因为 release 版本是最终用户在使用的版本,且用户根本不需要对文件进行调试,为了节约空间占比,release 版本便不会加上文件的调试信息,这也是为什么 release 版本下无法进行调试的原因。

-rwxrwxr-x 1 Alpaca Alpaca 9544 Feb  3 11:56 text.debug-rwxrwxr-x 1 Alpaca Alpaca 8384 Feb  3 11:57 text.release

🥑当我们拿到 debug 版本的可执行文件之后就可以进行调试了。直接 gdb + 可执行文件名 就可以打开调试器了。

[Alpaca@VM-12-9-centos myfile]$ gdb text.debug    //gdb + 文件名GNU gdb (GDB) Red Hat Enterprise Linux 7.6.1-120.el7Copyright (C) 2013 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 "x86_64-redhat-linux-gnu".For bug reporting instructions, please see:...Reading symbols from /home/Alpaca/myfile/text.debug...done.(gdb)                //进入后的命令行

🥑l + 行号(中间要有空格): 从该行开始向下打印10行。若代码过长再按回车会自动重复上一个指令进行操作。

(gdb) l 11#include2#include34void plus(int* p)5{6*p *= 2;7}89int main()10{(gdb)       //再按一次回车11int count = 0;12while (1)13{14printf("%d\n", count);15count++;16plus(&count);17}18return 0;19}(gdb) 

🥑r :开始调试 ,与VS中的F5效果相同,若程序非死循环或过程中无断点则会直接执行到程序结束。

断点

打断点

🥑 d + 行号 :在该行打断点。

🥑 d + 函数名 : 在该函数有效行处打上断点。

(gdb) b 11            //以行号打断点Breakpoint 3 at 0x40054e: file text.c, line 11.(gdb) b main          //找函数打断点Breakpoint 1 at 0x40054e: file text.c, line 11.

查看、删除断点

🥑 info b :查看所有断点信息。

🥑 d + 断点编号 :删除断点

(gdb) info bNum     Type           Disp Enb Address            What3       breakpoint     keep y   0x000000000040054e in main at text.c:114       breakpoint     keep y   0x0000000000400555 in main at text.c:145       breakpoint     keep y   0x0000000000400569 in main at text.c:15
(gdb) d 4(gdb) info bNum     Type           Disp Enb Address            What3       breakpoint     keep y   0x000000000040054e in main at text.c:115       breakpoint     keep y   0x0000000000400569 in main at text.c:15

断点使能

🥑 disable :  禁用断点。(当禁用断点后再次运行直到程序结束才会停止)

🥑 enable :  使用断点。

🥑 n :逐过程调试。(类似于VS中的F10,若遇到函数调用不会进入到函数之中)

🥑 :逐语句调试。(类似于VS中的F11,会进入到函数之中继续调试)

//逐语句Breakpoint 3, main () at text.c:1111int count = 0;(gdb) n14printf("%d\n", count);(gdb) n0Breakpoint 5, main () at text.c:1515count++;(gdb) n16plus(&count);(gdb) 17}//逐语句Breakpoint 5, main () at text.c:1515count++;(gdb) 16plus(&count);(gdb) plus (p=0x7fffffffe42c) at text.c:66*p *= 2;(gdb) 7}(gdb) main () at text.c:1717}

显示数据

🥑 p + 变量名 :打印出该变量当前的值。

🥑 display + 变量名:跟踪查看一个变量,每次停下来都显示它的值。

🥑 undisplay + 编号 : 取消对变量的跟踪查看。

(gdb) p count$4 = 2(gdb) display count3: count = 2(gdb) undisplay 3

其他指令

🥑 c :从一个断点处直接执行到下一个断点。

🥑 set var:修改变量的值。

🥑 finish : 执行完一个函数。

🥑 until + 行号:跳至该行。
🥑 bt :查看各级函数调用及参数。
🥑 quit :退出gdb。

🥑在Linux下以下的三条语句会产生三种不一样的结果。

    printf("hello world\n");     //正常打印后暂停一秒sleep(1);    printf("hello world");       //暂停了一秒后语句和提示符一起打印出来                       sleep(1);    printf("hello world\r");     //无语句打印                       sleep(1);
hello world[Alpaca@VM-12-9-centos myfile]$ hello world[Alpaca@VM-12-9-centos myfile]$[Alpaca@VM-12-9-centos myfile]$ 

行缓冲区

🥑在字符串被打印出来之前,会将其先加载到行缓冲区之中,但不是立刻就会打印出来。因此在第二条语句时,语句还没有打印出来系统就暂停了一秒钟,之后行缓冲区刷新,将之前的内容都打印出来, 因此第二个语句才会是先暂停一秒再打印。又因为提示符是跟随光标打印的,所以便跟在语句之后打印。

🥑我们都知道 \n 为换行符,而 \r 又被称为回车,会将光标会到本行的最开始。当我们使用 \n 便会强行刷新行缓冲区,使之前的数据被打印出来。而第三个语句之所以没有打印出语句则是因为 \r 使得光标回到本行开头,提示符从头开始打印将原来要打印出来的语句覆盖掉了,所以没有语句显示出来。

🥑若使用fflush对缓冲区进行刷新的话,便能够看到语句打印出来一秒钟后,就被系统的提示符覆盖打印了。

#include #include int main(){   printf("hello world\r");   fflush(stdout);          sleep(1);   return 0;}

小程序

🥑通过上面第三个语句的启发,我们可以写出一个类似于进度条的小程序,通过每次重复覆盖打印,得到进度条在持续增长的效果。

#include#include#include #define SIZE 101int main(){  int i = 0;  char s[SIZE];        //转换成重复打印一个数组  memset(s,0,SIZE*sizeof(char)); //对数组初始化  const char *lable ="|/-\\";  while(i<=100)  {    if(i!=100)    {       s[i] = '>';     //i指向最高一位,作为箭头    }     printf("[%-100s][%3d%%][%c]\r",s,i,lable[i%4]); //把数组对其打印出来,并附上其他观赏性信息     fflush(stdout);                 //每次刷新缓冲区                      s[i++] = '=';                   //进度条延长     usleep(100000);  }   printf("\n");   return 0; }

🥑好了这次调试器 gdb'\r' 的介绍就到这里结束了,关注博主共同进步!!

来源地址:https://blog.csdn.net/Lin_Alpaca/article/details/128863346

阅读原文内容投诉

免责声明:

① 本站未注明“稿件来源”的信息均来自网络整理。其文字、图片和音视频稿件的所属权归原作者所有。本站收集整理出于非商业性的教育和科研之目的,并不意味着本站赞同其观点或证实其内容的真实性。仅作为临时的测试数据,供内部测试之用。本站并未授权任何人以任何方式主动获取本站任何信息。

② 本站未注明“稿件来源”的临时测试数据将在测试完成后最终做删除处理。有问题或投稿请发送至: 邮箱/279061341@qq.com QQ/279061341

软考中级精品资料免费领

  • 历年真题答案解析
  • 备考技巧名师总结
  • 高频考点精准押题
  • 2024年上半年信息系统项目管理师第二批次真题及答案解析(完整版)

    难度     813人已做
    查看
  • 【考后总结】2024年5月26日信息系统项目管理师第2批次考情分析

    难度     354人已做
    查看
  • 【考后总结】2024年5月25日信息系统项目管理师第1批次考情分析

    难度     318人已做
    查看
  • 2024年上半年软考高项第一、二批次真题考点汇总(完整版)

    难度     435人已做
    查看
  • 2024年上半年系统架构设计师考试综合知识真题

    难度     224人已做
    查看

相关文章

发现更多好内容

猜你喜欢

AI推送时光机
位置:首页-资讯-人工智能
咦!没有更多了?去看看其它编程学习网 内容吧
首页课程
资料下载
问答资讯