Messages in this thread Patch in this message | | | Subject | Bug in asm-i386/processor.h: thread_saved_pc() ? | From | Jean Wolter <> | Date | 29 Mar 1999 17:40:03 +0200 |
| |
Hello,
I tried to use <alt sysrequest showTasks> to get some information about a server lockup, but the PC field (which is supposed to contain the PC of a blocked process) looked rather bogus.
sched.c:show_task() uses thread_saved_pc() to get the program counter of a blocked process.
extern inline unsigned long thread_saved_pc(struct thread_struct *t) { return ((unsigned long *)t->esp)[3]; } It takes the stack pointer, gets ebp (which was saved last during switch_to()), and tries to fetch the program counter. Unfortunately the program counter is at ((unsigned long *)t->esp)[1], since the normal stack frame looks like this:
parameters return address ebp <-- ebp
But if show_task() is supposed to show the point where the process blocked, I would propose the following patch. It is modeled after (ripped of) proc/array.c.
Jean
--- processor.h.orig Mon Mar 29 16:53:24 1999 +++ processor.h Mon Mar 29 16:59:42 1999 @@ -305,11 +305,35 @@ } while (0) /* + * These bracket the sleeping functions.. + */ +extern void scheduling_functions_start_here(void); +extern void scheduling_functions_end_here(void); +#define first_sched ((unsigned long) scheduling_functions_start_here) +#define last_sched ((unsigned long) scheduling_functions_end_here) + +/* * Return saved PC of a blocked thread. */ extern inline unsigned long thread_saved_pc(struct thread_struct *t) { - return ((unsigned long *)t->esp)[3]; + unsigned long ebp, eip; + unsigned long stack_page; + int count = 0; + + stack_page = (unsigned long)t & ~8191UL; + + /* include/asm-i386/system.h:switch_to() pushes ebp last. */ + ebp = *(unsigned long *) t->esp; + do { + if (ebp < stack_page || ebp >= 8188+stack_page) + return 0; + eip = *(unsigned long *) (ebp+4); + if (eip < first_sched || eip >= last_sched) + return eip; + ebp = *(unsigned long *) ebp; + } while (count++ < 16); + return 0; } extern struct task_struct * alloc_task_struct(void); - To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majordomo@vger.rutgers.edu Please read the FAQ at http://www.tux.org/lkml/
| |