1
0
Fork 0
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:
Marc Khouzam 2016-11-09 22:51:21 -05:00 committed by Gerrit Code Review @ Eclipse.org
parent c2b4f18943
commit e8480ca0f8
4 changed files with 98 additions and 6 deletions

View file

@ -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

View file

@ -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,

View file

@ -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);

View file

@ -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);
}
}