第01课:调试信息与调试原理

Posted wzqstudy

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了第01课:调试信息与调试原理相关的知识,希望对你有一定的参考价值。

  Linux下C/C++程序开发,即使使用Makefile、Cmake等编译工具,其最终都是调用GCC这一编译工具组的。这里说的工具组,是因为编译C程序和C++程序使用的编译工具还是有一点差别的,一般编译C程序使用GCC,编译C++程序使用G++。(下文统一使用GCC这一名词代指)。

  我使用的操作系统是Deepin。如果你机器上没有GCC和GDB,可以安装一下。

    debian系列的使用  apt-get

    redhat系列的使用  yum

 

  一般要调试某个程序,为了能清晰地看到调试的每一行代码、调用的堆栈信息、变量名和函数名等信息,需要调试程序含有调试符号信息。使用GCC编译程序时,如果加上-g选项即可在编译后的程序中保留调试符号信息。举个例子,以下命令将生成一个带调试信息的程序hello_server。

    gcc -g -o hello_server hello_server.c

  那么如何判断hello_server是否带有调试信息呢?我们使用GDB来调试一下这个程序,GDB会显示正确读取到改程序的调试信息,在打开的Linux Shell终端输入gdb hello_server查看显示结果即可:

技术分享图片

GDB加载成功以后,会显示如下信息:

      Reading symbols from hello_server...done.

 

另外补充两点说明:

  -- 本课程里虽然以GCC为例,但-g选项实际上同样适用于MakeFile、Cmake等工具编译生成的Linux程序。

  -- 在实际生成调试程序时,一般不仅要加上-g选项,也建议关闭编译器的程序优化选项。编译器的程序优化选项一般有五个级别,从O0-O4,O0表示不优化,从O1-O4优化级别越来越高,O4最高。这样做的目的是为了调试的时候,符号文件显示的调试变量等能与源代码完全对应起来。举个例子,假设有以下代码:

int func()
{
   int a = 1;
   int b = a + 1;
   int c = a + b;
   return a + b + c;       
}

int main()
{
     int a = func();
     printf("%d
",a);
}

  在此代码中,由于在main()函数中调用了func()函数,而func()函数值可以在编译期间直接算出来,如果开启了优化选项,在实际调试的时候,这个函数中的局部变量a,b,c,被直接的值取而代之(即编译器计算得出的值,a直接使用1,b直接使用2,c直接使用3,不会产生通过a计算b,通过a、b计算c的指令),甚至连函数func()也可能被优化掉。如果出现这种情况,调试显示的代码和实际代码可能就会有差异了,这会给排查问题带来困难。当然,上面说的优化现象是否一定会出现,不同版本的编译器可能会有不同的行为。总之一句话,建议生成调试文件时关闭编译器优化选项。

以上是关于第01课:调试信息与调试原理的主要内容,如果未能解决你的问题,请参考以下文章

20165306 第四周课下作业

第07课:实战调试Redis准备工作

第17课 调试程序

第02课:启动GDB调试

谷歌浏览器调试jsp 引入代码片段,如何调试代码片段中的js

python 第1课 - 软件调试