Loading...
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 | /** * Minimalist Kernel Debugger * Machine dependent stack traceback code for IA-64. * * Copyright (C) 1999 Goutham Rao <goutham.rao@intel.com> * Copyright (C) 1999 Sreenivas Subramoney <sreenivas.subramoney@intel.com> * Intel Corporation, August 1999. * Copyright (C) 1999 Hewlett-Packard Co * Copyright (C) 1999 David Mosberger-Tang <davidm@hpl.hp.com> * * 99/12/03 D. Mosberger Reimplemented based on <asm-ia64/unwind.h> API. * 99/12/06 D. Mosberger Added support for backtracing other processes. */ #include <linux/ctype.h> #include <linux/string.h> #include <linux/kernel.h> #include <linux/sched.h> #include <linux/kdb.h> #include <asm/system.h> #include <asm/current.h> #include <asm/kdbsupport.h> /* * Minimal stack back trace functionality. */ int kdb_bt (int argc, const char **argv, const char **envp, struct pt_regs *regs) { struct task_struct *task = current; struct ia64_frame_info info; char *name; int diag; if (strcmp(argv[0], "btp") == 0) { unsigned long pid; diag = kdbgetularg(argv[1], &pid); if (diag) return diag; task = find_task_by_pid(pid); if (!task) { kdb_printf("No process with pid == %d found\n", pid); return 0; } regs = ia64_task_regs(task); } else if (argc) { kdb_printf("bt <address> is unsupported for IA-64\n"); return 0; } if (task == current) { /* * Upon entering kdb, the stack frame looks like this: * * +---------------------+ * | struct pt_regs | * +---------------------+ * | | * | kernel stack | * | | * +=====================+ <--- top of stack upon entering kdb * | struct pt_regs | * +---------------------+ * | struct switch_stack | * +---------------------+ */ if (user_mode(regs)) { /* We are not implementing stack backtrace from user mode code */ kdb_printf ("Not in Kernel\n"); return 0; } ia64_unwind_init_from_current(&info, regs); } else { /* * For a blocked task, the stack frame looks like this: * * +---------------------+ * | struct pt_regs | * +---------------------+ * | | * | kernel stack | * | | * +---------------------+ * | struct switch_stack | * +=====================+ <--- task->thread.ksp */ ia64_unwind_init_from_blocked_task(&info, task); } kdb_printf("Ret Address Reg Stack base Name\n\n") ; do { unsigned long ip = ia64_unwind_get_ip(&info); name = kdbnearsym(ip); if (!name) { kdb_printf("Interrupt\n"); return 0; } kdb_printf("0x%016lx: [0x%016lx] %s\n", ip, ia64_unwind_get_bsp(&info), name); } while (ia64_unwind_to_previous_frame(&info) >= 0); return 0; } |