Я отлаживаю с помощью дампов ядра, и обратите внимание, что gdb требует, чтобы вы предоставили как исполняемый файл, так и дамп ядра. Почему это? Если дамп ядра содержит всю память, используемую процессом, разве исполняемый файл не содержится в дампе ядра? Возможно, нет никакой гарантии, что весь exe загружен в память (хотя отдельные исполняемые файлы обычно не такие большие), или, может быть, дамп ядра не содержит всей необходимой памяти? Это для символов (возможно, они не загружаются в память нормально)?
11
Ответы:
Дамп ядра - это просто дамп памяти вашей программы, если вы знаете, где все было, вы можете просто использовать это.
Вы используете исполняемый файл, потому что он объясняет, где (в терминах логических адресов) вещи находятся в памяти, то есть в файле ядра.
Если вы используете команду,
objdump
она выдаст метаданные об исполняемом объекте, который вы исследуете. Используя в качестве примера исполняемый объект с именем a.out.objdump -h a.out
выводит только информацию заголовка, вы увидите разделы с именем например. .data или .bss или .text (их намного больше). Они информируют загрузчик ядра о том, где в объекте можно найти различные разделы и где в адресном пространстве процесса следует загрузить раздел, а для некоторых разделов (например, .data .text), что следует загрузить. (Раздел .bss не содержит никаких данных в файле, но относится к объему памяти, который резервируется в процессе для неинициализированных данных, он заполнен нулями).Компоновка исполняемого объектного файла соответствует стандарту ELF.
objdump -x a.out
- сбрасывает всеЕсли исполняемый объект все еще содержит свои таблицы символов (он не был удален -
man strip
и вы использовали-g
генерацию отладки дляgcc
предположения компиляции источника переменного тока), то вы можете проверить содержимое ядра по именам символов, например, если у вас была переменная / буфер с именем inputLine в вашем исходном коде, вы можете использовать это имяgdb
для просмотра его содержимого. то естьgdb
будет знать смещение от начала сегмента данных, инициализированных вашими программами, где начинается inputLine, и длину этой переменной.Дальнейшее чтение Article1 , статья 2 , и вшивый песчаный Исполняемые и Linking Format (ELF) спецификации .
Обновление после комментария @mirabilos ниже.
Но если использовать таблицу символов, как в
Производит
а затем не использовать таблицу символов и исследовать адрес непосредственно в,
Производит
Я проверил память напрямую, не используя таблицу символов во 2-й команде.
Я также вижу, что ответ @ user580082 дополняет объяснение и будет способствовать голосованию.
источник
Основной файл представляет собой снимок образа стека, отображений памяти и регистров во время завершения процесса. Содержанием которого можно манипулировать, как указано на основной странице man . По умолчанию частные сопоставления, общие сопоставления и информация заголовка ELF выгружаются в основной файл.
Что касается вашего вопроса , то причина, по которой gdb требуется исполняемый файл, заключается в том, что он не имитирует выполнение, читая и интерпретируя двоичные инструкции, как это делает valgrind, вместо этого он становится родителем процесса, чтобы контролировать поведение процесса во время выполнения. время. Он использует файл ядра для определения отображений памяти и состояния процессора во время сбоя.
В Linux родительские процессы могут получать дополнительную информацию о своих дочерних элементах, в частности возможность отслеживать их, что позволяет отладчику получать доступ к низкоуровневой информации процесса, такой как чтение / запись в его памяти, регистры, изменение отображений сигналов, остановка его выполнения и т. Д.
Вы поймете требование к исполняемому файлу, несмотря на наличие файла core еще раз, прочитав, как работает любой отладчик.
источник
(в дополнение к другим хорошим ответам)
В современных системах Linux (и многих Unix-подобных) информация об отладке (включая метаданные о типах символов, расположении исходного кода, типе переменных и т. Д. И т. Д.) Находится в формате DWARF и находится внутри исполняемого файла ELF ( или ELF разделяемые библиотеки), когда он компилируется с какой-либо
-g
опцией. Я рекомендую отлаживать компиляцию программ-g3 -O0
и, возможно,-fno-inline
при использовании недавнего GCC ; однако, с GCC вы можете даже скомпилировать как информацию об оптимизации, так и информацию отладки, например, с помощью-O2 -g1
, хотя информация отладки в этом случае может быть немного «нечеткой» (это может немного помочь поймать некоторых непослушных гейзенбагов ).Разумно избегать помещения этой информации в основные файлы, поскольку у вас может быть много разных основных файлов (представьте себе широко используемое программное обеспечение, в котором многие пользователи создают отчеты об ошибках, большинство из которых имеют
core
дамп) для одного и того же исполняемого файла. Также файлы core (5) выгружаются ядром, которому не нужно заботиться о существовании разделов DWARF в исполняемых файлах elf (5) (поскольку эти разделы не отображаются в виртуальное адресное пространство ошибочного процесса, который выгружал ядро по некоторому сигналу ( 7) ). Существует даже возможность размещения отладочной информации в отдельных файлах (вне исполняемого файла).Кстати, GDB может быть болезненно используются для отладки ядра свалки для исполняемых файлов без какой - либо информации отладки. Но затем вы практически отлаживаете на уровне машинного кода (не на символическом уровне, обеспечиваемом языками программирования и их компиляторами).
источник