Почему отсутствуют некоторые символы отладки и как их отслеживать?
В настоящее время я отлаживаю модуль Kernel и с этой целью собрал все ядро с отладочной информацией (выдает kallsyms и т. Д.).
Когда я пытаюсь nm my_module.ko
Я получаю список символов, включенных в мой модуль. Все в порядке, за исключением того, что некоторые символы отсутствуют, поскольку они не отображаются в списке символов. Мне кажется, что связанные функции автоматически включаются.
В любом случае, когда я запускаю ядро с помощью qemu-kgdb/gdb, я вижу, что вызывается "отсутствующая" функция. Это означает, что компилятор не уничтожил его, потому что он никогда не использовался ни в каком пути кода (отсюда мое "чувство").
Поскольку символ не появляется, я не могу установить точку останова на нем, и GDB не развернет его, чтобы я мог видеть путь к исполняемому коду - понимаю, я не знаю, как сказать GDB, чтобы развернуть его.
К сожалению, я хочу увидеть эту часть пути кода... Как я могу это сделать?
РЕДАКТИРОВАТЬ: Как предложено в ответе Тома, я попытался использовать file:line
синтаксис как ниже:
Мой кодовый файл выглядит так:
int foo(int arg) // The function that I suspect to be inlined - here is line 1
{
/* Blabla */
return 42;
}
void foo2(void)
{
foo(0); // Line 9
}
Я старался b file.c:1
и точка останова была поражена, но foo()
функция не развернута. Конечно, я создаю символы отладки, так как я также установил точку останова на foo2
чтобы проверить, что случилось (что работало хорошо).
2 ответа
Вы не говорите, какую версию GDB вы используете.
Очень старые версии GDB не поддерживают встроенные функции. Это было верно для 6,8 и, возможно, даже 7,0 - я не помню. Вы можете посмотреть файл NEWS для вашего GDB, чтобы увидеть.
Затем были некоторые версии GDB, которые поддерживали точки останова для встроенных функций, но только с использованием синтаксиса "file:line". Итак, что вы должны сделать, это найти функцию в вашем редакторе, найти ее номер строки и ввести, например:
(gdb) break myfile.c:777
Даже более поздние версии GDB, начиная с 7.4 или 7.5 (я забыл), будут прекрасно обрабатывать "функцию разрыва", если "функция" была встроена.
Все это работает, только если у вас есть debuginfo. Так что, если вы попробовали это, и это не сработало, либо у вас более старый GDB, либо вы забыли использовать -g.
В gdb нет хорошего способа увидеть, какие объекты в компиляции отсутствовали -g. Вы можете легко увидеть это из оболочки, запустив "readelf -WS" для файлов.o и ища файлы, у которых нет раздела.debug_info.
Установка точки останова для строки подписи функции не сработала. Но установка в строку инструкции встроенной функции решила проблему для меня. Например, учитывая следующую функцию inline_foo
, найденный в myfile.c:
inline int inline_foo(int arg) // l.1
{
int a_var = 0;
do_smth(&a_var);
do_some_other_thing(); // l.5
if (a_var) {
a_var = blob();
} else {
a_var = blub();
return a_var; // l.10
}
я пытался b myfile.c:1
, который, казалось, не работал. Но если бы я попытался b myfile.c:3
вместо этого точка останова была хорошо обработана GDB. Поскольку метод такой же, как описанный ранее Томом, я приму его ответ.