zoukankan      html  css  js  c++  java
  • 断点命令【Linux学习】GDB调试器基本命令必知必会(一)

    在本文中,我们主要介绍断点命令的内容,自我感觉有个不错的建议和大家分享下

        本文介绍Linux下GDB调试器经常使用的基本命令。

        测试均在Ubuntu12.10下完成。

        先看看GDB调试的效果图:

        断点和命令

        对应的源代码:

        

    //插入排序,GDB调试测试代码
    #include <stdio.h>
    
    int x[10],//存放输入数据
            y[10],//工作空间数组
            num_inputs,//输入数组长度
            num_y = 0;//y中当前元素个数
    
    //函数
    //功能:从参数中提取输入数据
    void get_args(int ac,char **av){
            int i;
            num_inputs = ac - 1;
            for(i = 0;i < num_inputs;++i)
                    x[i] = atoi(av[i + 1]);
    }
    
    //函数
    //功能:向右挪动工作数组中索引jj及其后面的全部元素
    void scoot_over(int jj){
            int k;
            for(k = num_y;k > jj;++k)
                    y[k] = y[k - 1];
    }
    
    //函数:
    //功能:插入一个数据
    void insert(int new_y){
            int j;
            //工作数组为空
            if(0 == num_y){
                    y[0] = new_y;
                    return;
            }
    
            //将新元素插入到恰当位置:第一个比new_y大的元素后面
            for(j = 0;j < num_y;++j){
                    if(new_y < y[j]){
                            //向右挪动y[j]后面的全部元素
                            scoot_over(j);
                            y[j] = new_y;
                            return;
                    }
            }
    }
    
    //函数:
    //功能:处置全部输入数据
    void process_data(){
            for(num_y = 0;num_y < num_inputs;++num_y)
                    insert(x[num_y]);
    }
    
    //函数:
    //打印结果数据
    void print_results(){
            int i;
            for(i = 0;i < num_inputs;++i)
                    printf("%d\n",y[i]);
    }
    
    int main(int argc,char **argv){
            get_args(argc,argv);
            process_data();
            print_results();
    }

        

    源代码编译:

        

    gcc -g -Wall -o insert_sort ins.c

        

    这里面一个必要的步调是:GCC的-g选项:让编译器将符号表(对应于程序的变量和代码行的内存地址列表)保存在生成的可执行文件中。这样才能在调试会话过程当中引用源代码中的变量名和行号。

        


        

    一些基本命令

        

    启动GDB:gdb exeFileName

        

    gdb中中文表现是乱码,暂时还不知道怎么支持中文。

        


        

    联机帮助,可以通过help命令访问文档:(gdb) help breakpoints

        


        

    以TUI模式运行GDB:在调用gdb的时候指定-tui选项或者在处于非TUI模式时在GDB中使用Ctrl+X+A组合键,可以将终端屏幕分红原文本窗口和控制台的多个子窗口

        


        

    退出GDB:quit或者Ctrl+d

        


        

    可以直接按下回车再次执行近来执行过的那条命令

        


        

    执行程序:run

        


    查看栈帧:frame num(栈帧编号)
    注意栈帧编号规矩,当前正在执行的函数的帧被编号为0,其父帧(即该函数的调用者的栈帧)被编号为1,父帧的父帧被编号为2,以此类推。
    跳到调用栈中的下一个父帧:up
    引向相反方向:down

    表现整个栈,即当前存在的全部帧的集合:backtrace

    滚动查看代码:↑等箭头键

    输出当前值:print或者p

    浏览之前的GDB命令:上一个Ctrl+P、下一个Ctrl+N

    注意:如果我们须要修改程序,并且从新编译,不必重启GDB。GDB会在运行程序之前自动从新加载新的二分表和新的符号表。
    我们在从新编译程序之前仍然不必退出GDB。

        


        

    断点相关操作

        

    设置断点

        

    GDB设置点的后,该断点的有效性会持续到删除、禁用或退出GDB时。

        

    在某一行设置断点:break line_number(行数)

        

    break filename:line_number 在源代码文件filename的line_number处设置断点。

        

    在某个函数的入口(第一行可执行代码)处设置断点:break function(函数名)。这类方法相对以行数设置断点有一个优点:如果修改了源代码,使得函数不再在这一行处开始,那么如果用函数名指定断点,而不是用行号指定,则断点仍然有效。

        

    注意:break function会在全部拥有相同名称的函数上设置断点,注意函数重载的情况。

        

    break filename: function 在源代码文件filename的函数function入口处处设置断点。

        


        

    当GDB使用多个断点中断一行源代码时,它只会中断一次。

        


        

    GDB实际设置断点的位置可能和我们请求将断点放置的位置不同。

        

    比如以下代码:
    int main(void)
    {
        int i;
        i = 3;
    
       return 0;
    }

        

    如果我们实验在函数main入口处设置断点,断点实际会被设置在第4行。因为GDB会认为第三行的机器码对我们的调试目标来说没有用途。

        


        

    条件断点

        

    将正常断点转变为条件断点:condition break_p_num(断点编号) cond(条件)

        

    在有效的C条件语句中几乎可以用任何表达式。也可以用自己的函数或者库函数,只要他们被链接到程序中。

        

    如:condition 1 num_y == 1

        

    只有当满足条件num_y == 1时,GDB才会在断点1处暂停程序的执行。

        


        

    如果当前要删除条件,但是坚持断点,只需键入:cond break_p_num(断点编号)

        


        

    用break if可以将break和condition命令组合成一个步调:

        

    break line_num(行号) if cond(条件)

        

    例子:(gdb) nreak 30 if num_y == 1

        

    注意,条件语句可以用括号()括起来,也可以不用。

        


        

    临时断点:tbreak
    与break类似,但是这一命令设置的断点在首次到达该指定行后就不再有效。

        


        

    删除断点

        

    基于标识符删除断点:delete

        

    delete break_point_num(断点编号),可以在后面指定多个断点编号连续删除几个断点
        每日一道理
    天又快黑了,这座忙碌的城市又将入睡,让这劳累的“身躯”暂别白日的辛勤,让它入睡,陪伴着城市中的人们进入梦乡。当空的弯月正深情地注视着这座城市与城市中的人们,看着家家户户的灯渐渐熄灭,它在床头悄悄奏响“明月曲”……

        

    delete:删除全部断点

        


        

    另一种删除断点方法:clear

        

    根据位置删除断点,工作方法和对应的break命令相似:

        

    clear function

        

    clear filename:funtion

        

    clear line_number

        

    clear filename:line_number

        


        

    clear:清除GDB将执行的下一个指令处的断点

        


        

    禁用与启用断点

        

    禁用断点:disable breakpoint-list(是用空格分离隔的多个断点标识符)

        

    禁用全部现存断点:disable

        

    启用断点:enable breakpoint-list

        

    在下次引起GDB暂停执行后禁用:enable once breakpoint-list

        


        

    查看全部断点信息:info break或者是info breakpoints或者简写为i b

        


        

    断点命令列表

        

    让GDB在每次到达某个断点时自动执行一组命令,从而自动完成某一任务。

        

    使用commands命令设置命令列表:

        

    commands breakpoint_number

        

    ...

        

    commands

        

    ...

        

    end

        

    例如以下代码:

        

    断点和命令

        

        

    我盘算查看传递给fibonacci函数的值以及次序,但是不想在程序中插入printf语句并从新编译代码,可以这样做:

        

    在该函数入口处设置一个断点,然后设置命令列表:

        

    断点和命令

        

        

    printf命令和C中printf函数类似,只是括号是可选的。

        


        

    运行结果:

        

    断点和命令

        如果嫌GDB输出太冗长,可以使用silent命令,只需将其添加到设置的命令列表最开始处便可。

        断点和命令

        

        

    恢复执行
    三种方法
    (1)单步执行:step(s)、next(n),仅执行到代码的下一行后再次暂停。
    注意两者区别:在函数调用时step会进入函数,next导致下一次暂停出现在调用函数之后。next被称为单步超出(stepping over)函数,而step被称为单步进入(stepping into)函数。
    next和step都可以采取一个可选的数值参数,来表示要使用next或step执行的额外行数。
    (2)无条件恢复程序的执行:continue(c)

        

    直到碰到另一个断点或者程序结束。

        

    continue可以接受一个可选的数值参数n,要求GDB忽略下面n个断点。

        

    (3)用finish(fin)或until(u)命令恢复。

        

    finish命令指示GDB恢复执行,直到恰好在当前帧完成之后为止。

        

    until命令通经常使用来在不进一步在循环中暂停(除了循环中的旁边断点)的情况下完成正在执行的循环。until会执行循环的其余部分(如果碰到断点,还是会暂停),让GDB在循环后面的第一行代码处暂停。

        

    until命令也可以接受源代码中的位置作为参数,其用法与break命令同。

        

    比如以下代码清单swapflaw.c:
    #include <stdio.h>
    
    void swap(int *a,int *b){
            int c = *a;
            *a = *b;
            *b = c;
    }
    
    int main(void){
            int i = 3;
            int j = 5;
    
            printf("i:%d,j:%d\n",i,j);
            swap(&i,&j);
            printf("i:%d,j:%d\n",i,j);
    
            return 0;
    }

        

    如果GDB触发了main函数入口处的一个断点,那么可以使用下面这些命令方便地使程序始终执行到swap()的入口:

        

    until 13

        

    until swap

        

    until swapflaw.c:13

        

    until swapflaw.c:swap

        


        

    监视点

        

    监视点是一种特别类型的断点,区别在于监视点没有“住在”某一行源代码中,而是指示GDB每当某个表达式改变了值就暂停执行。

        

    设置监视点:watch z(变量名)也可以是复杂的表达式

        

    注意只能监视存在且在作用域内的变量。一旦变量不再存在调用栈的任何帧中,GDB会自动删除监视点。

        

    GDB实际上是在变量的内存位置改变值时中断。

        


        

    文件清单

        

    (gdb) list line1,line2
    查看源代码
    list lineNum 在lineNum的前后源代码表现出来
    list + 列出当前行的后面代码行
    list - 列出当前行的后面代码行
    list function
    set listsize count
    设置表现代码的行数
    show listsize
    表现打印代码的行数
    list first,last
    表现从first到last的源代码行

        


        

    GDB启动文件的使用

        

    有时候我们在完成调试前可能须要退出GDB,比如须要分开比较长的一段时间而且不能坚持登录在计算机中。为了不丧失某些信息,可以将断点和设置的其他命令放在一个GDB启动文件中,然后每次启动GDB时会自动加载它们。

        

    GDB启动文件默许名为.gdbinit。可以将一个文件放在主目录中用于一般用途,另一个文件放在特定项目专用的目录中。例如,可以将设置断点的命令放在后一个目录的启动文件中,在主目录的.gdbinit文件中存储开辟的一些通用的宏。最好不要将编程项目放在主目录中,因为不能将项目特有的信息放在.gdbinit中。

        


        

    在调用GDB时可以指定启动文件,如:

        

    $gdb -command=z x

        

    表示要在可执行文件x上运行GDB,首先要从文件z中读取命令。

        

    文章结束给大家分享下程序员的一些笑话语录: 雅虎最擅长的不是开通新业务,是关闭旧业务。

  • 相关阅读:
    6月23号 java方法 什么是方法?
    6月21号 Java流程控制 练习
    6月21号 Java流程控制 break continue
    6月21号 Java流程控制 增强for
    6月19号 Java流程控制 循环结构for练习
    6月18号 Java流程控制 循环结构for
    qbot
    clion 2019.2
    raptor
    字符串练习
  • 原文地址:https://www.cnblogs.com/xinyuyuanm/p/3093779.html
Copyright © 2011-2022 走看看