gdb调试使用

来源:互联网 发布:深圳积分入学 算法 编辑:程序博客网 时间:2024/05/16 10:09

    功夫再牛也怕菜刀,程序员不可能不犯错误,在linux下面调试我们使用gdb,这次就讲他的使用,它可以调试C和C++,gdb提供的功能有:

    1.监视程序中的变量的值

    2。设置断点停止代码执行

    3,一行行的执行

使用方式很简单,在命令行键入gdb就能用了,正常启动就会有如下类似的内容,

在这里可以键入命令来指定想要调试的文件名

$:gdb filename

这是就自动化装入了这个filename的文件

下面对一个代码进行分析 使用gdb进行调试

这个程序作用是将一个字符串反序输出,字符串为"Hello World";

代码如下:

然后编译用命令

$:gcc -o test gdbtest.c

然后运行

$:./test

显示为

发现第二个函数起到作用,大家是个明眼人应该已经看出来程序错在哪里,不过我们还是来调试下

使用命令

gcc gdbtest.c -g -o test

这条命令为了使程序在编译的时候加入调试信息,调试信息包括程序里的每个变量的类型和在可执行文件力的地址映射以及源代码的行号;

然后使用

gdb test ;命令,进入test可执行文件,进入gdb后,输入run命令运行test,结果显示如下:

陈寻运行结果和程序外运行结果没有什么不同,所以在for语句后面设置一个断点,首先要查处for语句的行号,在gdb下面输入list可以列出代码;

list默认列出10行代码,按回车就默认重复上一条命令,知道列完,我们发现应该在14行出加入断点,所以设置断点方法为

这样就设置了个断点,再次输入run,就会停在15行“string2[size-i]=string[i];"处,如图

可以设置一个观察点来观察string2[size-i]的值,

$:watch string2[size-i]

然后输入命令c来继续运行直到停止在下次循环体语句处,经过第一次循环,gdb显示如下:

大家从这个句子就发现了问题了把,这么交换的结果就是string2的第一个字符是个空子符,这就解释了为了什么没输出,验证下我们一直回车下去;为了方便,连i也一起watch了把;看到了

当i=11是就赋值完了‘!’,而string2的第一个[0]的位置却没值,仍然是初始化后的'/0',程序修改方法

“string2[size-i]=string[i];”改为“string2[size-i-1]=string[i];“

“string2[size+1]='/0';”改为“string2[size]='/0';”就OK啦~

发现我这个版本的gdb有点小bug,问题就在上上面那张图上,new value 和 old value显然有点写反了……

                                                                                 gdb基本命令

 

file装入想要调试的可执行文件。kill终止正在调试的程序。list执行一行源代码但不进入函数内部。next执行一行源代码但不进入函数内部。step执行一行源代码而且进入函数内部。run执行当前被调试的程序quit终止 gdbwatch使你能监视一个变量的值而不管它何时被改变。break在代码里设置断点, 这将使程序执行到这里时被挂起。make使你能不退出 gdb 就可以重新产生可执行文件。shell使你能不离开 gdb 就执行 UNIX shell 命令。

gdb的调用:

一般情况下gdb命令只是用一个参数:gdb<可执行程序名>

同时,如果程序运行时产生了段错误,会在当前目录下面产生核心内存印象core文件,可以在指定的执行文件的同时为可执行程序指定一个core文件:

gdb<可执行文件名>core

除此之外,还可以为要置信的文件指定一个进程号

gdb<可执行文件名>core<进程号>

 

比如将test指定进程号3000,

gdb test 3000

那么首先gdb会寻找一个文件名为3000的文件,如果没有的话,则把调试程序test的PID设为3000.

意义在于如果程序是一个服务程序,那么可以指定这个服务程序运行时的进程ID。gdb会自动attach上去,并调试它。program应该在PATH环境变量中搜索得到。

gdb启动时,可以加上一些gdb的启动开关,详细的开关可以用gdb -help查看。下面只列举一些比较常用的参数:

-symbols <file>

-s <file>

从指定文件中读取符号表。

-se file

从指定文件中读取符号表信息,并把它用在可执行文件中。

-core <file>

-c <file>

调试时core dump的core文件。

-directory <directory>

-d <directory>

加入一个源文件的搜索路径。默认搜索路径是环境变量中PATH所定义的路径。

/////////////////////////////////////////////////////////////////////

         现在我们来聊聊gdb运行模式的选择。我们可以用许多模式来运行gdb,例如在“批模式” 或“安静模式”。这些模式都是在gdb运行时在命令行作为选项指定的。 
    `-nx/" 
    `-n/" 
              不执行任何初始化文件中的命令。(一般初始化文件叫做`.gdbinit/").一般情况下在这些文件中的命令会在所有的命令行参数都被传给gdb后执行。
    `-quiet/" 
    `-q/" 
                       “安静模式”。不输出介绍和版权信息。这些信息在“批模式”中也被跳过。
    `-batch/" 
              “批模式”。在“批模式”下运行。当在命令文件中的所有命令都被成功的执行后gdb返回状态“0”,如果在执行过程中出错,gdb返回一个非零值。“批模式”在把gdb作为一个过滤器运行时很有用。比如在一台远程计算机上下载且执行一个程序。信息“ Program exited normally”(一般是当运行的程序正常结束时出现)不会在这种模式中出现。 
    `-cd DIRECTORY/" 
                  把DIRECTORY作为gdb的工作目录,而非当前目录(一般gdb缺省把当前目录作为工作目录)。 
    `-fullname/" 
    `-f/" 
              GNU Emacs 设置这个选项,当我们在Emacs下,把gdb作为它的一个子进程来运行时,Emacs告诉gdb按标准输出完整的文件名和行号,一个可视的栈内容。这个格式跟在文件名的后面。行号和字符重新按列排,Emacs-to-GDB界面使用//032字符作为一个显示一页原文件的信号。 
    `-b BPS/" 为远程调试设置波特率。
    `-tty DEVICE/" 使用DEVICE来作为你程序的标准输入输出。


原创粉丝点击