mirror of
https://github.com/eclipse-cdt/cdt
synced 2025-07-22 16:35:25 +02:00
Bug 498782 - add synchronize of process selection between the DV and GDB
This patch synchronizes the GDB focus when the user selects a process node in the DV. When the user selects a new process (inferior) from the GDB console, we are already synchronizing the DV to the thread/frame that GDB selects from that process. Change-Id: I11dfd175d51ec49e969f4d07288f80f7ea72a3e1
This commit is contained in:
parent
c2b4f18943
commit
e8480ca0f8
4 changed files with 98 additions and 6 deletions
|
@ -12,6 +12,7 @@ import org.eclipse.cdt.dsf.datamodel.IDMContext;
|
|||
import org.eclipse.cdt.dsf.debug.service.IStack.IFrameDMContext;
|
||||
import org.eclipse.cdt.dsf.gdb.internal.service.IGDBFocusSynchronizer;
|
||||
import org.eclipse.cdt.dsf.gdb.internal.ui.GdbUIPlugin;
|
||||
import org.eclipse.cdt.dsf.mi.service.IMIContainerDMContext;
|
||||
import org.eclipse.cdt.dsf.mi.service.IMIExecutionDMContext;
|
||||
import org.eclipse.cdt.dsf.service.DsfServicesTracker;
|
||||
import org.eclipse.cdt.dsf.service.DsfSession;
|
||||
|
@ -46,8 +47,10 @@ public class GdbDebugContextSyncManager implements IDebugContextListener {
|
|||
if (context != null) {
|
||||
final IDMContext dmc = context.getAdapter(IDMContext.class);
|
||||
|
||||
if (dmc instanceof IMIExecutionDMContext || dmc instanceof IFrameDMContext) {
|
||||
// A thread or stack frame was selected. In either case, have GDB switch to the new
|
||||
if (dmc instanceof IMIContainerDMContext ||
|
||||
dmc instanceof IMIExecutionDMContext ||
|
||||
dmc instanceof IFrameDMContext) {
|
||||
// A process, thread or stack frame was selected. In each case, have GDB switch to the new
|
||||
// corresponding thread, if required.
|
||||
|
||||
// Resolve the debug session
|
||||
|
|
|
@ -29,6 +29,7 @@ import org.eclipse.cdt.dsf.debug.service.command.IEventListener;
|
|||
import org.eclipse.cdt.dsf.gdb.internal.GdbPlugin;
|
||||
import org.eclipse.cdt.dsf.gdb.service.IGDBProcesses;
|
||||
import org.eclipse.cdt.dsf.gdb.service.command.IGDBControl;
|
||||
import org.eclipse.cdt.dsf.mi.service.IMIContainerDMContext;
|
||||
import org.eclipse.cdt.dsf.mi.service.IMIExecutionDMContext;
|
||||
import org.eclipse.cdt.dsf.mi.service.command.CommandFactory;
|
||||
import org.eclipse.cdt.dsf.mi.service.command.output.MIConst;
|
||||
|
@ -70,7 +71,7 @@ import org.osgi.framework.BundleContext;
|
|||
public class GDBFocusSynchronizer extends AbstractDsfService implements IGDBFocusSynchronizer, IEventListener
|
||||
{
|
||||
/** This service's opinion of what is the current GDB focus - it can be
|
||||
* a thread or stack frame context */
|
||||
* a process, thread or stack frame context */
|
||||
private IDMContext fCurrentGDBFocus;
|
||||
|
||||
private IStack fStackService;
|
||||
|
@ -170,6 +171,10 @@ public class GDBFocusSynchronizer extends AbstractDsfService implements IGDBFocu
|
|||
}
|
||||
});
|
||||
}
|
||||
// new selection is a process?
|
||||
else if (elem instanceof IMIContainerDMContext) {
|
||||
setProcessFocus((IMIContainerDMContext)elem, rm);
|
||||
}
|
||||
else {
|
||||
assert false;
|
||||
rm.done(new Status(IStatus.ERROR, GdbPlugin.PLUGIN_ID,
|
||||
|
@ -177,7 +182,59 @@ public class GDBFocusSynchronizer extends AbstractDsfService implements IGDBFocu
|
|||
return;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
protected void setProcessFocus(IMIContainerDMContext newProc, RequestMonitor rm) {
|
||||
if (newProc == null) {
|
||||
rm.done(new Status(IStatus.ERROR, GdbPlugin.PLUGIN_ID,
|
||||
INVALID_HANDLE, "GdbFocusSynchronizer unable to resolve process context for the selected element", null)); //$NON-NLS-1$
|
||||
return;
|
||||
}
|
||||
// There is no MI command to set the inferior. We could use the CLI 'inferior' command, but it would then
|
||||
// generate a =thread-selected event, which would cause us to change the selection in the Debug view and
|
||||
// select the stack frame of the first thread, or the first thread itself if it is running.
|
||||
// That would prevent the user from being able to leave the selection to a process node.
|
||||
// What we can do instead, is tell GDB to select the first thread of that inferior, which is what
|
||||
// GDB would do anyway, but since we have an MI -thread-select command it will prevent GDB from
|
||||
// issuing a =thread-selected event.
|
||||
fProcesses.getProcessesBeingDebugged(newProc, new ImmediateDataRequestMonitor<IDMContext[]>(rm) {
|
||||
@Override
|
||||
protected void handleSuccess() {
|
||||
if (getData().length > 0) {
|
||||
IDMContext finalThread = getData()[0];
|
||||
if (finalThread instanceof IMIExecutionDMContext) {
|
||||
setThreadFocus((IMIExecutionDMContext)(finalThread), new ImmediateRequestMonitor(rm) {
|
||||
@Override
|
||||
protected void handleSuccess() {
|
||||
// update the current focus, to match new GDB focus
|
||||
fCurrentGDBFocus = finalThread;
|
||||
rm.done();
|
||||
}
|
||||
});
|
||||
return;
|
||||
}
|
||||
rm.done();
|
||||
} else {
|
||||
// If there are no threads, it probably implies the inferior is not running
|
||||
// e.g., an exited process. In this case, we cannot set the thread, but it
|
||||
// then becomes safe to set the inferior using the CLI command since
|
||||
// there is no thread for that inferior and therefore no =thread-selected event
|
||||
String miInferiorId = newProc.getGroupId();
|
||||
// Remove the 'i' prefix
|
||||
String cliInferiorId = miInferiorId.substring(1, miInferiorId.length());
|
||||
ICommand<MIInfo> command = fCommandFactory.createCLIInferior(fGdbcontrol.getContext(), cliInferiorId);
|
||||
fGdbcontrol.queueCommand(command, new ImmediateDataRequestMonitor<MIInfo> (rm) {
|
||||
@Override
|
||||
protected void handleSuccess() {
|
||||
// update the current focus, to match new GDB focus
|
||||
fCurrentGDBFocus = newProc;
|
||||
rm.done();
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
protected void setThreadFocus(IMIExecutionDMContext newThread, RequestMonitor rm) {
|
||||
if (newThread == null) {
|
||||
rm.done(new Status(IStatus.ERROR, GdbPlugin.PLUGIN_ID,
|
||||
|
|
|
@ -31,6 +31,7 @@
|
|||
|
||||
package org.eclipse.cdt.dsf.mi.service.command;
|
||||
|
||||
import org.eclipse.cdt.debug.core.model.IChangeReverseMethodHandler.ReverseDebugMethod;
|
||||
import org.eclipse.cdt.dsf.datamodel.IDMContext;
|
||||
import org.eclipse.cdt.dsf.debug.service.IBreakpoints.IBreakpointsTargetDMContext;
|
||||
import org.eclipse.cdt.dsf.debug.service.IDisassembly.IDisassemblyDMContext;
|
||||
|
@ -53,6 +54,7 @@ import org.eclipse.cdt.dsf.mi.service.command.commands.CLIAttach;
|
|||
import org.eclipse.cdt.dsf.mi.service.command.commands.CLICatch;
|
||||
import org.eclipse.cdt.dsf.mi.service.command.commands.CLIDetach;
|
||||
import org.eclipse.cdt.dsf.mi.service.command.commands.CLIExecAbort;
|
||||
import org.eclipse.cdt.dsf.mi.service.command.commands.CLIInferior;
|
||||
import org.eclipse.cdt.dsf.mi.service.command.commands.CLIInfoBreak;
|
||||
import org.eclipse.cdt.dsf.mi.service.command.commands.CLIInfoProgram;
|
||||
import org.eclipse.cdt.dsf.mi.service.command.commands.CLIInfoRecord;
|
||||
|
@ -195,6 +197,7 @@ import org.eclipse.cdt.dsf.mi.service.command.output.CLIAddressableSizeInfo;
|
|||
import org.eclipse.cdt.dsf.mi.service.command.output.CLICatchInfo;
|
||||
import org.eclipse.cdt.dsf.mi.service.command.output.CLIInfoBreakInfo;
|
||||
import org.eclipse.cdt.dsf.mi.service.command.output.CLIInfoProgramInfo;
|
||||
import org.eclipse.cdt.dsf.mi.service.command.output.CLIInfoRecordInfo;
|
||||
import org.eclipse.cdt.dsf.mi.service.command.output.CLIInfoSharedLibraryInfo;
|
||||
import org.eclipse.cdt.dsf.mi.service.command.output.CLIInfoThreadsInfo;
|
||||
import org.eclipse.cdt.dsf.mi.service.command.output.CLIShowEndianInfo;
|
||||
|
@ -242,8 +245,6 @@ import org.eclipse.cdt.dsf.mi.service.command.output.MIVarSetFormatInfo;
|
|||
import org.eclipse.cdt.dsf.mi.service.command.output.MIVarShowAttributesInfo;
|
||||
import org.eclipse.cdt.dsf.mi.service.command.output.MIVarShowFormatInfo;
|
||||
import org.eclipse.cdt.dsf.mi.service.command.output.MIVarUpdateInfo;
|
||||
import org.eclipse.cdt.dsf.mi.service.command.output.CLIInfoRecordInfo;
|
||||
import org.eclipse.cdt.debug.core.model.IChangeReverseMethodHandler.ReverseDebugMethod;
|
||||
|
||||
/**
|
||||
* Factory to create MI/CLI commands.
|
||||
|
@ -279,6 +280,11 @@ public class CommandFactory {
|
|||
return new CLIExecAbort(ctx);
|
||||
}
|
||||
|
||||
/** @since 5.2 */
|
||||
public ICommand<MIInfo> createCLIInferior(ICommandControlDMContext ctx, String inferiorId) {
|
||||
return new CLIInferior(ctx, inferiorId);
|
||||
}
|
||||
|
||||
/** @since 4.2 */
|
||||
public ICommand<CLIInfoBreakInfo> createCLIInfoBreak(IDMContext ctx) {
|
||||
return new CLIInfoBreak(ctx);
|
||||
|
|
|
@ -0,0 +1,26 @@
|
|||
/*******************************************************************************
|
||||
* Copyright (c) 2016 Ericsson and others.
|
||||
* All rights reserved. This program and the accompanying materials
|
||||
* are made available under the terms of the Eclipse Public License v1.0
|
||||
* which accompanies this distribution, and is available at
|
||||
* http://www.eclipse.org/legal/epl-v10.html
|
||||
*******************************************************************************/
|
||||
|
||||
package org.eclipse.cdt.dsf.mi.service.command.commands;
|
||||
|
||||
import org.eclipse.cdt.dsf.debug.service.command.ICommandControlService.ICommandControlDMContext;
|
||||
import org.eclipse.cdt.dsf.mi.service.command.output.MIInfo;
|
||||
|
||||
/**
|
||||
* Selects the specified inferior in GDB.
|
||||
*
|
||||
* @since 5.2
|
||||
*/
|
||||
public class CLIInferior extends MIInterpreterExecConsole<MIInfo> {
|
||||
|
||||
private static final String INFERIOR = "inferior "; //$NON-NLS-1$
|
||||
|
||||
public CLIInferior(ICommandControlDMContext ctx, String inferiorId) {
|
||||
super(ctx, INFERIOR + inferiorId);
|
||||
}
|
||||
}
|
Loading…
Add table
Reference in a new issue