J'ai une question sur assert()
sous Linux: puis-je l'utiliser dans le noyau?
Si non, quelles techniques utilisez-vous habituellement si, par exemple, je ne veux pas entrer le pointeur NULL?
Les macros du noyau correspondantes sont BUG_ON
et WARN_ON
. Le premier est pour quand vous voulez faire paniquer le noyau et arrêter le système (c'est-à-dire une erreur irrécupérable). Ce dernier est pour quand vous voulez enregistrer quelque chose dans le journal du noyau (visible via dmesg
).
Comme le dit @Michael, dans le noyau, vous devez valider tout ce qui vient de l'espace utilisateur et juste le gérer, quel qu'il soit. BUG_ON et WARN_ON doivent détecter des bogues dans votre propre code ou des problèmes avec le matériel.
Une option serait d'utiliser la macro BUG_ON()
. Il va printk
un message, puis panic()
(c'est-à-dire planter) le noyau.
http://kernelnewbies.org/KernelHacking-HOWTO/Debugging_Kernel
Bien sûr, cela ne doit être utilisé que comme stratégie de gestion des erreurs de dernier recours (tout comme assert
) ...
Non. Sauf si vous travaillez sur le noyau du noyau et plutôt sur un module, vous devriez faire de votre mieux pour ne jamais planter (techniquement, abort()
) le noyau. Si vous ne voulez pas utiliser un pointeur NULL, juste ne le faites pas . Vérifiez-le avant de l'utiliser et produisez un journal des erreurs s'il l'est.
La chose la plus proche que vous - pourriez-vous vouloir faire si vous gérez réellement un cas fatal est la fonction panic()
ou BUG_ON
et WARN_ON
macros, qui abandonneront l'exécution et produiront des messages de diagnostic, une trace de pile et une liste de modules.
Eh bien, le déréférencement d'un pointeur nul produira un oups, que vous pouvez utiliser pour trouver le code incriminé. Maintenant, si vous voulez affirmer () une condition donnée, vous pouvez utiliser
BUG_ON(condition)
Un mécanisme moins mortel est WARN_ON, qui produira une trace arrière sans planter le noyau.
J'utilise cette macro, elle utilise BUG () mais ajoute quelques informations que j'utilise normalement pour le débogage, et bien sûr, vous pouvez la modifier pour inclure plus d'informations si vous le souhaitez:
#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)
BUG_ON()
est l'approche appropriée pour le faire. Il vérifie que la condition est vraie et appelle la macro BUG()
.
La manière dont BUG()
gère le reste est très bien expliquée dans l'article suivant: