[
Date Prev][
Date Next][
Thread Prev][
Thread Next][
Date Index][
Thread Index]
[
List Home]
[cdt-dev] Resuming from Shared Library Event
|
I have a question about the processing of a Shared Library event, in
particular, what's happening in EventManager.processSharedLibEvent.
As I read it, the function can be broken down into three parts:
1. Install any deferred breakpoints that reside in the just-loaded library.
2. Determine how execution should be restarted, based on the user's
last action (that is, is the user doing a Step Into, Step Over, Step
Return, or Continue).
3. Restart the application.
Unfortunately, I think there are problems with that last step. If
Step 2 determined that it needed to restart a Continue command, then
that command is performed immediately. However, for any other type
of restart, a lot of thread and stack munging takes place. It seems
that we (attempt to) get the current thread, the ID of that that
thread, and the stack of the thread. We then ask the debugged
process for the current stack level. This stack level number is then
used to create a different stack level number assuming that counting
starts from the end of the stack other than what gdb assumes.
Finally, we select the "current" thread, select the stack frame, and
issue the command to restart the application.
I think that all that thread and stack setting takes place because
the proper context needs to be established in order to restart the
Step, Next, and Finish commands. However, it doesn't seem to take
into account the possibility that the Shared Library event is taking
place in a different thread than the one in which the Step, Next, or
Finish command was issued in the first place.
Take the case I'm looking into right now. My application has 64
threads, with the 63rd thread (with Thread ID #92) being one in which
I'm performing a Step Out operation. Before that operation can
complete, Thread ID #1 loads a shared library, issuing a Shared
Library event.
Now, when processSharedLibEvent is called and tries to resume the
Step Out command, it gets the "current thread". This query returns
an object referring to Thread ID #92 where I was doing the Step Out.
When that thread object is used to get the "current stack frame", it
returns a record indicating the function in which I issued the Step
Out command, which is in the 42nd stack frame record. However, later
in the function, we query the debugged process for stack depth info.
This query indicates that the stack is only 5 levels deep, even
though I know it's at least 42 in the context of the Step Out
operation. Adding some debugging code here, I see that gdb thinks
that the current thread is Thread ID #1, not Thread ID #92 that CDT
thinks it is. With this mixed up information, processSharedLibEvent
calculates miLevel using the current depth of Thread ID #1 (which is
5) and the frame level of Thread ID #92 (which is 42), leading to a
negative number (-38). Because the negative number is, well,
negative, later code refuses to issue the command that restarts the
debugged process.
It seems to me that in order to solve this, the initial part of Step
3 needs to check to see if the current thread (and it really needs to
get the current thread in order to do this instead of relying on an
out-of-date cache) is the same as the one in which the Step Over,
Step Into, or Step Out operation was executed. If so, then it needs
to restart that operation. However, if the Shared Library event
takes place in a different thread, then that thread can just be
resumed with a Continue command.
Actually, what may need to happen is for the "lastRunningEvent"
information (see the source code to see what I'm referring to) to be
stored on a per-thread basis. But I think the simpler solution
described in the previous paragraph may suffice in the short term.
Anyway, I'm hoping that someone can examine my analysis and let me
know if I'm spot on or off the mark. If the former, I'll file a bug
report and fix my local copy. If the latter, then I'd appreciate
hearing what the correct fix would be.
Thanks,
-- Keith Rollin
-- Developer Tools engineer
-- PalmSource, Inc.