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: 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();
             }
 	}

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