diff options
Diffstat (limited to 'arch/mips/kernel')
| -rw-r--r-- | arch/mips/kernel/Makefile | 1 | ||||
| -rw-r--r-- | arch/mips/kernel/genex.S | 8 | ||||
| -rw-r--r-- | arch/mips/kernel/i8259.c | 4 | ||||
| -rw-r--r-- | arch/mips/kernel/process.c | 37 | ||||
| -rw-r--r-- | arch/mips/kernel/scall32-o32.S | 13 | ||||
| -rw-r--r-- | arch/mips/kernel/scall64-64.S | 2 | ||||
| -rw-r--r-- | arch/mips/kernel/scall64-n32.S | 2 | ||||
| -rw-r--r-- | arch/mips/kernel/scall64-o32.S | 2 | ||||
| -rw-r--r-- | arch/mips/kernel/stacktrace.c | 85 | ||||
| -rw-r--r-- | arch/mips/kernel/traps.c | 40 |
10 files changed, 132 insertions, 62 deletions
diff --git a/arch/mips/kernel/Makefile b/arch/mips/kernel/Makefile index 881c467c6982..cd9cec9e39e9 100644 --- a/arch/mips/kernel/Makefile +++ b/arch/mips/kernel/Makefile | |||
| @@ -11,6 +11,7 @@ obj-y += cpu-probe.o branch.o entry.o genex.o irq.o process.o \ | |||
| 11 | binfmt_irix-objs := irixelf.o irixinv.o irixioctl.o irixsig.o \ | 11 | binfmt_irix-objs := irixelf.o irixinv.o irixioctl.o irixsig.o \ |
| 12 | irix5sys.o sysirix.o | 12 | irix5sys.o sysirix.o |
| 13 | 13 | ||
| 14 | obj-$(CONFIG_STACKTRACE) += stacktrace.o | ||
| 14 | obj-$(CONFIG_MODULES) += mips_ksyms.o module.o | 15 | obj-$(CONFIG_MODULES) += mips_ksyms.o module.o |
| 15 | 16 | ||
| 16 | obj-$(CONFIG_APM) += apm.o | 17 | obj-$(CONFIG_APM) += apm.o |
diff --git a/arch/mips/kernel/genex.S b/arch/mips/kernel/genex.S index 37fda3dcdfc5..af6ef2fd8300 100644 --- a/arch/mips/kernel/genex.S +++ b/arch/mips/kernel/genex.S | |||
| @@ -220,8 +220,8 @@ NESTED(except_vec_vi_handler, 0, sp) | |||
| 220 | CLI | 220 | CLI |
| 221 | TRACE_IRQS_OFF | 221 | TRACE_IRQS_OFF |
| 222 | move a0, sp | 222 | move a0, sp |
| 223 | jalr v0 | 223 | PTR_LA ra, ret_from_irq |
| 224 | j ret_from_irq | 224 | jr v0 |
| 225 | END(except_vec_vi_handler) | 225 | END(except_vec_vi_handler) |
| 226 | 226 | ||
| 227 | /* | 227 | /* |
| @@ -349,8 +349,8 @@ NESTED(nmi_handler, PT_SIZE, sp) | |||
| 349 | .set at | 349 | .set at |
| 350 | __BUILD_\verbose \exception | 350 | __BUILD_\verbose \exception |
| 351 | move a0, sp | 351 | move a0, sp |
| 352 | jal do_\handler | 352 | PTR_LA ra, ret_from_exception |
| 353 | j ret_from_exception | 353 | j do_\handler |
| 354 | END(handle_\exception) | 354 | END(handle_\exception) |
| 355 | .endm | 355 | .endm |
| 356 | 356 | ||
diff --git a/arch/mips/kernel/i8259.c b/arch/mips/kernel/i8259.c index ea36c8e8852c..48e3418c217b 100644 --- a/arch/mips/kernel/i8259.c +++ b/arch/mips/kernel/i8259.c | |||
| @@ -302,11 +302,11 @@ static struct irqaction irq2 = { | |||
| 302 | }; | 302 | }; |
| 303 | 303 | ||
| 304 | static struct resource pic1_io_resource = { | 304 | static struct resource pic1_io_resource = { |
| 305 | .name = "pic1", .start = 0x20, .end = 0x3f, .flags = IORESOURCE_BUSY | 305 | .name = "pic1", .start = 0x20, .end = 0x21, .flags = IORESOURCE_BUSY |
| 306 | }; | 306 | }; |
| 307 | 307 | ||
| 308 | static struct resource pic2_io_resource = { | 308 | static struct resource pic2_io_resource = { |
| 309 | .name = "pic2", .start = 0xa0, .end = 0xbf, .flags = IORESOURCE_BUSY | 309 | .name = "pic2", .start = 0xa0, .end = 0xa1, .flags = IORESOURCE_BUSY |
| 310 | }; | 310 | }; |
| 311 | 311 | ||
| 312 | /* | 312 | /* |
diff --git a/arch/mips/kernel/process.c b/arch/mips/kernel/process.c index 2613a0dd4b82..045d987bc683 100644 --- a/arch/mips/kernel/process.c +++ b/arch/mips/kernel/process.c | |||
| @@ -40,6 +40,7 @@ | |||
| 40 | #include <asm/elf.h> | 40 | #include <asm/elf.h> |
| 41 | #include <asm/isadep.h> | 41 | #include <asm/isadep.h> |
| 42 | #include <asm/inst.h> | 42 | #include <asm/inst.h> |
| 43 | #include <asm/stacktrace.h> | ||
| 43 | #ifdef CONFIG_MIPS_MT_SMTC | 44 | #ifdef CONFIG_MIPS_MT_SMTC |
| 44 | #include <asm/mipsmtregs.h> | 45 | #include <asm/mipsmtregs.h> |
| 45 | extern void smtc_idle_loop_hook(void); | 46 | extern void smtc_idle_loop_hook(void); |
| @@ -398,7 +399,7 @@ unsigned long thread_saved_pc(struct task_struct *tsk) | |||
| 398 | #ifdef CONFIG_KALLSYMS | 399 | #ifdef CONFIG_KALLSYMS |
| 399 | /* used by show_backtrace() */ | 400 | /* used by show_backtrace() */ |
| 400 | unsigned long unwind_stack(struct task_struct *task, unsigned long *sp, | 401 | unsigned long unwind_stack(struct task_struct *task, unsigned long *sp, |
| 401 | unsigned long pc, unsigned long ra) | 402 | unsigned long pc, unsigned long *ra) |
| 402 | { | 403 | { |
| 403 | unsigned long stack_page; | 404 | unsigned long stack_page; |
| 404 | struct mips_frame_info info; | 405 | struct mips_frame_info info; |
| @@ -406,18 +407,42 @@ unsigned long unwind_stack(struct task_struct *task, unsigned long *sp, | |||
| 406 | char namebuf[KSYM_NAME_LEN + 1]; | 407 | char namebuf[KSYM_NAME_LEN + 1]; |
| 407 | unsigned long size, ofs; | 408 | unsigned long size, ofs; |
| 408 | int leaf; | 409 | int leaf; |
| 410 | extern void ret_from_irq(void); | ||
| 411 | extern void ret_from_exception(void); | ||
| 409 | 412 | ||
| 410 | stack_page = (unsigned long)task_stack_page(task); | 413 | stack_page = (unsigned long)task_stack_page(task); |
| 411 | if (!stack_page) | 414 | if (!stack_page) |
| 412 | return 0; | 415 | return 0; |
| 413 | 416 | ||
| 417 | /* | ||
| 418 | * If we reached the bottom of interrupt context, | ||
| 419 | * return saved pc in pt_regs. | ||
| 420 | */ | ||
| 421 | if (pc == (unsigned long)ret_from_irq || | ||
| 422 | pc == (unsigned long)ret_from_exception) { | ||
| 423 | struct pt_regs *regs; | ||
| 424 | if (*sp >= stack_page && | ||
| 425 | *sp + sizeof(*regs) <= stack_page + THREAD_SIZE - 32) { | ||
| 426 | regs = (struct pt_regs *)*sp; | ||
| 427 | pc = regs->cp0_epc; | ||
| 428 | if (__kernel_text_address(pc)) { | ||
| 429 | *sp = regs->regs[29]; | ||
| 430 | *ra = regs->regs[31]; | ||
| 431 | return pc; | ||
| 432 | } | ||
| 433 | } | ||
| 434 | return 0; | ||
| 435 | } | ||
| 414 | if (!kallsyms_lookup(pc, &size, &ofs, &modname, namebuf)) | 436 | if (!kallsyms_lookup(pc, &size, &ofs, &modname, namebuf)) |
| 415 | return 0; | 437 | return 0; |
| 416 | /* | 438 | /* |
| 417 | * Return ra if an exception occured at the first instruction | 439 | * Return ra if an exception occured at the first instruction |
| 418 | */ | 440 | */ |
| 419 | if (unlikely(ofs == 0)) | 441 | if (unlikely(ofs == 0)) { |
| 420 | return ra; | 442 | pc = *ra; |
| 443 | *ra = 0; | ||
| 444 | return pc; | ||
| 445 | } | ||
| 421 | 446 | ||
| 422 | info.func = (void *)(pc - ofs); | 447 | info.func = (void *)(pc - ofs); |
| 423 | info.func_size = ofs; /* analyze from start to ofs */ | 448 | info.func_size = ofs; /* analyze from start to ofs */ |
| @@ -436,11 +461,12 @@ unsigned long unwind_stack(struct task_struct *task, unsigned long *sp, | |||
| 436 | * one. In that cases avoid to return always the | 461 | * one. In that cases avoid to return always the |
| 437 | * same value. | 462 | * same value. |
| 438 | */ | 463 | */ |
| 439 | pc = pc != ra ? ra : 0; | 464 | pc = pc != *ra ? *ra : 0; |
| 440 | else | 465 | else |
| 441 | pc = ((unsigned long *)(*sp))[info.pc_offset]; | 466 | pc = ((unsigned long *)(*sp))[info.pc_offset]; |
| 442 | 467 | ||
| 443 | *sp += info.frame_size; | 468 | *sp += info.frame_size; |
| 469 | *ra = 0; | ||
| 444 | return __kernel_text_address(pc) ? pc : 0; | 470 | return __kernel_text_address(pc) ? pc : 0; |
| 445 | } | 471 | } |
| 446 | #endif | 472 | #endif |
| @@ -453,6 +479,7 @@ unsigned long get_wchan(struct task_struct *task) | |||
| 453 | unsigned long pc = 0; | 479 | unsigned long pc = 0; |
| 454 | #ifdef CONFIG_KALLSYMS | 480 | #ifdef CONFIG_KALLSYMS |
| 455 | unsigned long sp; | 481 | unsigned long sp; |
| 482 | unsigned long ra = 0; | ||
| 456 | #endif | 483 | #endif |
| 457 | 484 | ||
| 458 | if (!task || task == current || task->state == TASK_RUNNING) | 485 | if (!task || task == current || task->state == TASK_RUNNING) |
| @@ -466,7 +493,7 @@ unsigned long get_wchan(struct task_struct *task) | |||
| 466 | sp = task->thread.reg29 + schedule_mfi.frame_size; | 493 | sp = task->thread.reg29 + schedule_mfi.frame_size; |
| 467 | 494 | ||
| 468 | while (in_sched_functions(pc)) | 495 | while (in_sched_functions(pc)) |
| 469 | pc = unwind_stack(task, &sp, pc, 0); | 496 | pc = unwind_stack(task, &sp, pc, &ra); |
| 470 | #endif | 497 | #endif |
| 471 | 498 | ||
| 472 | out: | 499 | out: |
diff --git a/arch/mips/kernel/scall32-o32.S b/arch/mips/kernel/scall32-o32.S index e71785102206..61362e6fa9ec 100644 --- a/arch/mips/kernel/scall32-o32.S +++ b/arch/mips/kernel/scall32-o32.S | |||
| @@ -28,18 +28,7 @@ | |||
| 28 | NESTED(handle_sys, PT_SIZE, sp) | 28 | NESTED(handle_sys, PT_SIZE, sp) |
| 29 | .set noat | 29 | .set noat |
| 30 | SAVE_SOME | 30 | SAVE_SOME |
| 31 | #ifdef CONFIG_TRACE_IRQFLAGS | 31 | TRACE_IRQS_ON_RELOAD |
| 32 | TRACE_IRQS_ON | ||
| 33 | #ifdef CONFIG_64BIT | ||
| 34 | LONG_L $8, PT_R8(sp) | ||
| 35 | LONG_L $9, PT_R9(sp) | ||
| 36 | #endif | ||
| 37 | LONG_L $7, PT_R7(sp) | ||
| 38 | LONG_L $6, PT_R6(sp) | ||
| 39 | LONG_L $5, PT_R5(sp) | ||
| 40 | LONG_L $4, PT_R4(sp) | ||
| 41 | LONG_L $2, PT_R2(sp) | ||
| 42 | #endif | ||
| 43 | STI | 32 | STI |
| 44 | .set at | 33 | .set at |
| 45 | 34 | ||
diff --git a/arch/mips/kernel/scall64-64.S b/arch/mips/kernel/scall64-64.S index 4c22d0b4825d..6c7b5ed0ea6e 100644 --- a/arch/mips/kernel/scall64-64.S +++ b/arch/mips/kernel/scall64-64.S | |||
| @@ -34,7 +34,7 @@ NESTED(handle_sys64, PT_SIZE, sp) | |||
| 34 | */ | 34 | */ |
| 35 | .set noat | 35 | .set noat |
| 36 | SAVE_SOME | 36 | SAVE_SOME |
| 37 | TRACE_IRQS_ON | 37 | TRACE_IRQS_ON_RELOAD |
| 38 | STI | 38 | STI |
| 39 | .set at | 39 | .set at |
| 40 | #endif | 40 | #endif |
diff --git a/arch/mips/kernel/scall64-n32.S b/arch/mips/kernel/scall64-n32.S index f25c2a2f1038..6d9f18727ac5 100644 --- a/arch/mips/kernel/scall64-n32.S +++ b/arch/mips/kernel/scall64-n32.S | |||
| @@ -33,7 +33,7 @@ NESTED(handle_sysn32, PT_SIZE, sp) | |||
| 33 | #ifndef CONFIG_MIPS32_O32 | 33 | #ifndef CONFIG_MIPS32_O32 |
| 34 | .set noat | 34 | .set noat |
| 35 | SAVE_SOME | 35 | SAVE_SOME |
| 36 | TRACE_IRQS_ON | 36 | TRACE_IRQS_ON_RELOAD |
| 37 | STI | 37 | STI |
| 38 | .set at | 38 | .set at |
| 39 | #endif | 39 | #endif |
diff --git a/arch/mips/kernel/scall64-o32.S b/arch/mips/kernel/scall64-o32.S index 288ee4ac4dbb..2e6d0673163e 100644 --- a/arch/mips/kernel/scall64-o32.S +++ b/arch/mips/kernel/scall64-o32.S | |||
| @@ -28,7 +28,7 @@ | |||
| 28 | NESTED(handle_sys, PT_SIZE, sp) | 28 | NESTED(handle_sys, PT_SIZE, sp) |
| 29 | .set noat | 29 | .set noat |
| 30 | SAVE_SOME | 30 | SAVE_SOME |
| 31 | TRACE_IRQS_ON | 31 | TRACE_IRQS_ON_RELOAD |
| 32 | STI | 32 | STI |
| 33 | .set at | 33 | .set at |
| 34 | ld t1, PT_EPC(sp) # skip syscall on return | 34 | ld t1, PT_EPC(sp) # skip syscall on return |
diff --git a/arch/mips/kernel/stacktrace.c b/arch/mips/kernel/stacktrace.c new file mode 100644 index 000000000000..4aabe526a68e --- /dev/null +++ b/arch/mips/kernel/stacktrace.c | |||
| @@ -0,0 +1,85 @@ | |||
| 1 | /* | ||
| 2 | * arch/mips/kernel/stacktrace.c | ||
| 3 | * | ||
| 4 | * Stack trace management functions | ||
| 5 | * | ||
| 6 | * Copyright (C) 2006 Atsushi Nemoto <anemo@mba.ocn.ne.jp> | ||
| 7 | */ | ||
| 8 | #include <linux/sched.h> | ||
| 9 | #include <linux/stacktrace.h> | ||
| 10 | #include <asm/stacktrace.h> | ||
| 11 | |||
| 12 | /* | ||
| 13 | * Save stack-backtrace addresses into a stack_trace buffer: | ||
| 14 | */ | ||
| 15 | static void save_raw_context_stack(struct stack_trace *trace, | ||
| 16 | unsigned long reg29) | ||
| 17 | { | ||
| 18 | unsigned long *sp = (unsigned long *)reg29; | ||
| 19 | unsigned long addr; | ||
| 20 | |||
| 21 | while (!kstack_end(sp)) { | ||
| 22 | addr = *sp++; | ||
| 23 | if (__kernel_text_address(addr)) { | ||
| 24 | if (trace->skip > 0) | ||
| 25 | trace->skip--; | ||
| 26 | else | ||
| 27 | trace->entries[trace->nr_entries++] = addr; | ||
| 28 | if (trace->nr_entries >= trace->max_entries) | ||
| 29 | break; | ||
| 30 | } | ||
| 31 | } | ||
| 32 | } | ||
| 33 | |||
| 34 | static void save_context_stack(struct stack_trace *trace, | ||
| 35 | struct task_struct *task, struct pt_regs *regs) | ||
| 36 | { | ||
| 37 | unsigned long sp = regs->regs[29]; | ||
| 38 | #ifdef CONFIG_KALLSYMS | ||
| 39 | unsigned long ra = regs->regs[31]; | ||
| 40 | unsigned long pc = regs->cp0_epc; | ||
| 41 | |||
| 42 | if (raw_show_trace || !__kernel_text_address(pc)) { | ||
| 43 | unsigned long stack_page = | ||
| 44 | (unsigned long)task_stack_page(task); | ||
| 45 | if (stack_page && sp >= stack_page && | ||
| 46 | sp <= stack_page + THREAD_SIZE - 32) | ||
| 47 | save_raw_context_stack(trace, sp); | ||
| 48 | return; | ||
| 49 | } | ||
| 50 | do { | ||
| 51 | if (trace->skip > 0) | ||
| 52 | trace->skip--; | ||
| 53 | else | ||
| 54 | trace->entries[trace->nr_entries++] = pc; | ||
| 55 | if (trace->nr_entries >= trace->max_entries) | ||
| 56 | break; | ||
| 57 | pc = unwind_stack(task, &sp, pc, &ra); | ||
| 58 | } while (pc); | ||
| 59 | #else | ||
| 60 | save_raw_context_stack(sp); | ||
| 61 | #endif | ||
| 62 | } | ||
| 63 | |||
| 64 | /* | ||
| 65 | * Save stack-backtrace addresses into a stack_trace buffer. | ||
| 66 | */ | ||
| 67 | void save_stack_trace(struct stack_trace *trace, struct task_struct *task) | ||
| 68 | { | ||
| 69 | struct pt_regs dummyregs; | ||
| 70 | struct pt_regs *regs = &dummyregs; | ||
| 71 | |||
| 72 | WARN_ON(trace->nr_entries || !trace->max_entries); | ||
| 73 | |||
| 74 | if (task && task != current) { | ||
| 75 | regs->regs[29] = task->thread.reg29; | ||
| 76 | regs->regs[31] = 0; | ||
| 77 | regs->cp0_epc = task->thread.reg31; | ||
| 78 | } else { | ||
| 79 | if (!task) | ||
| 80 | task = current; | ||
| 81 | prepare_frametrace(regs); | ||
| 82 | } | ||
| 83 | |||
| 84 | save_context_stack(trace, task, regs); | ||
| 85 | } | ||
diff --git a/arch/mips/kernel/traps.c b/arch/mips/kernel/traps.c index e51d8fd9a152..b7292a56d4cd 100644 --- a/arch/mips/kernel/traps.c +++ b/arch/mips/kernel/traps.c | |||
| @@ -41,6 +41,7 @@ | |||
| 41 | #include <asm/mmu_context.h> | 41 | #include <asm/mmu_context.h> |
| 42 | #include <asm/watch.h> | 42 | #include <asm/watch.h> |
| 43 | #include <asm/types.h> | 43 | #include <asm/types.h> |
| 44 | #include <asm/stacktrace.h> | ||
| 44 | 45 | ||
| 45 | extern asmlinkage void handle_int(void); | 46 | extern asmlinkage void handle_int(void); |
| 46 | extern asmlinkage void handle_tlbm(void); | 47 | extern asmlinkage void handle_tlbm(void); |
| @@ -92,16 +93,14 @@ static void show_raw_backtrace(unsigned long reg29) | |||
| 92 | } | 93 | } |
| 93 | 94 | ||
| 94 | #ifdef CONFIG_KALLSYMS | 95 | #ifdef CONFIG_KALLSYMS |
| 95 | static int raw_show_trace; | 96 | int raw_show_trace; |
| 96 | static int __init set_raw_show_trace(char *str) | 97 | static int __init set_raw_show_trace(char *str) |
| 97 | { | 98 | { |
| 98 | raw_show_trace = 1; | 99 | raw_show_trace = 1; |
| 99 | return 1; | 100 | return 1; |
| 100 | } | 101 | } |
| 101 | __setup("raw_show_trace", set_raw_show_trace); | 102 | __setup("raw_show_trace", set_raw_show_trace); |
| 102 | 103 | #endif | |
| 103 | extern unsigned long unwind_stack(struct task_struct *task, unsigned long *sp, | ||
| 104 | unsigned long pc, unsigned long ra); | ||
| 105 | 104 | ||
| 106 | static void show_backtrace(struct task_struct *task, struct pt_regs *regs) | 105 | static void show_backtrace(struct task_struct *task, struct pt_regs *regs) |
| 107 | { | 106 | { |
| @@ -116,14 +115,10 @@ static void show_backtrace(struct task_struct *task, struct pt_regs *regs) | |||
| 116 | printk("Call Trace:\n"); | 115 | printk("Call Trace:\n"); |
| 117 | do { | 116 | do { |
| 118 | print_ip_sym(pc); | 117 | print_ip_sym(pc); |
| 119 | pc = unwind_stack(task, &sp, pc, ra); | 118 | pc = unwind_stack(task, &sp, pc, &ra); |
| 120 | ra = 0; | ||
| 121 | } while (pc); | 119 | } while (pc); |
| 122 | printk("\n"); | 120 | printk("\n"); |
| 123 | } | 121 | } |
| 124 | #else | ||
| 125 | #define show_backtrace(task, r) show_raw_backtrace((r)->regs[29]); | ||
| 126 | #endif | ||
| 127 | 122 | ||
| 128 | /* | 123 | /* |
| 129 | * This routine abuses get_user()/put_user() to reference pointers | 124 | * This routine abuses get_user()/put_user() to reference pointers |
| @@ -158,28 +153,6 @@ static void show_stacktrace(struct task_struct *task, struct pt_regs *regs) | |||
| 158 | show_backtrace(task, regs); | 153 | show_backtrace(task, regs); |
| 159 | } | 154 | } |
| 160 | 155 | ||
| 161 | static __always_inline void prepare_frametrace(struct pt_regs *regs) | ||
| 162 | { | ||
| 163 | __asm__ __volatile__( | ||
| 164 | ".set push\n\t" | ||
| 165 | ".set noat\n\t" | ||
| 166 | #ifdef CONFIG_64BIT | ||
| 167 | "1: dla $1, 1b\n\t" | ||
| 168 | "sd $1, %0\n\t" | ||
| 169 | "sd $29, %1\n\t" | ||
| 170 | "sd $31, %2\n\t" | ||
| 171 | #else | ||
| 172 | "1: la $1, 1b\n\t" | ||
| 173 | "sw $1, %0\n\t" | ||
| 174 | "sw $29, %1\n\t" | ||
| 175 | "sw $31, %2\n\t" | ||
| 176 | #endif | ||
| 177 | ".set pop\n\t" | ||
| 178 | : "=m" (regs->cp0_epc), | ||
| 179 | "=m" (regs->regs[29]), "=m" (regs->regs[31]) | ||
| 180 | : : "memory"); | ||
| 181 | } | ||
| 182 | |||
| 183 | void show_stack(struct task_struct *task, unsigned long *sp) | 156 | void show_stack(struct task_struct *task, unsigned long *sp) |
| 184 | { | 157 | { |
| 185 | struct pt_regs regs; | 158 | struct pt_regs regs; |
| @@ -206,11 +179,6 @@ void dump_stack(void) | |||
| 206 | { | 179 | { |
| 207 | struct pt_regs regs; | 180 | struct pt_regs regs; |
| 208 | 181 | ||
| 209 | /* | ||
| 210 | * Remove any garbage that may be in regs (specially func | ||
| 211 | * addresses) to avoid show_raw_backtrace() to report them | ||
| 212 | */ | ||
| 213 | memset(®s, 0, sizeof(regs)); | ||
| 214 | prepare_frametrace(®s); | 182 | prepare_frametrace(®s); |
| 215 | show_backtrace(current, ®s); | 183 | show_backtrace(current, ®s); |
| 216 | } | 184 | } |
