panic.c
上传用户:jlfgdled
上传日期:2013-04-10
资源大小:33168k
文件大小:3k
源码类别:

Linux/Unix编程

开发平台:

Unix_Linux

  1. /*
  2.  *  linux/kernel/panic.c
  3.  *
  4.  *  Copyright (C) 1991, 1992  Linus Torvalds
  5.  */
  6. /*
  7.  * This function is used through-out the kernel (including mm and fs)
  8.  * to indicate a major problem.
  9.  */
  10. #include <linux/config.h>
  11. #include <linux/sched.h>
  12. #include <linux/delay.h>
  13. #include <linux/reboot.h>
  14. #include <linux/notifier.h>
  15. #include <linux/init.h>
  16. #include <linux/sysrq.h>
  17. #include <linux/interrupt.h>
  18. asmlinkage void sys_sync(void); /* it's really int */
  19. int panic_timeout;
  20. struct notifier_block *panic_notifier_list;
  21. static int __init panic_setup(char *str)
  22. {
  23. panic_timeout = simple_strtoul(str, NULL, 0);
  24. return 1;
  25. }
  26. __setup("panic=", panic_setup);
  27. /**
  28.  * panic - halt the system
  29.  * @fmt: The text string to print
  30.  *
  31.  * Display a message, then perform cleanups. Functions in the panic
  32.  * notifier list are called after the filesystem cache is flushed (when possible).
  33.  *
  34.  * This function never returns.
  35.  */
  36.  
  37. NORET_TYPE void panic(const char * fmt, ...)
  38. {
  39. static char buf[1024];
  40. va_list args;
  41. #if defined(CONFIG_ARCH_S390)
  42.         unsigned long caller = (unsigned long) __builtin_return_address(0);
  43. #endif
  44. bust_spinlocks(1);
  45. va_start(args, fmt);
  46. vsprintf(buf, fmt, args);
  47. va_end(args);
  48. printk(KERN_EMERG "Kernel panic: %sn",buf);
  49. if (in_interrupt())
  50. printk(KERN_EMERG "In interrupt handler - not syncingn");
  51. else if (!current->pid)
  52. printk(KERN_EMERG "In idle task - not syncingn");
  53. else
  54. sys_sync();
  55. bust_spinlocks(0);
  56. #ifdef CONFIG_SMP
  57. smp_send_stop();
  58. #endif
  59. notifier_call_chain(&panic_notifier_list, 0, NULL);
  60. if (panic_timeout > 0)
  61. {
  62. /*
  63.    * Delay timeout seconds before rebooting the machine. 
  64.  * We can't use the "normal" timers since we just panicked..
  65.    */
  66. printk(KERN_EMERG "Rebooting in %d seconds..",panic_timeout);
  67. mdelay(panic_timeout*1000);
  68. /*
  69.  * Should we run the reboot notifier. For the moment Im
  70.  * choosing not too. It might crash, be corrupt or do
  71.  * more harm than good for other reasons.
  72.  */
  73. machine_restart(NULL);
  74. }
  75. #ifdef __sparc__
  76. {
  77. extern int stop_a_enabled;
  78. /* Make sure the user can actually press L1-A */
  79. stop_a_enabled = 1;
  80. printk("Press L1-A to return to the boot promn");
  81. }
  82. #endif
  83. #if defined(CONFIG_ARCH_S390)
  84.         disabled_wait(caller);
  85. #endif
  86. sti();
  87. for(;;) {
  88. #if defined(CONFIG_X86) && defined(CONFIG_VT) 
  89. extern void panic_blink(void);
  90. panic_blink(); 
  91. #endif
  92. CHECK_EMERGENCY_SYNC
  93. }
  94. }
  95. /**
  96.  * print_tainted - return a string to represent the kernel taint state.
  97.  *
  98.  * The string is overwritten by the next call to print_taint().
  99.  */
  100.  
  101. const char *print_tainted()
  102. {
  103. static char buf[20];
  104. if (tainted) {
  105. snprintf(buf, sizeof(buf), "Tainted: %c%c",
  106. tainted & 1 ? 'P' : 'G',
  107. tainted & 2 ? 'F' : ' ');
  108. }
  109. else
  110. snprintf(buf, sizeof(buf), "Not tainted");
  111. return(buf);
  112. }
  113. int tainted = 0;
  114. /*
  115.  * A BUG() call in an inline function in a header should be avoided,
  116.  * because it can seriously bloat the kernel.  So here we have
  117.  * helper functions.
  118.  * We lose the BUG()-time file-and-line info this way, but it's
  119.  * usually not very useful from an inline anyway.  The backtrace
  120.  * tells us what we want to know.
  121.  */
  122. void __out_of_line_bug(int line)
  123. {
  124. printk("kernel BUG in header file at line %dn", line);
  125. BUG();
  126. /* Satisfy __attribute__((noreturn)) */
  127. for ( ; ; )
  128. ;
  129. }