Community
Participate
Working Groups
(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... :-)
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.
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.
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
Let see if we can reproduce this one.
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).
We will need to reevaluate this for CDT-3.1. Does any folks from PalmSource can work with me to track this down. Thanks
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.
Returning to the pool.
Future means you commit to fix it in the Future. Inboxes can't make committments. Moving to '--'.