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?
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.
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
)...
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.
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.
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:
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)
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