linux - usan - signos de puntuacion
¿Cuál es el significado de los signos de interrogación? en Linux kernel panic call traces? (1)
El rastreo de llamadas contiene entradas como esa:
[<deadbeef>] FunctionName+0xAB/0xCD [module_name]
[<f00fface>] ? AnotherFunctionName+0x12/0x40 [module_name]
[<deaffeed>] ClearFunctionName+0x88/0x88 [module_name]
¿Cuál es el significado de ''?'' marcar antes de AnotherFunctionName?
''?'' significa que la información sobre esta entrada de pila probablemente no sea confiable.
El mecanismo de salida de la pila (ver la implementación de la función dump_trace () ) no pudo probar que la dirección que ha encontrado es una dirección de retorno válida en la pila de llamadas.
''?'' a sí mismo es printk_stack_address() por printk_stack_address() .
La entrada de la pila puede ser válida o no. A veces uno puede simplemente saltárselo. Puede ser útil investigar el desmontaje del módulo involucrado para ver a qué función se llama en ClearFunctionName+0x88
(o, en x86, inmediatamente antes de esa posición).
En cuanto a la fiabilidad
En x86, cuando se llama a dump_stack (), la función que realmente examina la pila es print_context_stack() definida en arch/x86/kernel/dumpstack.c
. Eche un vistazo a su código, intentaré explicarlo a continuación.
Supongo que las instalaciones de desenrollado de pila DWARF2 no están disponibles en su sistema Linux (lo más probable es que no lo estén, si no es OpenSUSE o SLES). En este caso, print_context_stack()
parece hacer lo siguiente.
Comienza desde una dirección (variable de ''pila'' en el código) que se garantiza que sea una dirección de una ubicación de pila. En realidad, es la dirección de una variable local en dump_stack()
.
La función incrementa repetidamente esa dirección ( while (valid_stack_ptr ...) { ... stack++}
) y comprueba si lo que apunta también podría ser una dirección en el código del kernel ( if (__kernel_text_address(addr)) ...
). De esta manera, intenta encontrar las direcciones de retorno de las funciones puestas en la pila cuando estas funciones fueron llamadas.
Por supuesto, no todos los valores largos sin firmar que parecen una dirección de retorno son en realidad una dirección de retorno. Así que la función intenta comprobarlo. Si se usan punteros de marco en el código del kernel (los registros% ebp /% rbp se emplean para eso si se configura CONFIG_FRAME_POINTER), se pueden usar para recorrer los marcos de pila de las funciones. La dirección de retorno de una función se encuentra justo encima del puntero del cuadro (es decir, en %ebp/%rbp + sizeof(unsigned long)
). print_context_stack comprueba exactamente eso.
Si hay un marco de pila al que apunta el valor ''pila'' es la dirección de retorno, el valor se considera una entrada de pila confiable. ops->address
se llamará para ello con reliable == 1
, eventualmente llamará a printk_stack_address()
y el valor se emitirá como una entrada confiable de la pila de llamadas. De lo contrario la dirección será considerada poco confiable. Será salida de todos modos pero con ''?'' antepuesto
[NB] Si la información del puntero de marco no está disponible (por ejemplo, como en Debian 6 de forma predeterminada), todas las entradas de la pila de llamadas se marcarán como no confiables por este motivo.
Los sistemas con soporte de desenrollado DWARF2 (y con el conjunto CONFIG_STACK_UNWIND) son una historia completamente diferente.