[英]gcc -g :what will happen
我在接受采訪時問了這個問題。
他們問我如何生成我可以調試的核心轉儲文件。 然后我說用gcc
-g
標志我們可以做到。
然后他們問我-g
標志對編譯器的確切作用。
我說(可能是一個錯誤的答案)它會打開核心文件中可用於調試的所有符號。
任何人都可以告訴我它到底是做什么的?
這是正確的,但不完整。 -g
請求編譯器和鏈接器在可執行文件本身中生成並保留源級調試/符號信息。
如果 ...
kill -SIGQUIT
pid ),或者 abort
) ...-其中沒有一個實際上是由使用-g
引起的 - 然后調試器將知道如何從可執行文件中讀取“ -g
”符號信息並將其與核心進行交叉引用。 這意味着您可以在堆棧框架中查看變量和函數的正確名稱,獲取行號並在可執行文件中徘徊時查看源代碼。
調試時,調試信息非常有用 - 無論是以核心還是僅從可執行文件開始。 它甚至可以幫助從pstack
命令中獲得更好的輸出。
請注意,您的環境可能有其他設置來控制是否生成核心(它們可能很大,並且沒有一般方法可以知道是否/何時可以刪除它們,因此並不總是需要它們)。 例如,在UNIX / LINUX shell上,它通常是ulimit -c
。
您可能還有興趣閱讀DWARF Wikipedia - 一種常用的調試信息格式,用於編碼可執行文件/庫對象中的嵌入式調試/符號信息(例如,在UNIX和Linux上)。
根據Victor的評論請求更新......
符號信息列出源代碼中的標識符(通常僅在需要任何名稱修改之后),它們將被加載到進程存儲器中的(虛擬)存儲器地址/偏移量,類型(例如數據與代碼)。 例如...
$ 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_num
是B
是一個具有隱式零值內存的全局內存,而 NS::ns_my_num
是D
因為可執行文件必須顯式提供值2
來占用該內存。 nm
的man / info- pages進一步記錄了這些東西......
-g標志告訴編譯器生成調試信息。 它對是否生成核心文件沒有影響。 在大多數類似unix的系統上,可以使用ulimit命令進行設置。
gcc -g標志告訴gcc生成並嵌入調試信息。 ulimit -c
用於啟用核心文件生成。 沒有另一個,你可以擁有其中任何一個。
-g
將調試信息(變量名,行號等)添加到可執行文件中。 這是您需要做的事情的一部分,以便能夠理解核心文件。
http://gcc.gnu.org/onlinedocs/gcc/Debugging-Options.html#Debugging-Options
當該過程接收到信號時,核心轉儲是過程的默認動作之一,例如標准信號“SIGQUIT”,“SIGILL”,“SIGABRT”,“SIGFPE”,“SIGSEGV”。 但是,大多數shell都會抑制核心文件的創建,因為核心文件往往很大,可能需要一些時間或大量時間。
為了啟用核心生成,“ulimit”是可用於設置shell或其子進程的文件限制的實用程序。
編譯器標志“-g”或僅與編譯器有關的任何內容。 從邏輯上講,它與核心轉儲無關。
如果你沒有放-g標志,就不能在gdb中調用列表來列出源代碼的樣子。 它將顯示“沒有加載符號表。使用”file“命令。”
此外,如果你鍵入info func或info frame,gdb中的信息本地,沒有-g它將不顯示返回數據類型及其參數,基本上沒有指令轉換為變量(從符號表映射)。
在分段錯誤或此類異常上生成核心文件。 gdb source.cc core
是查看核心文件的一種方法。 回溯和調查每一幀是開始研究核心。 -g
在二進制文件中添加調試符號。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.