Usando aserción en el kernel de Linux


Tengo una pregunta sobre assert() en Linux: ¿puedo usarla en el núcleo?

Si no, ¿qué técnicas utilizas normalmente si, por ejemplo, no quiero introducir puntero NULO?

Author: Mateusz Piotrowski, 2011-06-15

6 answers

Las macros correspondientes del núcleo son BUG_ON y WARN_ON. El primero es para cuando se quiere hacer que el kernel entre en pánico y derribar el sistema (es decir, un error irrecuperable). Este último es para cuando desea registrar algo en el registro del kernel (visible a través de dmesg).

Como dice @Michael, en el núcleo, necesitas validar cualquier cosa que venga del espacio de usuario y simplemente manejarlo, sea lo que sea. BUG_ON y WARN_ON son para atrapar errores en su propio código o problemas con el hardware.

 39
Author: Nemo,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2011-06-15 14:58:54

Una opción sería usar la macro BUG_ON(). Será printk un mensaje, y luego panic() (es decir, se bloqueará) el núcleo.

Http://kernelnewbies.org/KernelHacking-HOWTO/Debugging_Kernel

Por supuesto, esto solo debe usarse como una estrategia de manejo de errores de último recurso (al igual que assert)...

 7
Author: sleske,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2011-06-15 14:58:31

No. A menos que esté trabajando en el núcleo del núcleo y más bien en un módulo, debería hacer todo lo posible para nunca bloquear (técnicamente, abort()) el núcleo. Si no quieres usar un puntero NULO, simplemente no lo hagas. Compruébelo antes de usarlo, y produzca un registro de errores si lo es.

Lo más cercano que podría querer hacer si realmente está manejando un caso fatal es el panic() función o las macros BUG_ON y WARN_ON, que abortarán la ejecución y producirán diagnóstico mensajes, un seguimiento de pila y una lista de módulos.

 5
Author: Michael Foukarakis,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2011-06-15 15:02:59

Bueno, desreferenciar puntero nulo producirá un oops, que puede usar para encontrar el código ofensivo. Ahora, si desea afirmar() una condición dada, puede usar

BUG_ON(condition)

Un mecanismo menos letal es WARN_ON, que producirá una traza inversa sin que se bloquee el núcleo.

 4
Author: shodanex,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2011-06-15 15:02:40

BUG_ON() es el enfoque apropiado para hacerlo. Comprueba que la condición sea verdadera y llama a la macro BUG().

Cómo BUG() maneja el resto se explica muy bien en el siguiente artículo:

Http://kernelnewbies.org/FAQ/BUG

 0
Author: krazycoder,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2012-05-16 21:26:54

Uso esta macro, usa BUG() pero agrega algo más de información que normalmente uso para depurar, y por supuesto puedes editarla para incluir más información si lo deseas:

#define ASSERT(x)                                                       \
do {    if (x) break;                                                   \
        printk(KERN_EMERG "### ASSERTION FAILED %s: %s: %d: %s\n",      \
               __FILE__, __func__, __LINE__, #x); dump_stack(); BUG();  \
} while (0)
 0
Author: LIUB,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2012-12-28 22:35:17