gpt4 book ai didi

c++ - gcc -g :what will happen

转载 作者:IT老高 更新时间:2023-10-28 14:01:56 27 4
gpt4 key购买 nike

这个问题是在一次采访中问我的。

他们问我如何生成可以调试的核心转储文件。然后我说用 gcc 中的 -g 标志我们可以做到。

然后他们问我那个 -g 标志到底对编译器做了什么。

我说(可能是一个错误的答案)它将打开核心文件中所有可用于调试的符号。

谁能告诉我它到底是做什么的?

最佳答案

这有点对,但不完整。 -g 请求编译器和链接器在可执行文件本身中生成和保留源级调试/符号信息。

如果...

  • 该程序后来发生崩溃并生成一个核心文件(这表明实际代码中存在一些问题),或者
  • 一个故意的操作系统命令强制它进入核心(例如kill -SIGQUIT pid),或者
  • 程序调用转储核心的函数(例如 abort)

...- 实际上没有一个是由使用 -g 引起的 - 然后调试器将知道如何从可执行文件并将其与核心交叉引用。这意味着您可以在堆栈帧中查看变量和函数的正确名称、获取行号并在您在可执行文件中四处走动时查看源代码。

调试信息在调试时很有用 - 无论您是从内核开始还是仅从可执行文件开始。它甚至有助于从 pstack 等命令产生更好的输出。 .

请注意,您的环境可能有其他设置来控制是否生成内核(它们可能很大,并且没有一般的方法可以知道它们是否/何时可以删除,因此并不总是需要它们)。例如,在 UNIX/LINUX shell 上,它通常是 ulimit -c。 .

您可能也有兴趣阅读 DWARF Wikipedia - 一种常用的调试信息格式,用于对可执行/库对象中的嵌入式调试/符号信息进行编码(例如,在 UNIX 和 Linux 上)。

根据 Victor 在评论中的要求更新...

符号信息列出了源代码中的标识符(通常仅在需要的任何 name mangling 之后)、它们将在进程内存中加载的(虚拟)内存地址/偏移量、类型(例如数据与代码)。比如……

$ cat ok.cc
int g_my_num;
namespace NS { int ns_my_num = 2; }
int f() { return g_my_num + NS::ns_my_num; }
int main() { return f(); }

$ g++ -g ok.cc -o ok # compile ok executable with symbol info

$ nm ok # show mangled identifiers
00000000004017c8 d _DYNAMIC
0000000000401960 d _GLOBAL_OFFSET_TABLE_
0000000000400478 R _IO_stdin_used
w _ITM_deregisterTMCloneTable
w _ITM_registerTMCloneTable
w _Jv_RegisterClasses
000000000040037c T _Z1fv # this is f()
0000000000401798 D _ZN2NS9ns_my_numE # this is NS::ns_my_num
00000000004017a8 d __CTOR_END__
00000000004017a0 d __CTOR_LIST__
00000000004017b8 d __DTOR_END__
00000000004017b0 d __DTOR_LIST__
0000000000400540 r __FRAME_END__
00000000004017c0 d __JCR_END__
00000000004017c0 d __JCR_LIST__
00000000004017c8 d __TMC_END__
00000000004017c8 d __TMC_LIST__
0000000000401980 A __bss_start
0000000000401788 D __data_start
0000000000400440 t __do_global_ctors_aux
00000000004002e0 t __do_global_dtors_aux
0000000000401790 d __dso_handle
0000000000000000 a __fini_array_end
0000000000000000 a __fini_array_start
w __gmon_start__
0000000000000000 a __init_array_end
0000000000000000 a __init_array_start
00000000004003a0 T __libc_csu_fini
00000000004003b0 T __libc_csu_init
U __libc_start_main
0000000000000000 a __preinit_array_end
0000000000000000 a __preinit_array_start
0000000000401980 A _edata
0000000000401994 A _end
0000000000400494 T _fini
000000000040047c T _init
0000000000400220 T _start
000000000040024c t call_gmon_start
0000000000401980 b completed.6118
0000000000401788 W data_start
0000000000400270 t deregister_tm_clones
0000000000401988 b dtor_idx.6120
0000000000401994 A end
0000000000400350 t frame_dummy
0000000000401990 B g_my_num # our global g_my_num
0000000000400390 T main # the int main() function
00000000004002a0 t register_tm_clones

$ nm ok | c++filt # c++filt "unmangles" identifiers...
00000000004017c8 d _DYNAMIC
0000000000401960 d _GLOBAL_OFFSET_TABLE_
0000000000400478 R _IO_stdin_used
w _ITM_deregisterTMCloneTable
w _ITM_registerTMCloneTable
w _Jv_RegisterClasses
000000000040037c T f()
0000000000401798 D NS::ns_my_num
00000000004017a8 d __CTOR_END__
00000000004017a0 d __CTOR_LIST__
00000000004017b8 d __DTOR_END__
00000000004017b0 d __DTOR_LIST__
0000000000400540 r __FRAME_END__
00000000004017c0 d __JCR_END__
00000000004017c0 d __JCR_LIST__
00000000004017c8 d __TMC_END__
00000000004017c8 d __TMC_LIST__
0000000000401980 A __bss_start
0000000000401788 D __data_start
0000000000400440 t __do_global_ctors_aux
00000000004002e0 t __do_global_dtors_aux
0000000000401790 d __dso_handle
0000000000000000 a __fini_array_end
0000000000000000 a __fini_array_start
w __gmon_start__
0000000000000000 a __init_array_end
0000000000000000 a __init_array_start
00000000004003a0 T __libc_csu_fini
00000000004003b0 T __libc_csu_init
U __libc_start_main
0000000000000000 a __preinit_array_end
0000000000000000 a __preinit_array_start
0000000000401980 A _edata
0000000000401994 A _end
0000000000400494 T _fini
000000000040047c T _init
0000000000400220 T _start
000000000040024c t call_gmon_start
0000000000401980 b completed.6118
0000000000401788 W data_start
0000000000400270 t deregister_tm_clones
0000000000401988 b dtor_idx.6120
0000000000401994 A end
0000000000400350 t frame_dummy
0000000000401990 B g_my_num
0000000000400390 T main
00000000004002a0 t register_tm_clones

注意事项:

  • 我们的函数 f()main()T 类型(代表“TEXT” - 用于只读非- 零内存内容,无论它实际上是文本还是其他数据或可执行代码),
  • g_my_numB 是一个具有隐式归零内存的全局变量,而
  • NS::ns_my_numD,因为可执行文件必须显式提供值 2 以占用该内存。

man/info-page for nm进一步记录这些事情......

关于c++ - gcc -g :what will happen,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/5179202/

27 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com