g++与gdb常用参数与命令

本文详细介绍g++编译过程,包括预处理、编译、汇编和链接,并通过HelloWorld!实例演示各阶段输出。同时,深入讲解gdb调试工具的使用,包括断点、单步执行和变量查看等核心功能。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

g++ 与 gdb 常用操作

一、什么是g++,gdb ?

  g++:GNU的C++编译器。
  gdb:GNU发布的类unix系统下的程序调试工具。
    gcc与g++的区别:gcc无法链接c++程序。

二、C/C++代码到可执行程序的过程

  1. 预处理:进行头文件展开、宏替换、去掉注释和条件编译等(生成 *.i 文件)。
  2. 编译:检查代码无语法错误后,生成汇编语言代码(生成 *.s 文件)。
  3. 汇编:将汇编语言代码生成机器码(生成目标文件 *.o)。
  4. 链接:链接目标文件生成可执行文件(*.out)。

g++常用参数及其作用

参数作用
-EPreprocess only; do not compile, assemble or link.
-SCompile only; do not assemble or link.
-cCompile and assemble, but do not link.
-o < file >Place the output into < file >.
-g为调试程序(如gdb)生成相关信息.

即:

  1. -E:仅进行预处理,不进行编译、汇编与链接;
  2. -S:仅编译,不进行汇编与链接;
  3. -c:编译并汇编,但不进行链接;
  4. -o:指定输出文件。

三、一个简单的 “Hello World!”。

#include<iostream>
#define Hello "Hello World!"
int main()
{
    std::cout << Hello << std::endl;//此处利用宏输出“Hello World!”
    return 0;
}

  执行g++ file.cpp -E -o file.i,得到结果:

# 1 "file.cpp"
# 1 "<built-in>"
# 1 "<command-line>"
# 1 "/usr/include/stdc-predef.h" 1 3 4
# 1 "<command-line>" 2
# 1 "file.cpp"
# 1 "/usr/include/c++/8/iostream" 1 3
# 36 "/usr/include/c++/8/iostream" 3

# 37 "/usr/include/c++/8/iostream" 3

# 1 "/usr/include/c++/8/x86_64-redhat-linux/bits/c++config.h" 1 3


# 1 "/usr/include/bits/wordsize.h" 1 3 4
# 4 "/usr/include/c++/8/x86_64-redhat-linux/bits/c++config.h" 2 3
# 2180 "/usr/include/c++/8/x86_64-redhat-linux/bits/c++config.h" 3

# 2180 "/usr/include/c++/8/x86_64-redhat-linux/bits/c++config.h" 3
namespace std
{
  typedef long unsigned int size_t;
  typedef long int ptrdiff_t;


  typedef decltype(nullptr) nullptr_t;

}
...
...
# 2 "file.cpp" 2


# 3 "file.cpp"
int main()
{
    std::cout << "Hello World!" << std::endl;
    return 0;
}

  可以看到宏与注释被替换和处理掉了。
执行g++ file.i -S -o file.s,得到结果:

file   "file.cpp"
        .text
        .section        .rodata
        .type   _ZStL19piecewise_construct, @object
        .size   _ZStL19piecewise_construct, 1
_ZStL19piecewise_construct:
        .zero   1
        .local  _ZStL8__ioinit
        .comm   _ZStL8__ioinit,1,1
.LC0:
        .string "Hello World!"
        .text
        .globl  main
        .type   main, @function
main:
.LFB1518:
        .cfi_startproc
        pushq   %rbp
        .cfi_def_cfa_offset 16
        .cfi_offset 6, -16
        movq    %rsp, %rbp
        .cfi_def_cfa_register 6
        movl    $.LC0, %esi
        movl    $_ZSt4cout, %edi
        call    _ZStlsISt11char_traitsIcEERSt13basic_ostreamIcT_ES5_PKc
        movl    $_ZSt4endlIcSt11char_traitsIcEERSt13basic_ostreamIT_T0_ES6_, %esi
        movq    %rax, %rdi
        call    _ZNSolsEPFRSoS_E
        movl    $0, %eax
        popq    %rbp
        .cfi_def_cfa 7, 8
        ret
        .cfi_endproc
        ...
        ...

  可以看到处理后得到的汇编代码。
继续执行g++ file.s -c -o file.o,得到:

[pig@localhost learn]$ head file.o
ELF>�@@UH������H����]�UH��H���}��u��}�u'�}���u���������UH�����������]�Hello World!GCC: (GNU) 8.2.1 20180905 (Red Hat 8.2.1-3)zRx
                                                                                                                                               �'AbC
y<>A�C
P\A�C
 ��
%4'>de	
s'x���+Cfile.cpp_ZStL19piecewise_construct_ZStL8__ioinit_Z41__static_initialization_and_destruction_0ii_GLOBAL__sub_I_main_ZSt4cout_ZStlsISt11char_traitsIcEERSt13basic_ostreamIcT_ES5_PKc_ZSt4endlIcSt11char_traitsIcEERSt13basic_ostreamIT_T0_ES6__ZNSolsEPFRSoS_E_ZNSt8ios_base4InitC1Ev__dso_handle_ZNSt8ios_base4InitD1Ev__cxa_atexit


��������
��������E
J��������O
T
Y

继续执行g++ file.o -o file.out,得到可执行文件。执行./file.out,得到:

[pig@localhost learn]$ g++ file.o -o file.out
[pig@localhost learn]$ ./file.out 
Hello World!
[pig@localhost learn]$ 

四、gdb常用命令及作用

  在使用gdb调试程序时,需要在g++的参数中加入 -g,然后运行gdb *.out。否则,调试时看到的将是一堆汇编代码。

命令缩写描述
helph获取帮助信息
listl显示源代码
search朝向文件尾部搜索源代码
reverse-search朝文件头部搜索源代码
breakb设置断点
info break查看断点信息
clear清楚当前行的断点
runr从头运行程序到第一个断点
nextn单步执行(不进入函数体)
steps单步执行(进入函数体)
continuec从当前行继续运行程序至下一断点
printp打印变量值
watch设置观察点
set var variable=value设置变量variable的值为value
bt查看运行时栈
quitq退出gdb

  断点相关命令:

命令作用
b num根据行号设置断点
b file.c:num设置指定文件中的行号断点
b function根据函数名设置断点
b file.cpp:num if(express)根据表达时条件在某行设置断点
rbreak function*对所有function调用设置断点
rbreak .对所有函数设置断点
rbreak file.cpp:.对文件中的所有函数设置断点
rbreak file.cpp:^express对file.cpp中所有express开头的函数设置断点
tbreak断点仅生效一次
ignore num time忽略断点号为num的断点time次
disable禁用所有断点
disbale num禁用编号为num的断点
enable启用所有断点
enable num启用编号为num的断点
enable delete num启用并在此之后删除编号为num的断点
clear删除当前行所有断点
clear function删除函数名为function的断点
delete删除所有断点、观察点和捕捉点
delete num删除编号为num的断点

  End…

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值