Bug 74041 - "Target is not suspended" in Target.getCThreads
Summary: "Target is not suspended" in Target.getCThreads
Status: NEW
Alias: None
Product: CDT
Classification: Tools
Component: cdt-debug (show other bugs)
Version: 2.0   Edit
Hardware: PC Windows XP
: P3 normal (vote)
Target Milestone: ---   Edit
Assignee: cdt-debug-inbox@eclipse.org CLA
QA Contact: Jonah Graham CLA
URL:
Whiteboard:
Keywords:
Depends on:
Blocks:
 
Reported: 2004-09-16 01:01 EDT by Keith Rollin CLA
Modified: 2020-09-04 15:18 EDT (History)
4 users (show)

See Also:


Attachments

Note You need to log in before you can comment on or make changes to this bug.
Description Keith Rollin CLA 2004-09-16 01:01:22 EDT
(The following was found in 2.0.1)

I've noticed Target.getCThreads throwing an exception when it posts the
info-threads command in order to get information about the current threads:

org.eclipse.cdt.debug.core.cdi.CDIException: Target is not suspended
	at org.eclipse.cdt.debug.mi.core.cdi.model.Target.getCThreads(Target.java:291)
	at org.eclipse.cdt.debug.mi.core.cdi.model.Target.getThreads(Target.java:315)
	at org.eclipse.cdt.debug.mi.core.cdi.model.Target.getCurrentThread(Target.java:300)
	at
org.eclipse.cdt.debug.internal.core.model.CDebugTarget.setCurrentThread(CDebugTarget.java:1739)
	at
org.eclipse.cdt.debug.internal.core.model.CDebugTarget.refreshThreads(CDebugTarget.java:749)
	at
org.eclipse.cdt.debug.internal.core.model.CDebugTarget.handleSuspendedEvent(CDebugTarget.java:1334)
	at
org.eclipse.cdt.debug.internal.core.model.CDebugTarget.handleDebugEvents(CDebugTarget.java:1049)
	at org.eclipse.cdt.debug.mi.core.cdi.EventManager.fireEvents(EventManager.java:245)
	at org.eclipse.cdt.debug.mi.core.cdi.EventManager.update(EventManager.java:216)
	at java.util.Observable.notifyObservers(Unknown Source)
	at org.eclipse.cdt.debug.mi.core.MISession.notifyObservers(MISession.java:492)
	at org.eclipse.cdt.debug.mi.core.EventThread.run(EventThread.java:46)

While I can't be sure, I can guess at the cause.  That's because I just ran into
a similar situation in some of my own code that extends CDT.  The deal is this:
shared library events are handled in RxThread by (a) creating some MIEvents that
describe the event, (b) having MISession fire those events by posting them to a
queue, and then (c) resuming execution of the debugged process.  The events
posted in step (b) are picked up by EventThread and routed to whomever wants
them.  However, when the objects receiving the event notification are called,
there's no guarantee as to where the RxThread has gotten to in its execution. 
That is, the debugged process may or may not have been restarted by the time a
particular object received notification of the event.  Thus, attempts to post
MICommands may or may not result in "Target is not suspended" exceptions.

Perhaps the canonical way for handling event notification is with something like
the following:

        target.incrementSuspendCount();
        try {
            handleEvent();
        } finally {
            target.decrementSuspendCount();
        }

With suspend counts, you take care of any problems with multiple threads trying
to suspend and resume the target.  Unfortunately, it doesn't take care of *how*
the target should be suspended (vis., the various ways that the target needs to
be resumed after handling a shared library event -- see latter half of
EventManager.processSharedLibEvent).

Another possibility would be to force all of the events that are posted by
EventManager.processSharedLibEvent to be completely routed by the time
EventManager.processSharedLibEvent tries to restart the debugged process.  That
might clear up a lot of problems, but would seem to require the addition of some
API to check the state of the queue holding the MIEvents or block until it
signals that it's empty.

But there might be problem with that approach, too.  If the event notification
handler needs to issue some MICommands, it will post them to the TxThread and
then wait for a reply to come through in RxThread.  But if RxThread is waiting
for all event notifications to be handled, you'll have a deadlock.

