Bug in asm-i386/processor.h: thread_saved_pc() ?

Jean Wolter (jw5@os.inf.tu-dresden.de)
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/