Bug 4889 - adding new codeObserver in updateHit causes java.lang.IllegalStateException: Already stepping
Summary: adding new codeObserver in updateHit causes java.lang.IllegalStateException: ...
Alias: None
Product: frysk
Classification: Unclassified
Component: general (show other bugs)
Version: unspecified
: P2 normal
Target Milestone: ---
Assignee: Unassigned
Depends on:
Blocks: 2229
  Show dependency treegraph
Reported: 2007-08-03 12:26 UTC by Petr Machata
Modified: 2007-08-15 11:08 UTC (History)
0 users

See Also:
Host: i686-pc-linux-gnu
Last reconfirmed:


Note You need to log in before you can comment on or make changes to this bug.
Description Petr Machata 2007-08-03 12:26:27 UTC

Adding new codeObserver in updateHit causes java.lang.IllegalStateException:
Already stepping.  The stack trace I'm getting:
Exception in thread "main" java.lang.IllegalStateException: Already stepping
   at frysk.proc.Breakpoint.prepareStep(fltrace)
   at frysk.proc.live.LinuxTaskState$Running.sendContinue(fltrace)
   at frysk.proc.live.LinuxTaskState$Running.handleStoppedEvent(fltrace)
   at frysk.proc.live.LinuxTask.processStoppedEvent(fltrace)
   at frysk.proc.live.LinuxWaitBuilder.stopped(fltrace)
   at frysk.sys.Wait.wait(fltrace)
   at frysk.sys.Wait.waitAll(fltrace)
   at frysk.event.WaitEventLoop.block(fltrace)
   at frysk.event.EventLoop.runEventLoop(fltrace)
   at frysk.event.EventLoop.run(fltrace)
   at frysk.util.Ltrace.trace(fltrace)
   at frysk.bindir.fltrace.run(fltrace)
   at frysk.bindir.fltrace.main(fltrace)

This doesn't seem to happen when requesting observation of already observed
state.  The problem also goes away when I do

      return Action.BLOCK;

intead of return Action.CONTINUE.  The problem also went away when something
like that was in effect:

      task.getProc().getMainTask().requestAddCodeObserver(this, retAddr);
      System.err.println("[" + task.getTaskId().intValue() + "]");

All this seems to point to the problem of frysk having "enough time" to do the
observer shenanigans, as is suggested by comments on several places.

`retAddr' given above could have been arbitrary, e.g. I tried to enter
0x080483b4, the address of main in my testing binary, so the problems wasn't in
that I'd request breakpoint inside data segment or something.
Comment 1 Mark Wielaard 2007-08-03 12:57:44 UTC
This is related/similar to bug #4747 with the difference that frysk itself is
responsible for generating the stop signal to install the breakpoint instead of
an external trigger.

This will be fixed with the fix for #4747. The "workaround":

      task.requestAddCodeObserver(observer, address);
      return Action.BLOCK;

Is most likely what you actually want. It makes sure that the observer is
installed and only after that the task is unblocked. If you use the sequence:

      task.requestAddCodeObserver(observer, address);
      return Action.CONTINUE;

The request to add the new observer is only pending and the task might already
be running long before the observer is installed (so you could miss hitting that
breakpoint). This is actually what is happening here.
Comment 2 Mark Wielaard 2007-08-10 11:23:35 UTC
New testcase added: frysk.proc.TestTaskObserverCode.testInstallCodeDuringCode
Comment 3 Mark Wielaard 2007-08-15 11:08:07 UTC
Fixed by:

2007-08-15  Mark Wielaard  <mwielaard@redhat.com>
    * getSetupAddress (getSetupAddress): New method.
    (stepAbort): Likewise.
    * TestTaskObserverCode.java (testCodeSignalInterrupt): Enable test.
    (testInstallCodeDuringCode): Likewise.
    (Symbol): New static helper class.
    (getGlobalLabelAddress): New helper method.
    (breakTest): New test harness for funit-raise.
    (testBreakDivZero): New test based on breakTest.
    (testBreakIllegalAddress): Likewise.
    (testBreakIllegalInstruction): Likewise.
    (testBreakSignalTerminate): Likewise.
    (testBreakSignalIgnore): Likewise.
    (AttachedObserver.task): New field.
    (updateAttached): Set task field.
    (TerminatingObserver.task): New field.
    (TerminatingObserver.signal): Likewise.
    (TerminatingObserver.value): Likewise.
    (TerminatingObserver.updateTerminating): Set new fields.

2007-08-15  Mark Wielaard  <mwielaard@redhat.com>

    * LinuxTaskState.java (Stepping.handleTrappedpEvent): Always check
    (checkBreakpointStepping): New helper method.
    (handleSignaledEvent): Use checkBreakpointStepping before
    (handleStoppedEvent): Likewise.

2007-08-15  Mark Wielaard  <mwielaard@redhat.com>

    * funit-raise.S: New test.