[prev in list] [next in list] [prev in thread] [next in thread] 

List:       kde-devel
Subject:    Re: Execution replay for Qt/KDE applications
From:       "Oliver Oppitz" <o.oppitz () web ! de>
Date:       2004-10-21 19:39:26
Message-ID: opsf8jj0vali378s () smtp ! web ! de
[Download RAW message or body]

On 21 Oct 2004 09:19:46 -0000, <kde-devel-request@mail.kde.org> wrote:

>> To guarantee an identical replay one needs reconstruct the exact call
>> graph i.e. insert the invents in the same invocation of the event loop.
> That's only one solution to the problem (which would involve some kind
> of valgrind integration - a rather complex and non-portable solution...).
I do not see any need for valdgrind. There is another (conceptually)  
simple solution. Assuming the much simplified event loop looks as follows:

void EventLoop() {
   for(;;) {
      QEvent* event;
      while((event=getEvent())!=NULL) {
	  handleEvent(event);
      }
      doOtherThings();
    }
}

I assume here that getEvent() returns NULL if there is no pending event.  
What we see is, that depending on the timing when some events A,B,C,D are  
posted,  doOtherThings() may be called before A, between A & B, between B  
& C ... or even after D. That is the timing dependency I meant.

Now, if doOtherThings() interacts with the event handlers we may see  
faults during the execution but not during replay (or vice versa). A  
solution (for single-threaded applications) is:

// EventLoop for __Execution __
void EventLoop() {
   static int invocationCounter=0;
   for(;;) {
      QEvent* event;
      while((event=getEvent())!=NULL) {
	  handleEvent(event);
         saveEventToFile(event, invocationCounter++);  // record Event on  
Disk
      }
      doOtherThings();
   }
}

// EventLoop for __Replay__
void EventLoop() {
   static int invocationCounter = 0;
   for(;;) {
    QEvent* event;
    while(event=readEventFromDisk()) {  // EOF not handled ;-)
       int c = readInvocationCounterFromDisk();
	if (invocationCounter++ == c) {
	    handleEvent(event);
       } else {  // This branch is called when there was no event is  
available
                 // in the execution phase. Therefore we jump to  
doOtherThings()
	   unReadEventFromDisk(event); // ugly
	   break;
       }
    }
    doOtherThings();
}

This way the event is handled during the same invocation of the while-loop  
like during the execution. So we reconstruct the call graph i.e. the  
ordering/interleaving of function calls between handleEvent() and  
doOtherThings(). However, we do not reconstruct the timing: this would be  
a "full speed" replay. I must admit that I did not have a thorough look on  
the Qt source yet, so maybe it all does not work in practice. But  
conceptually it should do the trick ;-)

> Another solution (provided by KDX) is to insert synchronization points.
> While recording you can say "now wait for this widget to exist" or
> "wait for this widget to have the property foo with value bar", etc.
Sure, inserting sync points manually is a way to do it. This IMHO is  
mostly useful for test scripts where you need to define probes anyway.

>> Also, an execution-replay tool would need to capture all input from  
>> files
>> that the program works on. Does KDExecutor do this?
> I'm not sure, actually. Kalle?
I am positive about this. Assume the user opens a file in an editor. If  
the file is not there (or modified) during the replay, the program will  
behave differently.

Regards, Oliver


-- 

----------------------------------------------------------------------------
"To dare is to lose foothold a moment
  not to dare os to lose one self" by S.Kierkegaard

 
>> Visit http://mail.kde.org/mailman/listinfo/kde-devel#unsub to unsubscribe <<
[prev in list] [next in list] [prev in thread] [next in thread] 

Configure | About | News | Add a list | Sponsored by KoreLogic