debug.c 4.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213
  1. /*
  2. * Mach Operating System
  3. * Copyright (c) 1993 Carnegie Mellon University
  4. * All Rights Reserved.
  5. *
  6. * Permission to use, copy, modify and distribute this software and its
  7. * documentation is hereby granted, provided that both the copyright
  8. * notice and this permission notice appear in all copies of the
  9. * software, derivative works or modified versions, and any portions
  10. * thereof, and that both notices appear in supporting documentation.
  11. *
  12. * CARNEGIE MELLON ALLOWS FREE USE OF THIS SOFTWARE IN ITS "AS IS"
  13. * CONDITION. CARNEGIE MELLON DISCLAIMS ANY LIABILITY OF ANY KIND FOR
  14. * ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE.
  15. *
  16. * Carnegie Mellon requests users of this software to return to
  17. *
  18. * Software Distribution Coordinator or Software.Distribution@CS.CMU.EDU
  19. * School of Computer Science
  20. * Carnegie Mellon University
  21. * Pittsburgh PA 15213-3890
  22. *
  23. * any improvements or extensions that they make and grant Carnegie Mellon
  24. * the rights to redistribute these changes.
  25. */
  26. #include <mach/xen.h>
  27. #include <kern/printf.h>
  28. #include <stdarg.h>
  29. #include "cpu_number.h"
  30. #include <kern/lock.h>
  31. #include <kern/thread.h>
  32. #include <kern/debug.h>
  33. #include <machine/loose_ends.h>
  34. #include <machine/model_dep.h>
  35. #include <device/cons.h>
  36. #if NCPUS>1
  37. simple_lock_data_t Assert_print_lock; /* uninited, we take our chances */
  38. #endif
  39. static void
  40. do_cnputc(char c, vm_offset_t offset)
  41. {
  42. cnputc(c);
  43. }
  44. void
  45. Assert(const char *exp, const char *file, int line, const char *fun)
  46. {
  47. #if NCPUS > 1
  48. simple_lock(&Assert_print_lock);
  49. printf("{cpu%d} %s:%d: %s: Assertion `%s' failed.",
  50. cpu_number(), file, line, fun, exp);
  51. simple_unlock(&Assert_print_lock);
  52. #else
  53. printf("%s:%d: %s: Assertion `%s' failed.",
  54. file, line, fun, exp);
  55. #endif
  56. Debugger("assertion failure");
  57. }
  58. void SoftDebugger(message)
  59. const char *message;
  60. {
  61. printf("Debugger invoked: %s\n", message);
  62. #if !MACH_KDB
  63. printf("But no debugger, continuing.\n");
  64. return;
  65. #endif
  66. #if defined(vax) || defined(PC532)
  67. asm("bpt");
  68. #endif /* vax */
  69. #ifdef sun3
  70. current_thread()->pcb->flag |= TRACE_KDB;
  71. asm("orw #0x00008000,sr");
  72. #endif /* sun3 */
  73. #ifdef sun4
  74. current_thread()->pcb->pcb_flag |= TRACE_KDB;
  75. asm("ta 0x81");
  76. #endif /* sun4 */
  77. #if defined(mips ) || defined(i860) || defined(alpha)
  78. gimmeabreak();
  79. #endif
  80. #if defined(__i386__) || defined(__x86_64__)
  81. asm("int3");
  82. #endif
  83. }
  84. void Debugger(message)
  85. const char *message;
  86. {
  87. #if !MACH_KDB
  88. panic("Debugger invoked, but there isn't one!");
  89. #endif
  90. SoftDebugger(message);
  91. panic("Debugger returned!");
  92. }
  93. /* Be prepared to panic anytime,
  94. even before panic_init() gets called from the "normal" place in kern/startup.c.
  95. (panic_init() still needs to be called from there
  96. to make sure we get initialized before starting multiple processors.) */
  97. boolean_t panic_lock_initialized = FALSE;
  98. decl_simple_lock_data(, panic_lock)
  99. const char *panicstr;
  100. int paniccpu;
  101. void
  102. panic_init(void)
  103. {
  104. if (!panic_lock_initialized)
  105. {
  106. panic_lock_initialized = TRUE;
  107. simple_lock_init(&panic_lock);
  108. }
  109. }
  110. #if ! MACH_KBD
  111. extern boolean_t reboot_on_panic;
  112. #endif
  113. /*VARARGS1*/
  114. void
  115. Panic(const char *file, int line, const char *fun, const char *s, ...)
  116. {
  117. va_list listp;
  118. panic_init();
  119. simple_lock(&panic_lock);
  120. if (panicstr) {
  121. if (cpu_number() != paniccpu) {
  122. simple_unlock(&panic_lock);
  123. halt_cpu();
  124. /* NOTREACHED */
  125. }
  126. }
  127. else {
  128. panicstr = s;
  129. paniccpu = cpu_number();
  130. }
  131. simple_unlock(&panic_lock);
  132. printf("panic ");
  133. #if NCPUS > 1
  134. printf("{cpu%d} ", paniccpu);
  135. #endif
  136. printf("%s:%d: %s: ",file, line, fun);
  137. va_start(listp, s);
  138. _doprnt(s, listp, do_cnputc, 16, 0);
  139. va_end(listp);
  140. printf("\n");
  141. #if MACH_KDB
  142. Debugger("panic");
  143. #else
  144. # ifdef MACH_HYP
  145. hyp_crash();
  146. # else
  147. /* Give the user time to see the message */
  148. {
  149. int i = 1000; /* seconds */
  150. while (i--)
  151. delay (1000000); /* microseconds */
  152. }
  153. halt_all_cpus (reboot_on_panic);
  154. # endif /* MACH_HYP */
  155. #endif
  156. }
  157. /*
  158. * We'd like to use BSD's log routines here...
  159. */
  160. /*VARARGS2*/
  161. void
  162. log(int level, const char *fmt, ...)
  163. {
  164. va_list listp;
  165. va_start(listp, fmt);
  166. _doprnt(fmt, listp, do_cnputc, 16, 0);
  167. va_end(listp);
  168. }
  169. /* GCC references this for stack protection. */
  170. unsigned char __stack_chk_guard [ sizeof (vm_offset_t) ] =
  171. {
  172. [ sizeof (vm_offset_t) - 3 ] = '\r',
  173. [ sizeof (vm_offset_t) - 2 ] = '\n',
  174. [ sizeof (vm_offset_t) - 1 ] = 0xff,
  175. };
  176. void
  177. __stack_chk_fail (void)
  178. {
  179. panic("stack smashing detected");
  180. }