美文网首页
Biu一Biu---GDB

Biu一Biu---GDB

作者: yeshan333 | 来源:发表于2018-12-04 00:05 被阅读12次

    gcc常见编译选项

    • ** -c **:只激活预处理、编译和汇编,也就是生成obj文件
    • ** -S **:只激活处理和编译,把文件编译成汇编代码
    • ** -o **:定制目标名称,缺省的时候编译出来的可执行程序名为a.exe(windows)或a.out(linux)
    • ** -Wall **:打开一些很有用的编译警告
    • ** -std **:指定C标准,如-std=99,使用C99标准
    • ** -g **:指示编译器,编译的时候添加调试信息
    • ** -O0 -O1 -O2 -O3 **:编译器的优化选项的4个级别,-O0表示没有优化,-O1为缺省值,-O3优化级别最高
    image
    /*
    file_name: swap.c
    */ 
    
    #include<stdio.h>
    void swap(int a, int b)
    {
        int t;
        t = a;
        a = b;
        b = t;
    }
    
    int main()
    {
        int a=3, b=4;
        swap(a,b);
        printf("%d %d",a,b);
        return 0;   
    }
    

    GDB的使用

    什么是GDBhttps://www.bing.com/knows/search?q=gdb&mkt=zh-cn&FORM=BKACAI
    http://www.gnu.org/software/gdb/

    一般来说,GDB主要帮助你完成以下四个方面的内容
    1、启动你的程序,可以按照你的自定义的要求随心所欲的运行程序
    2、可以让被调试的程序在你所指定的调置的断点处停住。(断点可以是条件表达式)
    3、当程序被停住时,可以检查此时你的程序中所发生的事
    4、你可以改变你的程序,将一个BUG产生的影响修正,从而测试其他BUG

    GDB常见命令

    简称 全称 备注
    l list 显示指定行号或者指定函数附近的源代码
    b break 在指定行号或指定函数开头设置断点
    r run 运行程序,直到程序结束或遇到断点
    c continue 在程序中断后继续执行程序,直到程序结束或遇到断点停下。注意在程序开始执行前只能用r,而不能用c
    n next 执行一条语句。如果有函数调用,则把它当做一个整体
    s step 执行一条语句。如果有函数调用,则进入函数内部
    u until 执行到指定行号或指定函数的开头
    p print 显示变量或表达式的值
    disp display 把一个表达式设置为display,当程序每次停下来时都会显示其值
    cl clear 取消断点,和b格式相同,如果该位置有多个断点,将同时取消
    i info 显示各种信息,如i b显示所有断点,i disp显示display,而i lo显示所有局部变量
    bt backtrace 打印所有栈帧信息

    调用栈(Call Stack)

    调用栈描述的是函数之间的调用关系。调用栈由栈帧(Stack Frame)组成,每个栈帧对应着一个未运行完的函数。在GDB中可以用backtrace(简称bt)命令打印所有栈帧信息。若要用p命令打印一个非当前栈帧的局部变量,可以用frame命令选择另一个栈帧

    拿个程序来玩玩,swap.c文件

    #include<stdio.h>
    void swap(int a, int b){
        int t;t = a;a = b;b = t;
    }
    
    int main(){
        int a=3, b=4;
        swap(a,b);
        printf("%d %d",a,b);
        return 0;   
    }
    
    image image

    *** 程序的目的是交换a和b的值,然而并没有交换交换成功 ***

    image

    原因:

    • 函数的形参和在函数内部声明的变量都是该函数的局部变量。无法访问其他函数的局部变量。
    • 局部变量的存储空间是临时分配的,函数执行完毕时,局部变量的空间将被释放,其中的值无法保留到下次使用。
    • 如果要实现真正的交换,我们应该传入的是存储变量的地址,此时函数swap的形参类型应该为指针类型

    PS:
    C语言的变量都是放在内存中的,而内存中间的每一个字节都有一个称为地址(address)的编号。
    每一个变量都占有一定数目的字节(可以用sizeof运算符获得),其中第一个字节的地址称为变量的地址。

    o(*≧▽≦)ツ┏━┓拿个递归程序来玩玩

    #include<stdio.h>
    int f(int n)
    {
        return n == 0 ? 1 : f(n-1)*n;
    }
    int main()
    {
        printf("%d\n",f(3));
        return 0;
    }
    
    
    image image

    在C语言的函数中,调用自己和调用其他函数没有任何本质区别,都是建立新栈帧,传递参数并修改当前代码行。在函数执行体完毕后删除栈帧,处理返回值,并修改当前代码行数。

    以上调用栈的一个比喻

    皇帝(拥有main函数的栈帧):大臣,你给我算下f(3)
    大臣(拥有f(3)的栈帧):知府,你给我算下f(2)
    知府(拥有f(2)的栈帧):县令,你给我算下f(1)
    县令(拥有f(1)的栈帧):师爷,你给我算下f(0)
    师爷(拥有f(0)的栈帧):回老爷,f(0)=1
    县令(心算f(1)=f(0)1=1):回知府大人,f(1)=1
    知府(心算f(2)=f(1)
    2=2):回大人,f(2)=2
    大臣(心算f(3)=f(2)*3=6):回皇上,f(3)=6
    皇上满意了

    emmmmmm。。。。。。。。。。。。

    最后欢迎来我的个人博客看看https://shansan.top

    相关文章

      网友评论

          本文标题:Biu一Biu---GDB

          本文链接:https://www.haomeiwen.com/subject/lxspcqtx.html