Это вроде правильно, но не полностью. -g
запрашивает, чтобы компилятор и компоновщик генерировали и сохраняли информацию об отладке / символах на уровне исходного кода в самом исполняемом файле.
Если ...
- в дальнейшем происходит сбой программы и создается файл ядра (что указывает на некоторую проблему в реальном коде), или
- преднамеренная команда ОС принудительно привела его к ядру (например,
kill -SIGQUIT
pid ) или
- программа вызывает функцию, которая создает дамп ядра (например,
abort
)
... - ни один из которых на самом деле не вызван использованием -g
- тогда отладчик будет знать, как прочитать эту символьную информацию "-g
" из исполняемого файла и сопоставить ее с ядром. Это означает, что вы можете видеть правильные имена переменных и функций в ваших стековых фреймах, получать номера строк и видеть источник при переходе в исполняемый файл.
Эта отладочная информация полезна при отладке - начинаете ли вы с ядра или только с исполняемого файла. Это даже помогает получить лучший результат от таких команд, как pstack
.
Обратите внимание, что в вашей среде могут быть другие настройки для управления генерацией ядер (они могут быть большими, и нет общего способа узнать, можно ли / когда их удалить, поэтому они не всегда нужны). Например, в оболочках UNIX / LINUX это часто ulimit -c
.
Вам также может быть интересно прочитать о DWARF Википедии - широко используемом формате отладочной информации для кодирования встроенной информации отладки / символов в исполняемых / библиотечных объектах (например, в UNIX и Linux).
ОБНОВЛЕНИЕ по запросу Виктора в комментариях ...
Информация о символах перечисляет идентификаторы из исходного кода (обычно только после любого искажения имени необходимых), адреса / смещения (виртуальной) памяти, при которых они будут загружены в память процесса, тип (например, данные против кода). Например ...
$ 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
(что означает «ТЕКСТ» - используется для ненулевого содержимого памяти, доступного только для чтения, будь то текст, другие данные или исполняемый код), * 1057 *
g_my_num
- это B
глобал с неявно обнуленной памятью, в то время как
NS::ns_my_num
равно D
, поскольку исполняемый файл должен явно предоставить значение 2
, чтобы занять эту память.
Страница man / info для nm
документирует эти вещи дальше ...