This is the mail archive of the frysk@sources.redhat.com mailing list for the frysk project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

Re: Handling 'external' trap events


Hi Yao,

On Mon, 2006-10-16 at 20:40 +0800, Yao Qi wrote:
> With Yong's help, I pick up sigsetjmp/siglongjmp to skip that invalid
> instruction after it is executed, and to avoid that endless loop.
> 
> 2006-10-16  Yao Qi  <qiyaoltc@cn.ibm.com>
>  
>         * funit-breakpoints.c (trap_handler): Call siglongjmp to
>         * return.
>         (dummy): Call sigsetjmp to skip the invalid instruction after
>         it is executed for the first time on PPC64.

Nice to see that it works. This probably simulates better how real
programs handle SIGTRAP calls from faulting/illegal instructions. So I
would suggest to do this the same for all architectures (more common
code). I changed your patch a little so it does the same thing on
x86/x86_64. Seems to work fine here.

If you like this setup and it still works for you please check it in (I
will be away for 2 week).

Thanks,

Mark
Index: frysk-core/frysk/pkglibexecdir/funit-breakpoints.c
===================================================================
RCS file: /cvs/frysk/frysk-core/frysk/pkglibexecdir/funit-breakpoints.c,v
retrieving revision 1.5
diff -u -r1.5 funit-breakpoints.c
--- frysk-core/frysk/pkglibexecdir/funit-breakpoints.c	9 Oct 2006 02:08:20 -0000	1.5
+++ frysk-core/frysk/pkglibexecdir/funit-breakpoints.c	16 Oct 2006 14:35:01 -0000
@@ -44,6 +44,7 @@
 #include <stdio.h>
 #include <stdlib.h>
 #include <signal.h>
+#include <setjmp.h>
 
 // Counters for how many times the breakpoint functions have been called.
 // Used as sanity check to tell the tester the functions have actually ran.
@@ -57,6 +58,8 @@
 static int send_trap;
 static int received_trap;
 
+static sigjmp_buf env;
+
 static void
 trap_handler(int sig)
 {
@@ -67,6 +70,11 @@
     }
 
   received_trap++;
+
+  // Trap handler is triggered by inline invalide instruction in
+  // dummy().
+  if (received_trap % 2 == 0)
+    siglongjmp(env, SIGTRAP);
 }
 
 // Tries to trick frysk by sending trap signals and by having its
@@ -78,14 +86,26 @@
   kill (pid, SIGTRAP);
   send_trap++;
 
-  // Generating a trap event ourselves.
+  // Generating a trap event ourselves, simulating "bad code".  Setup
+  // a sigsetjump so we can handle it and return from this function
+  // safely when the signal handler uses longjmp. On some
+  // architectures the PC isn't incremented on invallid/trapping
+  // instructions. So this makes sure we skip it when we return.
+  if (sigsetjmp (env, 1) == 0)
+    {
 #if defined(__i386__) || defined(__x86_64__)
-  asm("int3");
+      asm("int3");
 #elif defined(__powerpc64__) || defined(__powerpc__)
-  asm(".long 0x7d821008");
+      asm(".long 0x7d821008");
 #else
-   #error unsuported architecture
+      #error unsuported architecture
 #endif
+    }
+  else
+    {
+      // Returned from signal handler through longjmp.
+      return;
+    }
 }
 
 static void

Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]