Así que estoy tratando de averiguar qué procesos del núcleo están llamando a algunas funciones en un controlador de bloque. Pensé que incluir backtrace() en la biblioteca de C lo haría más fácil. Pero estoy teniendo problemas para cargar la traza inversa.¿Cómo incluir C backtrace en un código de módulo kernel?
Copié esta función ejemplo para mostrar la traza inversa:
http://www.linuxjournal.com/files/linuxjournal.com/linuxjournal/articles/063/6391/6391l1.html
Todos los intentos para compilar tiene error en uno u otro lugar que un archivo no se puede encontrar o que las funciones no están definidos.
Esto es lo que viene más cerca.
En el Makefile puse las directivas del compilador:
-rdynamic -I/usr/include
Si dejo a cabo la segunda, -I/usr/include, el compilador informa de que no puede encontrar el execinfo.h cabecera requerida.
A continuación, en el código donde yo quiero hacer la traza He copiado la función del ejemplo:
//trying to include the c backtrace capability
#include <execinfo.h>
void show_stackframe() {
void *trace[16];
char **messages = (char **)NULL;
int i, trace_size = 0;
trace_size = backtrace(trace, 16);
messages = backtrace_symbols(trace, trace_size);
printk(KERN_ERR "[bt] Execution path:\n");
for (i=0; i<trace_size; ++i)
printk(KERN_ERR "[bt] %s\n", messages[i]);
}
//backtrace function
He puesto la llamada a esta función más adelante, en una función de controlador de bloque en el que el el primer signo del error ocurre. Simplemente:
show_stackframe();
Así que cuando compilo, los siguientes errores:
[email protected]:~/2.6-32$ make -s
Invoking make againt the kernel at /lib/modules/2.6.32-5-686/build
In file included from /usr/include/features.h:346,
from /usr/include/execinfo.h:22,
from /home/linux/2.6-32/block/block26.c:49:
/usr/include/sys/cdefs.h:287:1: warning: "__always_inline" redefined
In file included from /usr/src/linux-headers-2.6.32-5-common/include/linux/compiler-gcc.h:86,
from /usr/src/linux-headers-2.6.32-5-common/include/linux/compiler.h:40,
from /usr/src/linux-headers-2.6.32-5-common/include/linux/stddef.h:4,
from /usr/src/linux-headers-2.6.32-5-common/include/linux/list.h:4,
from /usr/src/linux-headers-2.6.32-5-common/include/linux/module.h:9,
from /home/linux/2.6-32/inc/linux_ver.h:40,
from /home/linux/2.6-32/block/block26.c:32:
/usr/src/linux-headers-2.6.32-5-common/include/linux/compiler-gcc4.h:15:1: warning: this is the location of the previous definition
/home/linux/2.6-32/block/block26.c:50: warning: function declaration isn’t a prototype
WARNING: "backtrace" [/home/linux/2.6-32/ndas_block.ko] undefined!
WARNING: "backtrace_symbols" [/home/linux/2.6-32/ndas_block.ko] undefined!
Nota: block26.c es el archivo Tengo la esperanza de obtener la traza de.
¿Hay alguna razón obvia por la que backtrace y backtrace_symbols permanezcan indefinidos cuando se compilan en los módulos .ko?
Lo adivino porque uso el compilador incluye execinfo.h que reside en la computadora y no se carga en el módulo.
Es mi conjetura inculta por decir lo menos.
¿Alguien puede ayudar a que las funciones de seguimiento se carguen en el módulo?
Gracias por mirar esta investigación.
Estoy trabajando en Debian. Cuando saco la función y tal, el módulo compila bien y casi funciona perfectamente.
De ndasusers
No estoy tan seguro de que deba incluir bibliotecas como esta en el código del módulo kernel. ¿Has intentado simplemente usar gdb y establecer un punto de ruptura? [1] [1]: http://www.xml.com/ldd/chapter/book/ch04.html#t5 – zdav
¡Oh, ratas! Tenía miedo de escuchar algo así. Este parece un capítulo útil al que me has vinculado. Gracias por eso. – ndasusers
A diferencia de los programas de espacio de usuario, el kernel no está vinculado a la biblioteca C estándar (ni a ninguna otra biblioteca, para el caso). http://kernelnewbies.org/FAQ/LibraryFunctionsInKernel – jschmier