Что означает вопросительный знак?"в ядре Linux следы панического вызова?

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

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

что означает '?- Марк перед другим именем?

1 ответов


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

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

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

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

по поводу надежности

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

Я полагаю, DWARF2 очистки стека объекты не доступно в вашей системе Linux (скорее всего, их нет, если это не 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 проверяет именно это.

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

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

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