This is the mail archive of the
frysk@sources.redhat.com
mailing list for the frysk project.
Re: Test and fix for syscall observer adding (bug #3147)
Hi,
On Mon, 2006-09-04 at 14:32 +0200, Mark Wielaard wrote:
> On Fri, 2006-09-01 at 23:01 +0200, Mark Wielaard wrote:
> > For the testcase I can of course do some tricks and see if accept() is a
> > syscall or, if not, whether socketcall() is available and then select
> > based on the first argument of the syscall to see if it really is accept
> > (#5). But this seems 1) fragile and 2) looks like a general problem
> > people will have when using Syscall Observers.
>
> I worked around it for the test case by just using the SYSread call for
> now:
>
> 2006-09-04 Mark Wielaard <mark@klomp.org>
>
> * funit-syscall-running.c: Accept socket and read() for it.
>
> 2006-09-04 Mark Wielaard <mark@klomp.org>
>
> * TestSyscallRunning.java: Added back, use SYSread and write to
> Socket.
>
> For the testcase this is OK since it just tests something low-level. But
> I think in general we have to look how people will want to use the
> syscalls and whether or not to provide something more portable and
> higher level.
This test still failed sometimes as pointed out by
http://sourceware.org/bugzilla/show_bug.cgi?id=3193
It was actually a bug in the test case. I rewrote the testcase to test
for accept again (which is possible now cross-architecture thanks to
Yao) and the observer now explicitly keeps track of whether or not it is
inside the correct syscall.
2006-09-18 Mark Wielaard <mark@klomp.org>
Fixes bug #3193
* TestSyscallRunning (SyscallObserver): Take syscall name and
whether the syscall is in an entered state. Use Syscall.getByName()
for accept.
2006-09-18 Mark Wielaard <mark@klomp.org>
* funit-syscall-running.c: Don't read, just accept socket.
Tested on both x86 and x86_64.
This test does show that trying to keep track of syscalls in an observer
is a little fragile since the observer alone cannot know whether the
task is running in a syscall already. Since the Task(State) does know it
does make sense to expose this info to the observers.
Cheers,
Mark
Index: frysk/pkglibexecdir/funit-syscall-running.c
===================================================================
RCS file: /cvs/frysk/frysk-core/frysk/pkglibexecdir/funit-syscall-running.c,v
retrieving revision 1.2
diff -u -r1.2 funit-syscall-running.c
--- frysk/pkglibexecdir/funit-syscall-running.c 4 Sep 2006 12:36:49 -0000 1.2
+++ frysk/pkglibexecdir/funit-syscall-running.c 18 Sep 2006 09:57:58 -0000
@@ -75,9 +75,12 @@
printf("%d\n", ntohs (addr.sin_port));
fflush(stdout);
+ // Wait for the start sign
+ getchar();
+
+ // Accept connection.
struct sockaddr_in sai;
len = sizeof (sai);
- fflush(stderr);
int f = accept (fd, (struct sockaddr *) &sai, &len);
if (f == -1)
{
@@ -85,17 +88,5 @@
exit (-1);
}
- // Wait for the start sign
- getchar();
-
- char cs[1];
- // Keep reading from the socket till it is closed.
- ssize_t c = 1;
- while (c > 0)
- c = read(f, &cs, 1);
-
- if (c < 0)
- perror ("read");
-
- return c;
+ return f;
}
Index: frysk/proc/TestSyscallRunning.java
===================================================================
RCS file: /cvs/frysk/frysk-core/frysk/proc/TestSyscallRunning.java,v
retrieving revision 1.4
diff -u -r1.4 TestSyscallRunning.java
--- frysk/proc/TestSyscallRunning.java 11 Sep 2006 17:43:13 -0000 1.4
+++ frysk/proc/TestSyscallRunning.java 18 Sep 2006 09:57:58 -0000
@@ -42,8 +42,6 @@
import java.io.*;
import java.net.*;
-import frysk.sys.SyscallNum;
-
public class TestSyscallRunning
extends TestLib
{
@@ -120,14 +118,13 @@
public void testSyscallRunning() throws IOException
{
- // Get the port that will be listened on and connect to it.
+ // Get the port that will be listened on.
String line = in.readLine();
int port = Integer.decode(line).intValue();
- Socket s = new Socket("localhost", port);
final Task task = proc.getMainTask();
- final SyscallObserver syso = new SyscallObserver();
+ final SyscallObserver syso = new SyscallObserver("accept", task, false);
task.requestAddSyscallObserver(syso);
// Make sure the observer is properly installed.
@@ -168,7 +165,7 @@
// Now unblock and then attach another observer.
// Do all this on the eventloop so properly serialize calls.
- final SyscallObserver syso2 = new SyscallObserver();
+ final SyscallObserver syso2 = new SyscallObserver("accept", task, true);
Manager.eventLoop.add(new TaskEvent()
{
public void execute ()
@@ -199,10 +196,11 @@
// Sanity check
assertTrue("syso entered", syso.getEntered());
assertFalse("syso exited", syso.getExited());
- assertFalse("syso2 entered", syso2.getEntered());
+ assertTrue("syso2 entered", syso2.getEntered());
assertFalse("syso2 exited", syso2.getExited());
// Write something to the socket and close it so the syscall exits.
+ Socket s = new Socket("localhost", port);
OutputStream out = s.getOutputStream();
out.write(1);
out.flush();
@@ -236,19 +234,22 @@
private boolean added;
private boolean removed;
- SyscallObserver()
+ private final frysk.proc.Syscall syscall;
+
+ SyscallObserver(String call, Task task, boolean entered)
{
+ syscall = frysk.proc.Syscall.syscallByName(call, task);
+ this.entered = entered;
}
public Action updateSyscallEnter(Task task)
{
SyscallEventInfo syscallEventInfo = getSyscallEventInfo(task);
- int syscallNum = syscallEventInfo.number (task);
- if (syscallNum == SyscallNum.SYSread)
+ if (syscallEventInfo.getSyscall(task).equals(syscall))
{
- entered = true;
synchronized(monitor)
{
+ entered = true;
monitor.notifyAll();
return Action.BLOCK;
}
@@ -258,13 +259,11 @@
public Action updateSyscallExit(Task task)
{
- SyscallEventInfo syscallEventInfo = getSyscallEventInfo(task);
- int syscallNum = syscallEventInfo.number (task);
- if (syscallNum == SyscallNum.SYSread)
+ if (entered)
{
- exited = true;
synchronized(monitor)
{
+ exited = true;
monitor.notifyAll();
}
}