]> Zhao Yanbai Git Server - minix.git/commitdiff
kernel: restore stacktraces
authorBen Gras <ben@minix3.org>
Fri, 4 Jan 2013 18:26:10 +0000 (18:26 +0000)
committerBen Gras <ben@minix3.org>
Mon, 7 Jan 2013 20:18:48 +0000 (20:18 +0000)
When processes have entered the kernel with one of the new
trap modes, %ebp is not valid, used for stacktraces, so we
need an alternative way to retrieve it to make the stacktraces
valid again.

kernel/arch/i386/exception.c
kernel/arch/i386/usermapped_glo_ipc.S

index d885cfcd1c84f91bcf5582f0fde748c16ce7646c..3a4064d8dad9004755d7b5944efa350e0e71caec 100644 (file)
@@ -312,8 +312,43 @@ static void proc_stacktrace_execute(struct proc *whichproc, reg_t v_bp, reg_t pc
  *===========================================================================*/
 void proc_stacktrace(struct proc *whichproc)
 {
+       u32_t use_bp;
+
+       if(whichproc->p_seg.p_kern_trap_style == KTS_NONE) {
+               printf("WARNING: stacktrace of running proecss\n");
+       }
+
+       switch(whichproc->p_seg.p_kern_trap_style) {
+               case KTS_SYSENTER:
+               case KTS_SYSCALL:
+               {
+                       u32_t sp = whichproc->p_reg.sp;
+
+                       /* Full context is not available in the p_reg
+                        * struct. Obtain it from the user's stack.
+                        * The use stack pointer is always available.
+                        * The fact that it's there, and the 16 byte offset,
+                        * is a dependency on the trap code in
+                        * kernel/arch/i386/usermapped_glo_ipc.S.
+                        */
+
+                       if(data_copy(whichproc->p_endpoint, sp+16,
+                         KERNEL, (vir_bytes) &use_bp,
+                               sizeof(use_bp)) != OK) {
+                               printf("stacktrace: aborting, copy failed\n");
+                               return;
+                       }
+
+                       break;
+               }
+               default:
+                       /* Full context is available; use the stored ebp */
+                       use_bp = whichproc->p_reg.fp;
+                       break;
+       }
+
 #if USE_SYSDEBUG
-       proc_stacktrace_execute(whichproc, whichproc->p_reg.fp, whichproc->p_reg.pc);
+       proc_stacktrace_execute(whichproc, use_bp, whichproc->p_reg.pc);
 #endif /* USE_SYSDEBUG */
 }
 
index 3df59df368efe057a92bfd076256a680884dcdbf..72d9bb8a94e097f561606ab35c105ae07b9c5af8 100644 (file)
@@ -29,6 +29,9 @@ ENTRY(usermapped_ ## name ## _sysenter)                                       ;\
        movl    %esp, %esi      /* kernel uses %esi for restored %esp */;\
        movl    $0f, %edx       /* kernel uses %edx for restored %eip */;\
        movl    $VEC, %edi      /* %edi to distinguish ipc/kerncall */  ;\
+       /* !!! There is a dependency of proc_stacktrace()               ;\
+        * on this stack layout; it needs to find %ebp on it.           ;\
+        */                                                             ;\
        SETARGS                 /* call-specific register setup */      ;\
        sysenter                /* disappear into kernel */             ;\
 0:                                                                     ;\
@@ -50,6 +53,9 @@ ENTRY(usermapped_ ## name ## _syscall)                                        ;\
        push    %esi                                                    ;\
        push    %edi                                                    ;\
        movl    $VEC, %edi      /* %edi to distinguish ipc/kerncall */  ;\
+       /* !!! There is a dependency of proc_stacktrace()               ;\
+        * on this stack layout; it needs to find %ebp on it.           ;\
+        */                                                             ;\
        SETARGS                 /* call-specific register setup */      ;\
        movl    %ecx, %edx      /* %ecx is clobbered by SYSCALL */      ;\
        syscall                 /* disappear into kernel */             ;\