traps.c 2.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107
  1. /*
  2. * Copyright (C) 2007-2009 Michal Simek <monstr@monstr.eu>
  3. * Copyright (C) 2007-2009 PetaLogix
  4. * Copyright (C) 2006 Atmark Techno, Inc.
  5. *
  6. * This file is subject to the terms and conditions of the GNU General Public
  7. * License. See the file "COPYING" in the main directory of this archive
  8. * for more details.
  9. */
  10. #include <linux/kernel.h>
  11. #include <linux/kallsyms.h>
  12. #include <linux/module.h>
  13. #include <linux/sched.h>
  14. #include <linux/debug_locks.h>
  15. #include <asm/exceptions.h>
  16. #include <asm/system.h>
  17. void trap_init(void)
  18. {
  19. __enable_hw_exceptions();
  20. }
  21. void __bad_xchg(volatile void *ptr, int size)
  22. {
  23. printk(KERN_INFO "xchg: bad data size: pc 0x%p, ptr 0x%p, size %d\n",
  24. __builtin_return_address(0), ptr, size);
  25. BUG();
  26. }
  27. EXPORT_SYMBOL(__bad_xchg);
  28. static int kstack_depth_to_print = 24;
  29. static int __init kstack_setup(char *s)
  30. {
  31. kstack_depth_to_print = strict_strtoul(s, 0, NULL);
  32. return 1;
  33. }
  34. __setup("kstack=", kstack_setup);
  35. void show_trace(struct task_struct *task, unsigned long *stack)
  36. {
  37. unsigned long addr;
  38. if (!stack)
  39. stack = (unsigned long *)&stack;
  40. printk(KERN_NOTICE "Call Trace: ");
  41. #ifdef CONFIG_KALLSYMS
  42. printk(KERN_NOTICE "\n");
  43. #endif
  44. while (!kstack_end(stack)) {
  45. addr = *stack++;
  46. /*
  47. * If the address is either in the text segment of the
  48. * kernel, or in the region which contains vmalloc'ed
  49. * memory, it *may* be the address of a calling
  50. * routine; if so, print it so that someone tracing
  51. * down the cause of the crash will be able to figure
  52. * out the call path that was taken.
  53. */
  54. if (kernel_text_address(addr))
  55. print_ip_sym(addr);
  56. }
  57. printk(KERN_NOTICE "\n");
  58. if (!task)
  59. task = current;
  60. debug_show_held_locks(task);
  61. }
  62. void show_stack(struct task_struct *task, unsigned long *sp)
  63. {
  64. unsigned long *stack;
  65. int i;
  66. if (sp == NULL) {
  67. if (task)
  68. sp = (unsigned long *) ((struct thread_info *)
  69. (task->stack))->cpu_context.r1;
  70. else
  71. sp = (unsigned long *)&sp;
  72. }
  73. stack = sp;
  74. printk(KERN_INFO "\nStack:\n ");
  75. for (i = 0; i < kstack_depth_to_print; i++) {
  76. if (kstack_end(sp))
  77. break;
  78. if (i && ((i % 8) == 0))
  79. printk("\n ");
  80. printk("%08lx ", *sp++);
  81. }
  82. printk("\n");
  83. show_trace(task, stack);
  84. }
  85. void dump_stack(void)
  86. {
  87. show_stack(NULL, NULL);
  88. }
  89. EXPORT_SYMBOL(dump_stack);