Unless there's a simple solution I'm overlooking (which is entirely possible), I
don't think I envy whoever is assigned this report... :-)
Comment 1 Keith Rollin CLA 2004-09-17 19:13:31 EDT
Thinking about the problem some more, perhaps a solution occurs to me.

The issue is that event notification handlers may expect that the debug target 
is suspended, allowing them to make queries on that target.  However, at least 
in the case of handling events generated as part of a "shared library event", 
the notification handlers can't know for sure if the debug target is 
suspended.  That's because the event notification is handled in one thread 
(the EventThread) while the shared library event is handled in another thread 
(the RxThread), which will restart the debug target at some indeterminate time 
relative to what's going on in EventThread.

Various possible approaches to a solution are presented in my original report, 
along with their serious drawbacks.  However, I think that a workable solution 
has occurred to me.

This approach is to move the restarting of the debug target from RxThread to 
EventThread in a way such that this restarting will occur after all event 
notification is handled.  This can be achieved by creating a new subclass of 
MIEvent and -- instead of executing all of that code in the second half of 
EventManager.processSharedLibEvent -- create an instance of this MIEvent 
subclass and post it to the MISession event queue after all the other MIEvents 
have been posted.  This MIEvent subclass would take care of executing the code 
that would otherwise be executed by EventManager.processSharedLibEvent.

This way, the RxThread is freed up to handle other incoming messages, and the 
debug target is restarted after the other MIEvents have been handled, allowing 
the handlers of those MIEvents to assume that the debug target is suspended 
and will stay suspended.
Comment 2 Keith Rollin CLA 2004-09-21 20:18:57 EDT
Following up with more information:

Some of my analysis was off the mark.  I had speculated that the cause was 
related to handling notifications in the context of a Shared Library Event, 
where the debug target was suspended and then resumed.  However, 
this "obviously" is not the case.  The stack trace shows that a SuspendedEvent 
is being handled.  But this kind of event is not sent out in the case of a 
Shared Library Event.  Rather, DestroyedEvents and CreatedEvents are sent 
out.  So that's not the cause of the problem.

However, the change I suggest (moving the code that resumes the debug target 
into an MIEvent) is probably still a good one to make.  I made the change 
myself in order to (a) attempt to fix the problem reported here, and (b) to 
fix the "similar situation" I alluded to in my original post.  While (a) was, 
of course, not fixed, (b) was.  So I still think it's a good change to make in 
the abstract.

In the meantime, I'm still not sure of the catalyst for the bug leading to the 
crash described in the original report.
Comment 3 Alain Magloire CLA 2004-09-22 17:19:42 EDT
Keith,
  you may or may not be aware of it but we are doing some
reengeneering of the CDI code including MI in the head branch

Feedback like this is very important to not do the same mistakes.
Will take a second look when back. Meanwhile cc'ing dave and mikhail
if you need a fix for the 2.0.x branch
Comment 4 Alain Magloire CLA 2004-10-31 20:47:25 EST
Let see if we can reproduce this one.
Comment 5 PalmSource Eclipse Bug Tracker CLA 2004-11-01 19:35:03 EST
Original submitter no longer with PalmSource.  Please direct any questions about
origin of bug to Brad.Jarvinen@palmsource.com (but Keith may still be in the
know if you want to try him too). 
Comment 6 Alain Magloire CLA 2005-07-21 16:54:11 EDT
We will need to reevaluate this for CDT-3.1.  Does
any folks from PalmSource can work with me to track this down.

Thanks
Comment 7 PalmSource Eclipse Bug Tracker CLA 2005-07-27 20:49:36 EDT
Hi Alain,

I'm working on trying to reproduce this.  So far I haven't had any luck and 
unfortunately the original reporter of the bug is no longer with PalmSource.

Thanks,
Ewa.
Comment 8 Alain Magloire CLA 2005-09-06 11:45:48 EDT
Returning to the pool.
Comment 9 Doug Schaefer CLA 2007-08-21 11:04:40 EDT
Future means you commit to fix it in the Future. Inboxes can't make committments. Moving to '--'.