Skip to main content

[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.


Back to the top