Our product supports running a program on a bare-metal target, which is
implemented by starting a debug session as usual, so that GDB initializes
the target and uploads the program, and then issuing "detach".
When trying to implement the same in DSF, I'm running into various issues.
For starters, I have the following step:
Step detach = new Step() {
public void execute(RequestMonitor rm) {
IGDBControl gdbControl = tracker.getService(IGDBControl.class);
gdbControl.queueCommand(
gdbControl.getCommandFactory().createCLIDetach(gdbControl.getContext()),
new DataRequestMonitor<MIInfo>(gdbControl.getExecutor(), rm));
}
};
This is added to the final launch sequence, and is the last step. It almost works,
except that the launch is not marked as terminated in the debug view. If I run
an application a dozen times, I'll have 10 launches in debug view. This is clearly
not good idea. So, I've added another step:
Step terminate = new Step() {
public void execute(RequestMonitor rm) {
IGDBControl gdbControl = tracker.getService(IGDBControl.class);
gdbControl.terminate(rm);
}
};
This works fine, most of the times. However, sometimes the launch progress monitor gets
stuck at 97%. What happens is that:
- As part of 'detach', GDB reports =thread-group-exited, which results, eventually,
in AbstractMIControl.stopCommandProcessing, which clears fRxCommands, calling done
on associated monitors.
- If timing is right, terminate is already called, sent -gdb-exit and is waiting for
response. When fRxCommands are cleared above, the monitor for -gdb-exit
(see GDB_Control_7_0.terminate) is called, notices isSuccess() is false, and does
nothing. Couple of seconds later, the timer also set up by 'terminate' fires, killing
GDB and notifying the request monitor.
- However, RequestMonitor.done submits a runnable to executor. At this point, executor
appears to be shut down, so RejectedExecutionException is raised, and
RequestMonitor.handleRejectedExecutionException is called.
- This in turn, calls 'done' on parent monitor. Parent monitor is RequestMonitorWithProgress
associated with the final launch sequence. It does not have handleCompleted method doing
anything interesting.
So, in essense, the request monitor for the 'terminate' step, created in Sequence.executeStep,
does not ever have its 'done' method called. Sequence.finish() is therefore never called as
well, and the call to Sequence.get from GdbLaunchDelegate never finished.
Attached is a quick-n-dirty workaround. However, I'm not sure what is the best fix
here. Any ideas?
A smaller issue is that the stack service sometimes is quick enough to issue -stack-list-frames,
which fails because GDB is gone, and we end up with a launch where program item is marked
as terminated, but which has a "stack", consisting of a single element saying "cannot get frames".
How do fix this?
Thanks in advance,