Community
Participate
Working Groups
The MIInferiorProcess class automatically calls terminate() and closes its streams when getting an IExitedDMEvent for a process. On a restart, GDB creates the new process before indicating that the previous one was terminated. So, the IExitedDMEvent is received by both the old MIInferiorProcess and the new MIInferiorProcess, and they both think they should call terminate() because they both have the same id. The consequence is that after a restart, the streams of the inferior process are closed right away.
This problem happens for GDB >= 7.0 only right now. It seems that for GDB < 7.0, we don't even receive the IExitedDMEvent which is problem in itself. Once the event is received, the immediate terminate() might also affect those versions.
(In reply to comment #0) > The consequence is that after a restart, the streams of the inferior process > are closed right away. Actually, the process can't even run very long after the restart and gets a SIGHUP because of this issue.
Created attachment 195655 [details] Fix This fix does two things: when doing a restart, it replaces the containerDmc for the original process, with a new one that will represent the new process. We do this because the context hierarchy contains the pid, and the pid will change once the process is restarted, so we should not re-use the same container. The trick was to choose the right groupId based on the GDB version. GDB <= 6.8, the groupId is the MIProcesses.UNIQUE_GROUP_ID, as it always is. GDB 7.0 and 7.1, the groupId will eventually be the new pid, but until the process is started, we have to fall back on MIProcesses.UNIQUE_GROUP_ID (this is another reason why we can't use the old container, which will have the groupId set to the pid of the original process) GDB >= 7.2, the groupId remains the same even after the restart. The second thing this patch does is to have MIInferiorProcess listen for IStartedEvent for the process. This allows us to get the fully formed Container context with pid, once the process is started, but also, we mark MIInferiorProcess as 'started'. Now that we know if an inferior has been started yet, we can ignore the IExitedDMEvent for the new inferior that was not started yet. I admit that things are getting pretty complex. The fundamental reason for that is that we support many different versions of GDB that have subtle differences.
Committed to HEAD.
Pawel, can you review?
*** cdt cvs genie on behalf of mkhouzam *** Bug 345749: MIInferior process gets terminated right away on a restart [*] GDBProcesses.java 1.28 http://dev.eclipse.org/viewcvs/index.cgi/org.eclipse.cdt/dsf-gdb/org.eclipse.cdt.dsf.gdb/src/org/eclipse/cdt/dsf/gdb/service/GDBProcesses.java?root=Tools_Project&r1=1.27&r2=1.28 [*] GDBProcesses_7_2.java 1.18 http://dev.eclipse.org/viewcvs/index.cgi/org.eclipse.cdt/dsf-gdb/org.eclipse.cdt.dsf.gdb/src/org/eclipse/cdt/dsf/gdb/service/GDBProcesses_7_2.java?root=Tools_Project&r1=1.17&r2=1.18 [*] GDBProcesses_7_0.java 1.55 http://dev.eclipse.org/viewcvs/index.cgi/org.eclipse.cdt/dsf-gdb/org.eclipse.cdt.dsf.gdb/src/org/eclipse/cdt/dsf/gdb/service/GDBProcesses_7_0.java?root=Tools_Project&r1=1.54&r2=1.55 [*] MIInferiorProcess.java 1.14 http://dev.eclipse.org/viewcvs/index.cgi/org.eclipse.cdt/dsf-gdb/org.eclipse.cdt.dsf.gdb/src/org/eclipse/cdt/dsf/mi/service/command/MIInferiorProcess.java?root=Tools_Project&r1=1.13&r2=1.14