X-Git-Url: http://git.onelab.eu/?a=blobdiff_plain;f=arch%2Fsh64%2Flib%2Fdbg.c;h=58087331b8a6acd3da88e41f8cb7912635258d64;hb=43bc926fffd92024b46cafaf7350d669ba9ca884;hp=d74913fe399cbd39d28dfa71294d52ad75d81c8d;hpb=5fc42a6ed0ec81088c37caadb45898ae6cd0ad2c;p=linux-2.6.git diff --git a/arch/sh64/lib/dbg.c b/arch/sh64/lib/dbg.c index d74913fe3..58087331b 100644 --- a/arch/sh64/lib/dbg.c +++ b/arch/sh64/lib/dbg.c @@ -8,6 +8,7 @@ -- Copyright 2004 Richard Curnow (evt_debug etc) -- --------------------------------------------------------------------------*/ +#include #include #include #include @@ -136,6 +137,8 @@ void print_itlb(void) /* ======================================================================= */ +#ifdef CONFIG_POOR_MANS_STRACE + #include "syscalltab.h" struct ring_node { @@ -151,6 +154,17 @@ struct ring_node { static struct ring_node event_ring[16]; static int event_ptr = 0; +struct stored_syscall_data { + int pid; + int syscall_number; +}; + +#define N_STORED_SYSCALLS 16 + +static struct stored_syscall_data stored_syscalls[N_STORED_SYSCALLS]; +static int syscall_next=0; +static int syscall_next_print=0; + void evt_debug(int evt, int ret_addr, int event, int tra, struct pt_regs *regs) { int syscallno = tra & 0xff; @@ -160,7 +174,7 @@ void evt_debug(int evt, int ret_addr, int event, int tra, struct pt_regs *regs) struct ring_node *rr; pid = current->pid; - stack_bottom = (unsigned long) current->thread_info; + stack_bottom = (unsigned long) task_stack_page(current); asm volatile("ori r15, 0, %0" : "=r" (sp)); rr = event_ring + event_ptr; rr->evt = evt; @@ -187,15 +201,35 @@ void evt_debug(int evt, int ret_addr, int event, int tra, struct pt_regs *regs) event_ptr = (event_ptr + 1) & 15; if ((event == 2) && (evt == 0x160)) { - if (syscallno < NUM_SYSCALL_INFO_ENTRIES) - printk("Task %d: %s()\n", - current->pid, - syscall_info_table[syscallno].name); + if (syscallno < NUM_SYSCALL_INFO_ENTRIES) { + /* Store the syscall information to print later. We + * can't print this now - currently we're running with + * SR.BL=1, so we can't take a tlbmiss (which could occur + * in the console drivers under printk). + * + * Just overwrite old entries on ring overflow - this + * is only for last-hope debugging. */ + stored_syscalls[syscall_next].pid = current->pid; + stored_syscalls[syscall_next].syscall_number = syscallno; + syscall_next++; + syscall_next &= (N_STORED_SYSCALLS - 1); + } + } +} + +static void drain_syscalls(void) { + while (syscall_next_print != syscall_next) { + printk("Task %d: %s()\n", + stored_syscalls[syscall_next_print].pid, + syscall_info_table[stored_syscalls[syscall_next_print].syscall_number].name); + syscall_next_print++; + syscall_next_print &= (N_STORED_SYSCALLS - 1); } } void evt_debug2(unsigned int ret) { + drain_syscalls(); printk("Task %d: syscall returns %08x\n", current->pid, ret); } @@ -231,6 +265,8 @@ void evt_debug_ret_from_exc(struct pt_regs *regs) event_ptr = (event_ptr + 1) & 15; } +#endif /* CONFIG_POOR_MANS_STRACE */ + /* ======================================================================= */ void show_excp_regs(char *from, int trapnr, int signr, struct pt_regs *regs)