Подтвердить что ты не робот

В чем смысл вопросительных знаков? в ядре ядра паника вызывает трассировки?

Трассировка вызова содержит такие записи:

 [<deadbeef>] FunctionName+0xAB/0xCD [module_name]
 [<f00fface>] ? AnotherFunctionName+0x12/0x40 [module_name]
 [<deaffeed>] ClearFunctionName+0x88/0x88 [module_name]

В чем смысл "?" значить перед AnotherFunctionName?

4b9b3361

Ответ 1

'?' означает, что информация об этой записи стека, вероятно, не является надежной.

Механизм вывода стека (см. реализацию функция dump_trace()) не смог доказать, что найденный им адрес является действительным возвратом адрес в стеке вызовов.

'?' сам выводится printk_stack_address().

Запись стека может быть действительной или нет. Иногда можно просто пропустить его. Может быть полезно исследовать разборку задействованного модуля, чтобы увидеть, какая функция вызывается в ClearFunctionName+0x88 (или, на x86, непосредственно перед этой позицией).

Что касается надежности

В x86, когда вызывается dump_stack(), функция, которая фактически проверяет стек, print_context_stack(), определенная в arch/x86/kernel/dumpstack.c. Взгляните на его код, я попытаюсь объяснить это ниже.

Я предполагаю, что в вашей системе Linux недоступны средства для удаления стека DWARF2 (скорее всего, это не так, если это не OpenSUSE или SLES). В этом случае print_context_stack(), похоже, делает следующее.

Он начинается с адреса (переменной "stack" в коде), который гарантированно является адресом местоположения стека. Фактически это адрес локальной переменной в dump_stack().

Функция неоднократно увеличивает этот адрес (while (valid_stack_ptr ...) { ... stack++}) и проверяет, может ли то, на что он указывает, быть адресом в коде ядра (if (__kernel_text_address(addr)) ...). Таким образом, он пытается найти возвращаемые адреса функций, нажатые на стек, когда эти функции были вызваны.

Конечно, не каждое беззнаковое длинное значение, которое выглядит как обратный адрес, на самом деле является обратным адресом. Поэтому функция пытается проверить это. Если указатели рамки используются в коде ядра (для этого используются регистры% ebp/% rbp, если установлено CONFIG_FRAME_POINTER), они могут использоваться для перемещения кадров стека функций. Обратный адрес для функции находится чуть выше указателя кадра (т.е. В %ebp/%rbp + sizeof(unsigned long)). print_context_stack проверяет именно это.

Если существует стек стека, для которого значение "стек" указывает на обратный адрес, значение считается надежной записью стека. ops->address будет вызван для него с помощью reliable == 1, он в конечном итоге вызовет printk_stack_address(), и значение будет выводиться как запись надежного стека вызовов. В противном случае адрес будет считаться ненадежным. Он будет выводиться в любом случае, но с '?' предваряется.

[NB] Если информация указателя кадра недоступна (например, как это было в Debian 6 по умолчанию), все записи стека вызовов будут помечаться как ненадежные по этой причине.

Системы с поддержкой разворота DWARF2 (и с набором CONFIG_STACK_UNWIND) - это еще одна история.