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

Linux/Unix编程

开发平台:

Unix_Linux

  1. /* $Id: traps.c,v 1.17 2001/12/07 17:02:34 bjornw Exp $
  2.  *
  3.  *  linux/arch/cris/traps.c
  4.  *
  5.  *  Here we handle the break vectors not used by the system call 
  6.  *  mechanism, as well as some general stack/register dumping 
  7.  *  things.
  8.  * 
  9.  *  Copyright (C) 2000,2001 Axis Communications AB
  10.  *
  11.  *  Authors:   Bjorn Wesen
  12.  *          Hans-Peter Nilsson
  13.  *
  14.  */
  15. #include <linux/init.h>
  16. #include <linux/sched.h>
  17. #include <linux/kernel.h>
  18. #include <linux/string.h>
  19. #include <linux/errno.h>
  20. #include <linux/ptrace.h>
  21. #include <linux/timer.h>
  22. #include <linux/mm.h>
  23. #include <asm/uaccess.h>
  24. #include <asm/system.h>
  25. #include <asm/segment.h>
  26. #include <asm/io.h>
  27. #include <asm/pgtable.h>
  28. int kstack_depth_to_print = 24;
  29. void show_trace(unsigned long * stack)
  30. {
  31. unsigned long addr, module_start, module_end;
  32. extern char _stext, _etext;
  33. int i;
  34.         printk("nCall Trace: ");
  35.         i = 1;
  36.         module_start = VMALLOC_START;
  37.         module_end = VMALLOC_END;
  38.         while (((long) stack & (THREAD_SIZE-1)) != 0) {
  39. if (__get_user (addr, stack)) {
  40. /* This message matches "failing address" marked
  41.    s390 in ksymoops, so lines containing it will
  42.    not be filtered out by ksymoops.  */
  43. printk ("Failing address 0x%lxn", (unsigned long)stack);
  44. break;
  45. }
  46. stack++;
  47.                 /*
  48.                  * If the address is either in the text segment of the
  49.                  * kernel, or in the region which contains vmalloc'ed
  50.                  * memory, it *may* be the address of a calling
  51.                  * routine; if so, print it so that someone tracing
  52.                  * down the cause of the crash will be able to figure
  53.                  * out the call path that was taken.
  54.                  */
  55.                 if (((addr >= (unsigned long) &_stext) &&
  56.                      (addr <= (unsigned long) &_etext)) ||
  57.                     ((addr >= module_start) && (addr <= module_end))) {
  58.                         if (i && ((i % 8) == 0))
  59.                                 printk("n       ");
  60.                         printk("[<%08lx>] ", addr);
  61.                         i++;
  62.                 }
  63.         }
  64. }
  65. void show_trace_task(struct task_struct *tsk)
  66. {
  67. /* TODO, this is not really useful since its called from
  68.  * SysRq-T and we don't have a keyboard.. :) 
  69.  */
  70. }
  71. /*
  72.  * These constants are for searching for possible module text
  73.  * segments. MODULE_RANGE is a guess of how much space is likely
  74.  * to be vmalloced.
  75.  */
  76. #define MODULE_RANGE (8*1024*1024)
  77. /*
  78.  * The output (format, strings and order) is adjusted to be usable with
  79.  * ksymoops-2.4.1 with some necessary CRIS-specific patches.  Please don't
  80.  * change it unless you're serious about adjusting ksymoops and syncing
  81.  * with the ksymoops maintainer.
  82.  */
  83. void 
  84. show_stack(unsigned long *sp)
  85. {
  86.         unsigned long *stack, addr;
  87.         int i;
  88. /*
  89.  * debugging aid: "show_stack(NULL);" prints a
  90.  * back trace.
  91.  */
  92.         if(sp == NULL)
  93.                 sp = (unsigned long*)rdsp();
  94.         stack = sp;
  95. printk("nStack from %08lx:n       ", (unsigned long)stack);
  96.         for(i = 0; i < kstack_depth_to_print; i++) {
  97.                 if (((long) stack & (THREAD_SIZE-1)) == 0)
  98.                         break;
  99.                 if (i && ((i % 8) == 0))
  100.                         printk("n       ");
  101. if (__get_user (addr, stack)) {
  102. /* This message matches "failing address" marked
  103.    s390 in ksymoops, so lines containing it will
  104.    not be filtered out by ksymoops.  */
  105. printk ("Failing address 0x%lxn", (unsigned long)stack);
  106. break;
  107. }
  108. stack++;
  109. printk("%08lx ", addr);
  110.         }
  111. show_trace(sp);
  112. }
  113. #if 0
  114. /* displays a short stack trace */
  115. int 
  116. show_stack()
  117. {
  118. unsigned long *sp = (unsigned long *)rdusp();
  119. int i;
  120. printk("Stack dump [0x%08lx]:n", (unsigned long)sp);
  121. for(i = 0; i < 16; i++)
  122. printk("sp + %d: 0x%08lxn", i*4, sp[i]);
  123. return 0;
  124. }
  125. #endif
  126. void 
  127. show_registers(struct pt_regs * regs)
  128. {
  129. /* We either use rdusp() - the USP register, which might not
  130.    correspond to the current process for all cases we're called,
  131.    or we use the current->thread.usp, which is not up to date for
  132.    the current process.  Experience shows we want the USP
  133.    register.  */
  134. unsigned long usp = rdusp();
  135. printk("IRP: %08lx SRP: %08lx DCCR: %08lx USP: %08lx MOF: %08lxn",
  136.        regs->irp, regs->srp, regs->dccr, usp, regs->mof );
  137. printk(" r0: %08lx  r1: %08lx   r2: %08lx  r3: %08lxn",
  138.        regs->r0, regs->r1, regs->r2, regs->r3);
  139. printk(" r4: %08lx  r5: %08lx   r6: %08lx  r7: %08lxn",
  140.        regs->r4, regs->r5, regs->r6, regs->r7);
  141. printk(" r8: %08lx  r9: %08lx  r10: %08lx r11: %08lxn",
  142.        regs->r8, regs->r9, regs->r10, regs->r11);
  143. printk("r12: %08lx r13: %08lx oR10: %08lxn",
  144.        regs->r12, regs->r13, regs->orig_r10);
  145. printk("R_MMU_CAUSE: %08lxn", (unsigned long)*R_MMU_CAUSE);
  146. printk("Process %s (pid: %d, stackpage=%08lx)n",
  147.        current->comm, current->pid, (unsigned long)current);
  148. /*
  149.          * When in-kernel, we also print out the stack and code at the
  150.          * time of the fault..
  151.          */
  152.         if (! user_mode(regs)) {
  153.    int i;
  154.                 show_stack((unsigned long*)usp);
  155. /* Dump kernel stack if the previous dump wasn't one.  */
  156. if (usp != 0)
  157. show_stack (NULL);
  158.                 printk("nCode: ");
  159.                 if(regs->irp < PAGE_OFFSET)
  160.                         goto bad;
  161. /* Often enough the value at regs->irp does not point to
  162.    the interesting instruction, which is most often the
  163.    _previous_ instruction.  So we dump at an offset large
  164.    enough that instruction decoding should be in sync at
  165.    the interesting point, but small enough to fit on a row
  166.    (sort of).  We point out the regs->irp location in a
  167.    ksymoops-friendly way by wrapping the byte for that
  168.    address in parentheses.  */
  169.                 for(i = -12; i < 12; i++)
  170.                 {
  171.                         unsigned char c;
  172.                         if(__get_user(c, &((unsigned char*)regs->irp)[i])) {
  173. bad:
  174.                                 printk(" Bad IP value.");
  175.                                 break;
  176.                         }
  177. if (i == 0)
  178.   printk("(%02x) ", c);
  179. else
  180.   printk("%02x ", c);
  181.                 }
  182. printk("n");
  183.         }
  184. }
  185. /* Called from entry.S when the watchdog has bitten
  186.  * We print out something resembling an oops dump, and if
  187.  * we have the nice doggy development flag set, we halt here
  188.  * instead of rebooting.
  189.  */
  190. void
  191. watchdog_bite_hook(struct pt_regs *regs)
  192. {
  193. #ifdef CONFIG_ETRAX_WATCHDOG_NICE_DOGGY
  194. cli();
  195. stop_watchdog();
  196. show_registers(regs);
  197. while(1) /* nothing */;
  198. #else
  199. show_registers(regs);
  200. #endif
  201. }
  202. void dump_stack(void)
  203. {
  204. show_stack(NULL);
  205. }
  206. /* This is normally the 'Oops' routine */
  207. void 
  208. die_if_kernel(const char * str, struct pt_regs * regs, long err)
  209. {
  210. extern void reset_watchdog(void);
  211. extern void stop_watchdog(void);
  212. if(user_mode(regs))
  213. return;
  214. #ifdef CONFIG_ETRAX_WATCHDOG_NICE_DOGGY
  215. /* This printout might take too long and trigger the 
  216.  * watchdog normally. If we're in the nice doggy
  217.  * development mode, stop the watchdog during printout.
  218.  */
  219. stop_watchdog();
  220. #endif
  221. printk("%s: %04lxn", str, err & 0xffff);
  222. show_registers(regs);
  223. #ifdef CONFIG_ETRAX_WATCHDOG_NICE_DOGGY
  224. reset_watchdog();
  225. #endif
  226. do_exit(SIGSEGV);
  227. }
  228. void __init 
  229. trap_init(void)
  230. {
  231. /* Nothing needs to be done */
  232. }