diff options
author | Arjan van de Ven <arjan@linux.intel.com> | 2008-01-25 15:08:33 -0500 |
---|---|---|
committer | Ingo Molnar <mingo@elte.hu> | 2008-01-25 15:08:33 -0500 |
commit | e14af7eeb47ea96c52741c5e5fa010d33daf6973 (patch) | |
tree | 0b4c1af86e766726ba75873812715706e4044086 /kernel | |
parent | 21aa9280b9f4e9e68d3fa8990df6c9d7fd71f994 (diff) |
debug: track and print last unloaded module in the oops trace
Based on a suggestion from Andi:
In various cases, the unload of a module may leave some bad state around
that causes a kernel crash AFTER a module is unloaded; and it's then hard
to find which module caused that.
This patch tracks the last unloaded module, and prints this as part of the
module list in the oops trace.
Right now, only the last 1 module is tracked; I expect that this is enough
for the vast majority of cases where this information matters; if it turns
out that tracking more is important, we can always extend it to that.
[ mingo@elte.hu: build fix ]
Signed-off-by: Arjan van de Ven <arjan@linux.intel.com>
Signed-off-by: Ingo Molnar <mingo@elte.hu>
Diffstat (limited to 'kernel')
-rw-r--r-- | kernel/module.c | 6 |
1 files changed, 6 insertions, 0 deletions
diff --git a/kernel/module.c b/kernel/module.c index 5bbf225ca07a..1bb4c5e0d56e 100644 --- a/kernel/module.c +++ b/kernel/module.c | |||
@@ -496,6 +496,8 @@ static struct module_attribute modinfo_##field = { \ | |||
496 | MODINFO_ATTR(version); | 496 | MODINFO_ATTR(version); |
497 | MODINFO_ATTR(srcversion); | 497 | MODINFO_ATTR(srcversion); |
498 | 498 | ||
499 | static char last_unloaded_module[MODULE_NAME_LEN+1]; | ||
500 | |||
499 | #ifdef CONFIG_MODULE_UNLOAD | 501 | #ifdef CONFIG_MODULE_UNLOAD |
500 | /* Init the unload section of the module. */ | 502 | /* Init the unload section of the module. */ |
501 | static void module_unload_init(struct module *mod) | 503 | static void module_unload_init(struct module *mod) |
@@ -719,6 +721,8 @@ sys_delete_module(const char __user *name_user, unsigned int flags) | |||
719 | mod->exit(); | 721 | mod->exit(); |
720 | mutex_lock(&module_mutex); | 722 | mutex_lock(&module_mutex); |
721 | } | 723 | } |
724 | /* Store the name of the last unloaded module for diagnostic purposes */ | ||
725 | sprintf(last_unloaded_module, mod->name); | ||
722 | free_module(mod); | 726 | free_module(mod); |
723 | 727 | ||
724 | out: | 728 | out: |
@@ -2503,6 +2507,8 @@ void print_modules(void) | |||
2503 | printk("Modules linked in:"); | 2507 | printk("Modules linked in:"); |
2504 | list_for_each_entry(mod, &modules, list) | 2508 | list_for_each_entry(mod, &modules, list) |
2505 | printk(" %s%s", mod->name, module_flags(mod, buf)); | 2509 | printk(" %s%s", mod->name, module_flags(mod, buf)); |
2510 | if (last_unloaded_module[0]) | ||
2511 | printk(" [last unloaded: %s]", last_unloaded_module); | ||
2506 | printk("\n"); | 2512 | printk("\n"); |
2507 | } | 2513 | } |
2508 | 2514 | ||