* Handling 'external' trap events
@ 2006-10-05 12:08 Mark Wielaard
2006-10-09 2:10 ` Yao Qi
0 siblings, 1 reply; 8+ messages in thread
From: Mark Wielaard @ 2006-10-05 12:08 UTC (permalink / raw)
To: frysk
[-- Attachment #1: Type: text/plain, Size: 1454 bytes --]
Hi,
This fixes bug #3256. We now treat trap events that don't correspond to
any of our own breakpoint addresses as normal trap signals. On which you
can now also install a signal observer. The funit-breakpoints test prog
now installs a trap signal handler and generates trap signals and
inserts trap instructions itself to check whether that works correctly
when traced by frysk.
2006-10-05 Mark Wielaard <mark@klomp.org>
* funit-breakpoints.c (trap_handler): New function.
(dummy): Send trap signal and generate trap event.
(main): Install trap signal handler.
2006-10-05 Mark Wielaard <mark@klomp.org>
* Breakpoint.java (getAddress): New method.
* BreakpointAddresses.java (getCodeObservers): Return null when
no observers installed on the specified address.
* Task.java (steppingBreakpoint): New package private field.
(notifyCodeBreakpoint): Return -1 when no observers at specified
address.
* TaskState.java (Running.steppingBreakpoint): Removed field.
(Running.handleTrappedEvent): Check whether trap is for one
of our own installed breakpoints, handle it as a regular trap
signal to process otherwise.
Tested on x86 and x86_64. There is code for powerpc64, but I don't have
such a machine so couldn't actually test there. If someone could try and
inspect the code path for powerpc64 that would be nice.
Phil, this should also solve your problems with tracing emacs.
Committed,
Mark
[-- Attachment #2: breakpoint-sig-trap.patch --]
[-- Type: text/x-patch, Size: 7211 bytes --]
Index: frysk-core/frysk/pkglibexecdir/funit-breakpoints.c
===================================================================
RCS file: /cvs/frysk/frysk-core/frysk/pkglibexecdir/funit-breakpoints.c,v
retrieving revision 1.3
diff -u -r1.3 funit-breakpoints.c
--- frysk-core/frysk/pkglibexecdir/funit-breakpoints.c 29 Sep 2006 16:47:23 -0000 1.3
+++ frysk-core/frysk/pkglibexecdir/funit-breakpoints.c 5 Oct 2006 11:51:59 -0000
@@ -42,13 +42,51 @@
#include <fcntl.h>
#include <unistd.h>
#include <stdio.h>
+#include <stdlib.h>
+#include <signal.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.
static int bp1;
static int bp2;
-static void dummy() { /* nop */ }
+static pid_t pid;
+
+// Counters to check whether real and received Trap signals match
+// and don't interfere with the breakpoints inserted by frysk.
+static int send_trap;
+static int received_trap;
+
+static void
+trap_handler(int sig)
+{
+ if (sig != SIGTRAP)
+ {
+ fprintf (stderr, "Wrong signal recieved %d\n", sig);
+ exit (-1);
+ }
+
+ received_trap++;
+}
+
+// Tries to trick frysk by sending trap signals and by having its
+// own trap instruction.
+static void
+dummy()
+{
+ // Sending ourselves a trap signal.
+ kill (pid, SIGTRAP);
+ send_trap++;
+
+ // Generating a trap event ourselves.
+#if defined(__i386__) || defined(__x86_64__)
+ asm("int3");
+#elif defined(__powerpc64__)
+ asm(".long 0x7d821008");
+#else
+ #error unsuported architecture
+#endif
+}
static void
first_breakpoint_function ()
@@ -67,6 +105,10 @@
int
main (int argc, char *argv[], char *envp[])
{
+ pid = getpid();
+ received_trap = 0;
+ send_trap = 0;
+ signal (SIGTRAP, &trap_handler);
// The number of runs the tester wants us to do.
// Zero when we should terminate.
@@ -116,6 +158,13 @@
fflush(stdout);
}
+ // Have our own trap signals and trap instructions triggered?
+ if (2 * send_trap != received_trap)
+ {
+ fprintf (stderr, "send: %d, recv: %d\n", send_trap, received_trap);
+ exit (-1);
+ }
+
// Finally re-exec ourselves to show breakpoints are gone.
// When called with an argument then we are execing ourselves just to
// do a little testrun (all breakpoints should be cleared now).
Index: frysk-core/frysk/proc/Breakpoint.java
===================================================================
RCS file: /cvs/frysk/frysk-core/frysk/proc/Breakpoint.java,v
retrieving revision 1.3
diff -u -r1.3 Breakpoint.java
--- frysk-core/frysk/proc/Breakpoint.java 5 Oct 2006 11:31:53 -0000 1.3
+++ frysk-core/frysk/proc/Breakpoint.java 5 Oct 2006 11:51:59 -0000
@@ -96,6 +96,11 @@
return breakpoint;
}
+ public long getAddress()
+ {
+ return address;
+ }
+
/**
* Installs breakpoint. Caller must make sure there is no breakpoint set
* at that address yet and that install() is not called again till remove()
Index: frysk-core/frysk/proc/BreakpointAddresses.java
===================================================================
RCS file: /cvs/frysk/frysk-core/frysk/proc/BreakpointAddresses.java,v
retrieving revision 1.3
diff -u -r1.3 BreakpointAddresses.java
--- frysk-core/frysk/proc/BreakpointAddresses.java 29 Sep 2006 16:47:23 -0000 1.3
+++ frysk-core/frysk/proc/BreakpointAddresses.java 5 Oct 2006 11:51:59 -0000
@@ -136,7 +136,7 @@
/**
* Called by the Proc when it has trapped a breakpoint. Returns an
* Iterator of TaskObserver.Code observers interested in the given
- * address.
+ * address or null when no Code observer was installed on this address.
*/
Iterator getCodeObservers(long address)
{
@@ -144,7 +144,7 @@
Breakpoint breakpoint = Breakpoint.create(address, proc);
ArrayList list = (ArrayList) map.get(breakpoint);
if (list == null)
- throw new IllegalArgumentException();
+ return null;
// Return the cloned list of observers in case the Code observer
// wants to add or remove itself or a new observer to that same
Index: frysk-core/frysk/proc/Task.java
===================================================================
RCS file: /cvs/frysk/frysk-core/frysk/proc/Task.java,v
retrieving revision 1.101
diff -u -r1.101 Task.java
--- frysk-core/frysk/proc/Task.java 29 Sep 2006 16:47:24 -0000 1.101
+++ frysk-core/frysk/proc/Task.java 5 Oct 2006 11:51:59 -0000
@@ -924,9 +924,15 @@
proc.requestDeleteCodeObserver(this, codeObservers, o, a);
}
+ // Whether we are currently stepping over a breakpoint.
+ // Used in the running task state when a trap event occurs after
+ // a step has been issued. Null when no step is being performed.
+ Breakpoint steppingBreakpoint;
+
/**
* Notify all Code observers of the breakpoint. Return the number of
- * blocking observers.
+ * blocking observers or -1 if no Code observer were installed on this
+ * address.
*/
int notifyCodeBreakpoint (long address)
{
@@ -934,6 +940,9 @@
new Object[] { this, Long.valueOf(address) });
Iterator i = proc.breakpoints.getCodeObservers(address);
+ if (i == null)
+ return -1;
+
while (i.hasNext())
{
TaskObserver.Code observer = (TaskObserver.Code) i.next();
Index: frysk-core/frysk/proc/TaskState.java
===================================================================
RCS file: /cvs/frysk/frysk-core/frysk/proc/TaskState.java,v
retrieving revision 1.118
diff -u -r1.118 TaskState.java
--- frysk-core/frysk/proc/TaskState.java 4 Oct 2006 21:30:09 -0000 1.118
+++ frysk-core/frysk/proc/TaskState.java 5 Oct 2006 11:51:59 -0000
@@ -44,6 +44,8 @@
import java.util.Collection;
import java.util.Iterator;
+import frysk.sys.Sig;
+
/**
* The task state machine.
*/
@@ -958,9 +960,6 @@
return this;
}
- // Whether we are currently stepping over a breakpoint.
- private Breakpoint steppingBreakpoint;
-
/**
* Handles traps caused by breakpoints. If there are any Code
* observers at the address of the trap they get notified. If
@@ -973,10 +972,15 @@
{
logger.log (Level.FINE, "{0} handleTrappedEvent\n", task);
+ // To be fully correct we should also check that the 'current'
+ // instruction is right 'after' the breakpoint. Otherwise it could
+ // actually be a trap generated by the instruction we are currently
+ // stepping. FIXME.
+ Breakpoint steppingBreakpoint = task.steppingBreakpoint;
if (steppingBreakpoint != null)
{
steppingBreakpoint.stepDone(task);
- steppingBreakpoint = null;
+ task.steppingBreakpoint = null;
sendContinue(task, 0);
return this;
}
@@ -993,14 +997,19 @@
}
int blockers = task.notifyCodeBreakpoint(address);
- if (blockers == 0)
+ if (blockers == -1)
+ {
+ // This is not a trap event generated by us.
+ return handleSignaledEvent (task, Sig.TRAP_);
+ }
+ else if (blockers == 0)
{
try
{
Breakpoint bp = Breakpoint.create(address, task.getProc());
bp.prepareStep(task);
task.sendStepInstruction(0);
- steppingBreakpoint = bp;
+ task.steppingBreakpoint = bp;
return this;
}
catch (TaskException te)
^ permalink raw reply [flat|nested] 8+ messages in thread
* Re: Handling 'external' trap events
2006-10-05 12:08 Handling 'external' trap events Mark Wielaard
@ 2006-10-09 2:10 ` Yao Qi
2006-10-09 7:08 ` Mark Wielaard
0 siblings, 1 reply; 8+ messages in thread
From: Yao Qi @ 2006-10-09 2:10 UTC (permalink / raw)
To: frysk
[-- Attachment #1: Type: text/plain, Size: 1110 bytes --]
On Thu, Oct 05, 2006 at 02:08:10PM +0200, Mark Wielaard wrote:
>
> 2006-10-05 Mark Wielaard <mark@klomp.org>
>
> * funit-breakpoints.c (trap_handler): New function.
> (dummy): Send trap signal and generate trap event.
> (main): Install trap signal handler.
>
> Tested on x86 and x86_64. There is code for powerpc64, but I don't have
> such a machine so couldn't actually test there. If someone could try and
> inspect the code path for powerpc64 that would be nice.
Hi, Mark,
Here is a small patch to make funit-breakpoints.c be built on ppc64 in
32-bit mode (for bi-arch test).
2006-10-08 Yao Qi <qiyaoltc@cn.ibm.com>
* funit-breakpoints.c (dummy): Generate trap event for
powerpc32 as well.
Committed!
After this patch applied and rebuild frysk, frysk.proc.TestBreakpoints
will hang on testHitAndRun as follows,
[qiyao@plinuxt6 ~/build-frysk/frysk-core]$ ./TestRunner frysk.proc.TestBreakpoints
frysk.proc.TestBreakpoints
Running testHitAndRun(frysk.proc.TestBreakpoints) ...
Add it in my todo list! If you could give us some help, we do not
mind. :-)
--
Yao Qi
[-- Attachment #2: break.patch --]
[-- Type: text/plain, Size: 699 bytes --]
Index: frysk-core/frysk/pkglibexecdir/funit-breakpoints.c
===================================================================
RCS file: /cvs/frysk/frysk-core/frysk/pkglibexecdir/funit-breakpoints.c,v
retrieving revision 1.4
diff -u -r1.4 funit-breakpoints.c
--- frysk-core/frysk/pkglibexecdir/funit-breakpoints.c 5 Oct 2006 12:06:48 -0000 1.4
+++ frysk-core/frysk/pkglibexecdir/funit-breakpoints.c 8 Oct 2006 09:46:18 -0000
@@ -81,7 +81,7 @@
// Generating a trap event ourselves.
#if defined(__i386__) || defined(__x86_64__)
asm("int3");
-#elif defined(__powerpc64__)
+#elif defined(__powerpc64__) || defined(__powerpc__)
asm(".long 0x7d821008");
#else
#error unsuported architecture
^ permalink raw reply [flat|nested] 8+ messages in thread
* Re: Handling 'external' trap events
2006-10-09 2:10 ` Yao Qi
@ 2006-10-09 7:08 ` Mark Wielaard
2006-10-11 3:16 ` Yao Qi
0 siblings, 1 reply; 8+ messages in thread
From: Mark Wielaard @ 2006-10-09 7:08 UTC (permalink / raw)
To: Yao Qi; +Cc: frysk
Hi Yao,
On Mon, 2006-10-09 at 10:09 +0800, Yao Qi wrote:
> On Thu, Oct 05, 2006 at 02:08:10PM +0200, Mark Wielaard wrote:
> > Tested on x86 and x86_64. There is code for powerpc64, but I don't have
> > such a machine so couldn't actually test there. If someone could try and
> > inspect the code path for powerpc64 that would be nice.
>
> Here is a small patch to make funit-breakpoints.c be built on ppc64 in
> 32-bit mode (for bi-arch test).
>
> 2006-10-08 Yao Qi <qiyaoltc@cn.ibm.com>
>
> * funit-breakpoints.c (dummy): Generate trap event for
> powerpc32 as well.
Thanks. I wasn't sure whether the same could be used on both
architectures.
> After this patch applied and rebuild frysk, frysk.proc.TestBreakpoints
> will hang on testHitAndRun as follows,
> [qiyao@plinuxt6 ~/build-frysk/frysk-core]$ ./TestRunner frysk.proc.TestBreakpoints
> frysk.proc.TestBreakpoints
> Running testHitAndRun(frysk.proc.TestBreakpoints) ...
>
> Add it in my todo list! If you could give us some help, we do not
> mind. :-)
I don't know what could cause this immediately. First thing to try is
probably to add some debug fprintf(stderr) "sending signal", "illegal
instruction", "received signal", etc. in the funit-breakpoints.c dummy()
and trap_handler() functions to see if the sending of signals and the
illegal instruction traps events are send and received properly.
combined with ./TestRunner -c FINE that hopefully gives you a clue what
is going on.
Cheers,
Mark
^ permalink raw reply [flat|nested] 8+ messages in thread
* Re: Handling 'external' trap events
2006-10-09 7:08 ` Mark Wielaard
@ 2006-10-11 3:16 ` Yao Qi
2006-10-11 11:01 ` Mark Wielaard
0 siblings, 1 reply; 8+ messages in thread
From: Yao Qi @ 2006-10-11 3:16 UTC (permalink / raw)
To: frysk
[-- Attachment #1: Type: text/plain, Size: 2537 bytes --]
On Mon, Oct 09, 2006 at 09:08:01AM +0200, Mark Wielaard wrote:
> Hi Yao,
>
> On Mon, 2006-10-09 at 10:09 +0800, Yao Qi wrote:
> > On Thu, Oct 05, 2006 at 02:08:10PM +0200, Mark Wielaard wrote:
> After this patch applied and rebuild frysk, frysk.proc.TestBreakpoints
> > will hang on testHitAndRun as follows,
> > [qiyao@plinuxt6 ~/build-frysk/frysk-core]$ ./TestRunner frysk.proc.TestBreakpoints
> > frysk.proc.TestBreakpoints
> > Running testHitAndRun(frysk.proc.TestBreakpoints) ...
> >
> > Add it in my todo list! If you could give us some help, we do not
> > mind. :-)
>
> I don't know what could cause this immediately. First thing to try is
> probably to add some debug fprintf(stderr) "sending signal", "illegal
> instruction", "received signal", etc. in the funit-breakpoints.c dummy()
> and trap_handler() functions to see if the sending of signals and the
> illegal instruction traps events are send and received properly.
> combined with ./TestRunner -c FINE that hopefully gives you a clue what
> is going on.
Hi, Mark,
Thanks for your advice, and I make some progress with your help.
Firstly, I find that dummy() is called endlessly unless I remove that
inline asm to generate a SIGTRAP, asm(".long 0x7d821008").
And then, I add System.err.println(Long.toHexString(address)) in
getCodeObservers(long address) in BreakpointsAddress.java. When I run
this case, the output is always 100009c0, which is the address of that
inline asm in dummy().
Now, both "int 3" on x86 and ".long 0x7d821008" on ppc64 could
generate a SIGTRAP, but with the *different* side-effect. "int 3",
which is a valid instruction, cause a SIGTRAP and program counter
increment, but ".long 0x7d821008", which is an *invalid*
instruction, cause a SIGTRAP but *no* update to program counter.
(The following part is my guesswork. If I am wrong, free to correct
me)
when frysk core get a SIGTRAP, could not find observers installed
on the specified address, frysk core will resume the program from the
unfinished instruction(on powerpc), which is still an invalid
instruction. So a endless loop is made.
I could not figure out how to ask cpu to skip this invalid
instruction to avoid endless loop after hit it for the first time.
So I comment out that inlined asm as a workaround in this patch.
2006-10-11 Yao Qi <qiyaoltc@cn.ibm.com>
* funit-breakpoints.c (dummy): Remove inline asm that generate
SIGTRAP for powerpc.
(main): Change the condition according to the change above.
OK to commit? Thanks!
--
Yao Qi
[-- Attachment #2: breakpoint.patch --]
[-- Type: text/plain, Size: 1118 bytes --]
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 11 Oct 2006 02:20:57 -0000
@@ -82,10 +82,11 @@
#if defined(__i386__) || defined(__x86_64__)
asm("int3");
#elif defined(__powerpc64__) || defined(__powerpc__)
- asm(".long 0x7d821008");
+ // asm(".long 0x7d821008");
#else
#error unsuported architecture
#endif
+
}
static void
@@ -157,9 +158,12 @@
printf("%d\n", bp2);
fflush(stdout);
}
-
+#if defined(__i386__) || defined(__x86_64__)
// Have our own trap signals and trap instructions triggered?
if (2 * send_trap != received_trap)
+#elif defined(__powerpc64__) || defined(__powerpc__)
+ if (send_trap != received_trap)
+#endif
{
fprintf (stderr, "send: %d, recv: %d\n", send_trap, received_trap);
exit (-1);
^ permalink raw reply [flat|nested] 8+ messages in thread
* Re: Handling 'external' trap events
2006-10-11 3:16 ` Yao Qi
@ 2006-10-11 11:01 ` Mark Wielaard
2006-10-16 12:41 ` Yao Qi
0 siblings, 1 reply; 8+ messages in thread
From: Mark Wielaard @ 2006-10-11 11:01 UTC (permalink / raw)
To: Yao Qi; +Cc: frysk
Hi Yao,
On Wed, 2006-10-11 at 11:15 +0800, Yao Qi wrote:
> Now, both "int 3" on x86 and ".long 0x7d821008" on ppc64 could
> generate a SIGTRAP, but with the *different* side-effect. "int 3",
> which is a valid instruction, cause a SIGTRAP and program counter
> increment, but ".long 0x7d821008", which is an *invalid*
> instruction, cause a SIGTRAP but *no* update to program counter.
Aha. I didn't realize that.
> (The following part is my guesswork. If I am wrong, free to correct
> me)
> when frysk core get a SIGTRAP, could not find observers installed
> on the specified address, frysk core will resume the program from the
> unfinished instruction(on powerpc), which is still an invalid
> instruction. So a endless loop is made.
If no observers are installed on the specified address then we make the
program handle the sigtrap. See TaskState.Running.handleTrapEvent():
int blockers = task.notifyCodeBreakpoint(address);
if (blockers == -1)
{
// This is not a trap event generated by us.
return handleSignaledEvent (task, Sig.TRAP_);
}
And in this case the funit-breakpoints.c (trap_handler) does nothing
fancy and just returns. Which on a x86 means after the instruction that
trapped, but as you found out on powerpc means at the same trapping
instruction.
> I could not figure out how to ask cpu to skip this invalid
> instruction to avoid endless loop after hit it for the first time.
> So I comment out that inlined asm as a workaround in this patch.
>
> 2006-10-11 Yao Qi <qiyaoltc@cn.ibm.com>
>
> * funit-breakpoints.c (dummy): Remove inline asm that generate
> SIGTRAP for powerpc.
> (main): Change the condition according to the change above.
>
> OK to commit? Thanks!
It think this is the wrong thing to do. We should really skip the
illegal instruction from the trap handler in funit-breakpoints.c. What
we are after is using breakpoints with a program that handles its own
sig trap events. Maybe a good way to simulate this is using setjmp and
longjmp to return from the trap signal handler. That should be platform
independent.
Cheers,
Mark
^ permalink raw reply [flat|nested] 8+ messages in thread
* Re: Handling 'external' trap events
2006-10-11 11:01 ` Mark Wielaard
@ 2006-10-16 12:41 ` Yao Qi
2006-10-16 14:39 ` Mark Wielaard
0 siblings, 1 reply; 8+ messages in thread
From: Yao Qi @ 2006-10-16 12:41 UTC (permalink / raw)
To: frysk
[-- Attachment #1: Type: text/plain, Size: 1368 bytes --]
On Wed, Oct 11, 2006 at 01:01:25PM +0200, Mark Wielaard wrote:
>
> It think this is the wrong thing to do. We should really skip the
> illegal instruction from the trap handler in funit-breakpoints.c. What
> we are after is using breakpoints with a program that handles its own
> sig trap events. Maybe a good way to simulate this is using setjmp and
> longjmp to return from the trap signal handler. That should be platform
> independent.
>
Hi, Mark,
Thanks for your explanation on SyscallObserver and advise on setjmp/longjmp
to skip that instruction.
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.
Now, test it on x86 and ppc64 rawhide.
[qiyao@plinuxt6 ~/build-frysk/frysk-core]$ ./TestRunner frysk.proc.TestBreakpointsRunning
testHitAndRun(frysk.proc.TestBreakpoints) ...
PASS
Running testInsertRemove(frysk.proc.TestBreakpoints) ...<<BROKEN http://sourceware.org/bugzilla/show_bug.cgi?id=3240 >>PASS
Running testAddLots(frysk.proc.TestBreakpoints) ...PASS
Time: 1.516
OK (3 tests)
OK to commit? Thanks!!
--
Yao Qi
[-- Attachment #2: funit-breakpoint.patch --]
[-- Type: text/plain, Size: 1816 bytes --]
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 12:02:24 -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.
@@ -56,6 +57,10 @@
// and don't interfere with the breakpoints inserted by frysk.
static int send_trap;
static int received_trap;
+#if defined(__powerpc64__) || defined(__powerpc__)
+int i;
+sigjmp_buf env;
+#endif
static void
trap_handler(int sig)
@@ -67,6 +72,13 @@
}
received_trap++;
+
+#if defined(__powerpc64__) || defined(__powerpc__)
+ // Trap handler is triggered by inline invalide instruction in
+ // dummy().
+ if (received_trap%2 == 0)
+ siglongjmp(env, SIGTRAP);
+#endif
}
// Tries to trick frysk by sending trap signals and by having its
@@ -82,7 +94,14 @@
#if defined(__i386__) || defined(__x86_64__)
asm("int3");
#elif defined(__powerpc64__) || defined(__powerpc__)
- asm(".long 0x7d821008");
+ // Make sure this inline asm could be skipped after it is executed
+ // for the frist time. As this inline asm code could cause a SIGTRAP,
+ // the singal handler trap_handler() could call longjmp to return SIGTRAP
+ // here to skip this inline asm code.
+ i = 0;
+ i = sigsetjmp(env, 1);
+ if (i == 0)
+ asm(".long 0x7d821008");
#else
#error unsuported architecture
#endif
^ permalink raw reply [flat|nested] 8+ messages in thread
* Re: Handling 'external' trap events
2006-10-16 12:41 ` Yao Qi
@ 2006-10-16 14:39 ` Mark Wielaard
2006-10-19 3:43 ` Yao Qi
0 siblings, 1 reply; 8+ messages in thread
From: Mark Wielaard @ 2006-10-16 14:39 UTC (permalink / raw)
To: Yao Qi; +Cc: frysk
[-- Attachment #1: Type: text/plain, Size: 887 bytes --]
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
[-- Attachment #2: funit-breakpoint.patch --]
[-- Type: text/x-patch, Size: 1955 bytes --]
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
^ permalink raw reply [flat|nested] 8+ messages in thread
* Re: Handling 'external' trap events
2006-10-16 14:39 ` Mark Wielaard
@ 2006-10-19 3:43 ` Yao Qi
0 siblings, 0 replies; 8+ messages in thread
From: Yao Qi @ 2006-10-19 3:43 UTC (permalink / raw)
To: frysk
On Mon, Oct 16, 2006 at 04:38:42PM +0200, Mark Wielaard wrote:
> 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).
Hi, Mark,
The more common code is more portable on other new platform if we plan
to support, and your setup is fine to me.
Test your patch on x86/x86_64/ppc64, and check it in.
--
Yao Qi
^ permalink raw reply [flat|nested] 8+ messages in thread
end of thread, other threads:[~2006-10-19 3:43 UTC | newest]
Thread overview: 8+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2006-10-05 12:08 Handling 'external' trap events Mark Wielaard
2006-10-09 2:10 ` Yao Qi
2006-10-09 7:08 ` Mark Wielaard
2006-10-11 3:16 ` Yao Qi
2006-10-11 11:01 ` Mark Wielaard
2006-10-16 12:41 ` Yao Qi
2006-10-16 14:39 ` Mark Wielaard
2006-10-19 3:43 ` Yao Qi
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).