sysrq.c 2.0 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788
  1. /*
  2. * Copyright (C) 2001 Jeff Dike (jdike@karaya.com)
  3. * Licensed under the GPL
  4. */
  5. #include "linux/config.h"
  6. #include "linux/sched.h"
  7. #include "linux/kernel.h"
  8. #include "linux/module.h"
  9. #include "linux/kallsyms.h"
  10. #include "asm/page.h"
  11. #include "asm/processor.h"
  12. #include "sysrq.h"
  13. #include "user_util.h"
  14. /* Catch non-i386 SUBARCH's. */
  15. #if !defined(CONFIG_UML_X86) || defined(CONFIG_64BIT)
  16. void show_trace(struct task_struct *task, unsigned long * stack)
  17. {
  18. unsigned long addr;
  19. if (!stack) {
  20. stack = (unsigned long*) &stack;
  21. WARN_ON(1);
  22. }
  23. printk("Call Trace: \n");
  24. while (((long) stack & (THREAD_SIZE-1)) != 0) {
  25. addr = *stack;
  26. if (__kernel_text_address(addr)) {
  27. printk("%08lx: [<%08lx>]", (unsigned long) stack, addr);
  28. print_symbol(" %s", addr);
  29. printk("\n");
  30. }
  31. stack++;
  32. }
  33. printk("\n");
  34. }
  35. #endif
  36. /*
  37. * stack dumps generator - this is used by arch-independent code.
  38. * And this is identical to i386 currently.
  39. */
  40. void dump_stack(void)
  41. {
  42. unsigned long stack;
  43. show_trace(current, &stack);
  44. }
  45. EXPORT_SYMBOL(dump_stack);
  46. /*Stolen from arch/i386/kernel/traps.c */
  47. static int kstack_depth_to_print = 24;
  48. /* This recently started being used in arch-independent code too, as in
  49. * kernel/sched.c.*/
  50. void show_stack(struct task_struct *task, unsigned long *esp)
  51. {
  52. unsigned long *stack;
  53. int i;
  54. if (esp == NULL) {
  55. if (task != current && task != NULL) {
  56. /* XXX: Isn't this bogus? I.e. isn't this the
  57. * *userspace* stack of this task? If not so, use this
  58. * even when task == current (as in i386).
  59. */
  60. esp = (unsigned long *) KSTK_ESP(task);
  61. /* Which one? No actual difference - just coding style.*/
  62. //esp = (unsigned long *) PT_REGS_IP(&task->thread.regs);
  63. } else {
  64. esp = (unsigned long *) &esp;
  65. }
  66. }
  67. stack = esp;
  68. for(i = 0; i < kstack_depth_to_print; i++) {
  69. if (kstack_end(stack))
  70. break;
  71. if (i && ((i % 8) == 0))
  72. printk("\n ");
  73. printk("%08lx ", *stack++);
  74. }
  75. printk("Call Trace: \n");
  76. show_trace(current, esp);
  77. }