当前位置:Linux教程 - Linux - GUN中的GCC和GDB

GUN中的GCC和GDB



        
    1.gcc简单介绍

    gcc使一个高效而强有力的C编译器.在这里我为初学者提供了
    快速入门的一些描述.

    a.c
    #include
    main()
    {
    printf(\"Hello world!\\n\");
    }

    gcc a.c -o hello
    hello
    Hello world!

    基本参数:
    -c 只编译不连接
    如:gcc a.c -c 只产生a.o

    -o 设定输出文件名
    如:gcc a.c -o hello

    -s 产生汇编文件后停止
    如:gcc a.c -s
    产生a.s

    -g 加入调试信息,为gdb准备

    -l 设定要连接的库
    如:gcc a.c -lfoo
    连接libfoo.so或libfoo.a

    缺省时,gcc优先连接动态库,实在找不到才连接静态库.
    -static 强制连接静态库

    -O1
    -O2
    -O3
    进行优化,1 2 3表示不同的优化等级.
    -O0
    不进行优化

    -W
    产生警告信息,常用 -Wall 表示输出所有的警告信息.

    -Dname
    定义,相当于在C中使用#define name

    -shared
    编译产生共享库.
    -fPIC
    在编译共享库时作一些优化.

    产生自己的共享库:
    a.c
    #include
    void pln(char *str)
    {
    printf(\"%s\\n\",str);
    }

    gcc -shared -fPIC a.c -o libmy.so
    -----
    也可以不加
    b.c
    extern viod pln(char *)
    main()
    {
    pln(\"hello world\");
    }

    gcc b.c -lmy
    注意:缺省情况下gcc只在/etc/ld.so.conf中指定的目录下寻找库.

    -Idir
    也在dir下找头文件.
    -Ldir
    也在dir下找库文件.

    经常会看到 -Wl option , 这是将option作为参数传给连接程序
    ,如option中有逗号,则分裂为多个参数传递.

    2.Gdb简单应用

    Gdb是GNU的超级调试工具,功能强大,无法控制.本文只能介绍
    一些常用的命令.为了使用Gdb,在编译时加上参数 -g.
    如:
    g.c
    #include
    void b();

    main()
    {
    int i=10;
    b();
    }
    void b()
    {
    int i;
    i=100;
    }
    gcc a.c -g
    gdb a.out
    l 命令来列出源码
    (gdb) l
    1 #include
    2 void b();
    3
    4 main()
    5 {
    6 int i=10;
    7 b();
    8 }
    9
    10 void b()
    (gdb) l
    11 {
    12 int i;
    13 i=100;
    14 }

    l n,m
    列出从n到m.

    l function
    列入出函数function的源码.

    r 运行程序,r 后可直接接参数, 参数被传给程序.

    p 命令可以看个变量的内容.如:(gdb)p i

    断点的设置和管理:

    b 设置断点.
    b 行号
    b 函数名
    每一个断点用一个序列号来描述.

    c 继续运行

    如:
    (gdb) b b
    Breakpoint 1 at 0x804845a: file g.c, line 13.
    ---
    序列号为1
    (gdb) r
    Starting program: /root/tmp/a.out

    Breakpoint 1, b () at g.c:13
    13 i=100;
    (gdb) c
    Continuing.

    Program exited with code 0240.

    info breakpoint 可以察看现在的断点情况.

    delete 序列号 用来删除断点
    clear 行号 也是用来删除断点的

    enable 序列号 允许一个断点
    disable 序列号 禁止一个断点

    tb 创建一个临时断点,中断一次后即被禁止.

    其实,在设断点时还可以加条件,例如:
    b 100 if ( i == 10 )
    但运行到100行且i等于10则中断.

    如果希望在i等于100时被中断,而不管运行到哪里,可用下面的
    命令: watch i == 100. 如果希望无论何时只要存取i时,就会被中断
    awatch i.

    命令bt产生议长列表,包含了从最近的过程开始的所有的有效过程
    和调用这些进程的参数.

    用set variable i=100 可以改变变量i的值.

    用where可以知道当前的位置.
    用whatis和ptype可以显示变量的类型.你试一试就知道了.


    单步执行:
    step
    next
    区别在于,step可以调试进一个函数的内部.

    看看下面一个程序:
    a.c

    a()
    {
    int i=0;
    b()
    }
    b()
    {
    int i;
    i=100;
    ......

    当你调试进函数b时,你用p i会看到b 中的 i.实际上,这些局部变
    量是存栈中的,在gdb中可用up和down来在堆栈中移动.在上面这个
    例子中,
    (gdb)p i
    i = 100 //b中的i
    (gdb)up //切换到函数a的堆栈中
    (gdb)p i //a中的i
    i = 0
    (gdb)down //返回b

    你可以直接使用命令call来调用一个函数,当你在一个函数中时,
    你可以用finish来结束本次调用(后面的代码被运行),也可以用
    (return 返回值)来强制返回(后面的代码不被运行).

    在gdb中处理信号:
    handle 信号名 option
    option
    nostop 不发送给程序,也不停止程序.
    stop 停止程序运行,以便调试
    print 打印一条消息
    noprint 不显示消息
    pass 将信号传递给程序
    nopass 不把信号传递给程序

    你可以使用(signal 信号名)来主动发送一个信号.

    发布人:netbull 来自:Bricks with GNU&LINU