crash_mod/0002755000130300001450000000000011410411134013034 5ustar jwesselftpadmincrash_mod/test_panic.c0000744000130300001450000002023011410410373015331 0ustar jwesselftpadmin/* * Copyright (c) 2005-2010 Wind River Systems, Inc. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 as * published by the Free Software Foundation. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. * See the GNU General Public License for more details. */ #include #include #include #include #include #include #include #include #include #include #include #include #include #include #define LOCAL_MODULE_VERSION "1.0" #define MODULE_NAME "test_panic" #define DEAD_ADDRESS 0xdeadbeef static struct proc_dir_entry *panic_dir; static struct proc_dir_entry *panic_file; static struct proc_dir_entry *bad_kfree_file; static struct proc_dir_entry *bad_access_file; static struct proc_dir_entry *deep_panic_file; static struct proc_dir_entry *deep_bug_file; static struct proc_dir_entry *bug_file; static struct proc_dir_entry *hang_file; static struct proc_dir_entry *disableirq_file; static int no_crash_here; static int bug_write(struct file *file, const char *buffer, unsigned long count, void *data) { printk(KERN_INFO "Starting BUG\n"); if (!no_crash_here) BUG(); return count; } static int hang_write(struct file *file, const char *buffer, unsigned long count, void *data) { printk(KERN_INFO "going to sleep for 11 seconds with irq disabled\n"); local_irq_disable(); local_irq_disable(); /* Sleep and locking experiments */ /* write_lock_irq(&tasklist_lock); */ printk("Disable local irq for 11 seconds\n"); mdelay(11000); /* write_unlock_irq(&tasklist_lock); */ local_irq_enable(); mdelay(1000); cpu_relax(); return count; } int test_panic_recover = 0; int deep_bug_test_panic = 0; noinline void deep01(void) { printk(KERN_CRIT "Deep crash\n"); if (deep_bug_test_panic) panic("Hard panic in deep trace"); else BUG(); } noinline void deep02(void) { deep01(); } noinline void deep03(void) { deep02(); } noinline void deep04(void) { deep03(); } noinline void deep05(void) { deep04(); } noinline void deep06(void) { deep05(); } noinline void deep07(void) { deep06(); } noinline void deep08(void) { deep07(); } noinline void deep09(void) { deep08(); } noinline void deep10(void) { deep09(); } noinline void deep11(void) { deep10(); } noinline void deep12(void) { deep11(); } noinline void deep13(void) { deep12(); } noinline void deep14(void) { deep13(); } noinline void deep15(void) { deep14(); } noinline void deep16(void) { deep15(); } noinline void deep17(void) { deep16(); } noinline void deep18(void) { deep17(); } noinline void deep19(void) { deep18(); } noinline void deep20(void) { deep19(); } noinline void deep21(void) { deep20(); } noinline void deep22(void) { deep21(); } noinline void deep23(void) { deep22(); } noinline void deep24(void) { deep23(); } noinline void deep25(void) { deep24(); } static int deep_panic_write(struct file *file, const char *buffer, unsigned long count, void *data) { deep_bug_test_panic = 1; deep25(); return 0; } static int deep_bug_write(struct file *file, const char *buffer, unsigned long count, void *data) { deep_bug_test_panic = 0; deep25(); return 0; } static int disableirq_write(struct file *file, const char *buffer, unsigned long count, void *data) { printk(KERN_INFO "irq disable\n"); local_irq_disable(); while (1); local_irq_enable(); return 0; } /* called when someone writes to the proc file. trigger a panic here */ static int bad_kfree_write(struct file *file, const char *buffer, unsigned long count, void *data) { printk(KERN_INFO "Starting bad kfree\n"); kfree((void *)1); return count; } static int test_panic_counter; static int *tp_address_ref = &test_panic_counter; static void create_bad_access(void) { trace_printk("create_bad_access() does bad things!\n"); tp_address_ref = (int *)DEAD_ADDRESS; } static int bad_access_write(struct file *file, const char *buffer, unsigned long count, void *data) { create_bad_access(); printk(KERN_INFO "Starting bad memory write\n"); *tp_address_ref = 1; return count; } static int panic_write(struct file *file, const char *buffer, unsigned long count, void *data) { trace_printk("Starting panic\n"); printk(KERN_INFO "Starting panic\n"); panic("test_panic running!\n"); return count; } static int __init test_panic_init(void) { int rc = -ENOMEM; trace_printk("Running test_panic_init()"); /* create directory */ panic_dir = proc_mkdir(MODULE_NAME, NULL); if(!panic_dir) return rc; trace_printk("test_panic: Building panic\n"); panic_file = create_proc_entry("panic", 0600, panic_dir); if(!panic_file) goto fail1; panic_file->data = NULL; panic_file->read_proc = NULL; panic_file->write_proc = panic_write; trace_printk("test_panic: Building bad_kfree\n"); bad_kfree_file = create_proc_entry("bad_kfree", 0600, panic_dir); if(!bad_kfree_file) goto fail2; bad_kfree_file->data = NULL; bad_kfree_file->read_proc = NULL; bad_kfree_file->write_proc = bad_kfree_write; trace_printk("test_panic: Building bug\n"); bug_file = create_proc_entry("bug", 0600, panic_dir); if(!bug_file) goto fail3; bug_file->data = NULL; bug_file->read_proc = NULL; bug_file->write_proc = bug_write; trace_printk("test_panic: Building hang\n"); hang_file = create_proc_entry("hang", 0600, panic_dir); if(!hang_file) goto fail4; hang_file->data = NULL; hang_file->read_proc = NULL; hang_file->write_proc = hang_write; trace_printk("test_panic: Building disableirq\n"); disableirq_file = create_proc_entry("disableirq", 0600, panic_dir); if(!disableirq_file) goto fail5; disableirq_file->data = NULL; disableirq_file->read_proc = NULL; disableirq_file->write_proc = disableirq_write; trace_printk("test_panic: Building bad_access\n"); bad_access_file = create_proc_entry("bad_access", 0600, panic_dir); if(!bad_access_file) goto fail6; bad_access_file->data = NULL; bad_access_file->read_proc = NULL; bad_access_file->write_proc = bad_access_write; trace_printk("test_panic: Building deep_panic\n"); deep_panic_file = create_proc_entry("deep_panic", 0600, panic_dir); if(!bad_access_file) goto fail7; deep_panic_file->data = NULL; deep_panic_file->read_proc = NULL; deep_panic_file->write_proc = deep_panic_write; trace_printk("test_panic: Building deep_bug\n"); deep_bug_file = create_proc_entry("deep_bug", 0600, panic_dir); if(!bad_access_file) goto fail8; deep_bug_file->data = NULL; deep_bug_file->read_proc = NULL; deep_bug_file->write_proc = deep_bug_write; trace_printk(KERN_INFO "%s %s initialised\n", MODULE_NAME, LOCAL_MODULE_VERSION); printk(KERN_INFO "%s %s initialised\n", MODULE_NAME, LOCAL_MODULE_VERSION); return 0; fail8: remove_proc_entry("deep_panic", panic_dir); fail7: remove_proc_entry("bad_access", panic_dir); fail6: remove_proc_entry("disableirq", panic_dir); fail5: remove_proc_entry("hang", panic_dir); fail4: remove_proc_entry("bug", panic_dir); fail3: remove_proc_entry("bad_kfree", panic_dir); fail2: remove_proc_entry("panic", panic_dir); fail1: remove_proc_entry(MODULE_NAME, NULL); return rc; } static void __exit test_panic_exit(void) { remove_proc_entry("panic", panic_dir); remove_proc_entry("bad_kfree", panic_dir); remove_proc_entry("bug", panic_dir); remove_proc_entry("hang", panic_dir); remove_proc_entry("disableirq", panic_dir); remove_proc_entry("bad_access", panic_dir); remove_proc_entry("deep_panic", panic_dir); remove_proc_entry("deep_bug", panic_dir); remove_proc_entry(MODULE_NAME, NULL); printk(KERN_INFO "%s %s removed\n", MODULE_NAME, LOCAL_MODULE_VERSION); } module_init(test_panic_init); module_exit(test_panic_exit); MODULE_AUTHOR("WindRiver"); MODULE_DESCRIPTION("Force a kernel panic"); MODULE_LICENSE("GPL"); crash_mod/Makefile0000640000130300001450000000007411410411054014470 0ustar jwesselftpadmin obj-m := test_panic.o ioModuleExample-objs := test_panic.o