mirror of
https://github.com/eclipse-cdt/cdt
synced 2025-04-29 19:45:01 +02:00
[298883] Support for MacOS version of services
This commit is contained in:
parent
866f945428
commit
44863628a6
9 changed files with 513 additions and 27 deletions
|
@ -1,5 +1,5 @@
|
|||
/*******************************************************************************
|
||||
* Copyright (c) 2008, 2009 QNX Software Systems and others.
|
||||
* Copyright (c) 2010 QNX Software Systems 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
|
||||
|
@ -9,6 +9,7 @@
|
|||
* QNX Software Systems - Initial API and implementation
|
||||
* Windriver and Ericsson - Updated for DSF
|
||||
* IBM Corporation
|
||||
* Ericsson - Added support for Mac OS
|
||||
*******************************************************************************/
|
||||
package org.eclipse.cdt.dsf.gdb.launching;
|
||||
|
||||
|
@ -30,6 +31,7 @@ import org.eclipse.cdt.dsf.gdb.internal.GdbPlugin;
|
|||
import org.eclipse.cdt.dsf.gdb.service.GdbDebugServicesFactory;
|
||||
import org.eclipse.cdt.dsf.gdb.service.GdbDebugServicesFactoryNS;
|
||||
import org.eclipse.cdt.dsf.gdb.service.SessionType;
|
||||
import org.eclipse.cdt.dsf.gdb.service.macos.MacOSGdbDebugServicesFactory;
|
||||
import org.eclipse.cdt.dsf.service.DsfSession;
|
||||
import org.eclipse.core.resources.IMarker;
|
||||
import org.eclipse.core.resources.IProject;
|
||||
|
@ -382,6 +384,11 @@ public class GdbLaunchDelegate extends LaunchConfigurationDelegate
|
|||
}
|
||||
|
||||
private boolean isNonStopSupported(String version) {
|
||||
if (version.contains(LaunchUtils.MACOS_GDB_MARKER)) {
|
||||
// Mac OS's GDB does not support Non-Stop
|
||||
return false;
|
||||
}
|
||||
|
||||
if (NON_STOP_FIRST_VERSION.compareTo(version) <= 0) {
|
||||
return true;
|
||||
}
|
||||
|
@ -394,11 +401,14 @@ public class GdbLaunchDelegate extends LaunchConfigurationDelegate
|
|||
if (isNonStopSession && isNonStopSupported(version)) {
|
||||
return new GdbDebugServicesFactoryNS(version);
|
||||
}
|
||||
|
||||
if (version.startsWith("6.6") || //$NON-NLS-1$
|
||||
version.startsWith("6.7") || //$NON-NLS-1$
|
||||
version.startsWith("6.8")) { //$NON-NLS-1$
|
||||
return new GdbDebugServicesFactory(version);
|
||||
|
||||
if (version.contains(LaunchUtils.MACOS_GDB_MARKER)) {
|
||||
// The version string at this point should look like
|
||||
// 6.3.50-20050815APPLE1346, we extract the gdb version and apple version
|
||||
String versions [] = version.split(LaunchUtils.MACOS_GDB_MARKER);
|
||||
if (versions.length == 2) {
|
||||
return new MacOSGdbDebugServicesFactory(versions[0], versions[1]);
|
||||
}
|
||||
}
|
||||
|
||||
return new GdbDebugServicesFactory(version);
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
/*******************************************************************************
|
||||
* Copyright (c) 2008 Ericsson and others.
|
||||
* Copyright (c) 2010 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
|
||||
|
@ -7,6 +7,7 @@
|
|||
*
|
||||
* Contributors:
|
||||
* Ericsson - Initial API and implementation
|
||||
* Ericsson - Added support for Mac OS
|
||||
*******************************************************************************/
|
||||
package org.eclipse.cdt.dsf.gdb.launching;
|
||||
|
||||
|
@ -43,6 +44,12 @@ import org.eclipse.debug.core.ILaunchConfiguration;
|
|||
|
||||
public class LaunchUtils {
|
||||
|
||||
/**
|
||||
* A prefix that we use to indicate that a GDB version is for MAC OS
|
||||
* @since 2.1
|
||||
*/
|
||||
public static final String MACOS_GDB_MARKER = "APPLE"; //$NON-NLS-1$
|
||||
|
||||
/**
|
||||
* Verify the following things about the project:
|
||||
* - is a valid project name given
|
||||
|
@ -230,6 +237,26 @@ public class LaunchUtils {
|
|||
version = "6.8"; //$NON-NLS-1$
|
||||
}
|
||||
}
|
||||
|
||||
// Look for the case of Apple's GDB, since the version must be handled differently
|
||||
// The format is:
|
||||
// GNU gdb 6.3.50-20050815 (Apple version gdb-696) (Sat Oct 20 18:20:28 GMT 2007)
|
||||
// GNU gdb 6.3.50-20050815 (Apple version gdb-966) (Tue Mar 10 02:43:13 UTC 2009)
|
||||
// GNU gdb 6.3.50-20050815 (Apple version gdb-1346) (Fri Sep 18 20:40:51 UTC 2009)
|
||||
// It seems the version that changes is the "Apple version" but we still use both.
|
||||
// The Mac OS prefix and version are appended to the normal version so the
|
||||
// returned string has this format: 6.3.50-20050815APPLE1346. The normal version and the
|
||||
// Apple version are extracted later and passed to the MacOS services factory.
|
||||
if (versionOutput.indexOf("Apple") != -1) { //$NON-NLS-1$
|
||||
// Add a prefix to indicate we are dealing with an Apple GDB
|
||||
version += MACOS_GDB_MARKER;
|
||||
Pattern aPattern = Pattern.compile(" \\(Apple version gdb-(\\d*)\\)", Pattern.MULTILINE); //$NON-NLS-1$
|
||||
|
||||
Matcher aMatcher = aPattern.matcher(versionOutput);
|
||||
if (aMatcher.find()) {
|
||||
version += aMatcher.group(1);
|
||||
}
|
||||
}
|
||||
|
||||
return version;
|
||||
}
|
||||
|
|
|
@ -0,0 +1,32 @@
|
|||
/*******************************************************************************
|
||||
* Copyright (c) 2010 Wind River Systems 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
|
||||
*
|
||||
* Contributors:
|
||||
* Wind River Systems - initial API and implementation
|
||||
*******************************************************************************/
|
||||
package org.eclipse.cdt.dsf.gdb.service.macos;
|
||||
|
||||
import org.eclipse.cdt.dsf.mi.service.MIExpressions;
|
||||
import org.eclipse.cdt.dsf.mi.service.MIVariableManager;
|
||||
import org.eclipse.cdt.dsf.service.DsfSession;
|
||||
|
||||
/**
|
||||
* Specific ExpressionService for MacOS
|
||||
*
|
||||
* @since 2.1
|
||||
*/
|
||||
public class MacOSGDBExpressions extends MIExpressions {
|
||||
|
||||
public MacOSGDBExpressions(DsfSession session) {
|
||||
super(session);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected MIVariableManager createMIVariableManager() {
|
||||
return new MacOSGDBVariableManager(getSession(), getServicesTracker());
|
||||
}
|
||||
}
|
|
@ -0,0 +1,135 @@
|
|||
/*******************************************************************************
|
||||
* Copyright (c) 2010 Wind River Systems 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
|
||||
*
|
||||
* Contributors:
|
||||
* Wind River Systems - initial API and implementation
|
||||
*******************************************************************************/
|
||||
package org.eclipse.cdt.dsf.gdb.service.macos;
|
||||
|
||||
import org.eclipse.cdt.dsf.concurrent.DataRequestMonitor;
|
||||
import org.eclipse.cdt.dsf.mi.service.MIVariableManager;
|
||||
import org.eclipse.cdt.dsf.mi.service.command.commands.macos.MacOSMIVarUpdate;
|
||||
import org.eclipse.cdt.dsf.mi.service.command.output.MIVarChange;
|
||||
import org.eclipse.cdt.dsf.mi.service.command.output.macos.MacOSMIVarUpdateInfo;
|
||||
import org.eclipse.cdt.dsf.service.DsfServicesTracker;
|
||||
import org.eclipse.cdt.dsf.service.DsfSession;
|
||||
|
||||
/**
|
||||
* Specific VariableManager for MacOS
|
||||
*
|
||||
* @since 2.1
|
||||
*/
|
||||
public class MacOSGDBVariableManager extends MIVariableManager {
|
||||
|
||||
public MacOSGDBVariableManager(DsfSession session, DsfServicesTracker tracker) {
|
||||
super(session, tracker);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected MIRootVariableObject createRootVariableObject(VariableObjectId id) {
|
||||
return new MacOSGDBRootVariableObject(id);
|
||||
}
|
||||
|
||||
private class MacOSGDBRootVariableObject extends MIRootVariableObject {
|
||||
|
||||
public MacOSGDBRootVariableObject(VariableObjectId id) {
|
||||
super(id);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void update(final DataRequestMonitor<Boolean> rm) {
|
||||
|
||||
if (isOutOfScope()) {
|
||||
rm.setData(false);
|
||||
rm.done();
|
||||
} else if (currentState != STATE_READY) {
|
||||
// Object is not fully created or is being updated
|
||||
// so add RequestMonitor to pending queue
|
||||
updatesPending.add(rm);
|
||||
} else if (getOutOfDate() == false) {
|
||||
rm.setData(false);
|
||||
rm.done();
|
||||
} else {
|
||||
// Object needs to be updated in the back-end
|
||||
currentState = STATE_UPDATING;
|
||||
|
||||
// In GDB, var-update will only report a change if -var-evaluate-expression has
|
||||
// changed -- in the current format--. This means that situations like
|
||||
// double z = 1.2;
|
||||
// z = 1.4;
|
||||
// Will not report a change if the format is anything else than natural.
|
||||
// This is because 1.2 and 1.4 are both printed as 1, 0x1, etc
|
||||
// Since we cache the values of every format, we must know if -any- format has
|
||||
// changed, not just the current one.
|
||||
// To solve this, we always do an update in the natural format; I am not aware
|
||||
// of any case where the natural format would stay the same, but another format
|
||||
// would change. However, since a var-update update all children as well,
|
||||
// we must make sure these children are also in the natural format
|
||||
// The simplest way to do this is that whenever we change the format
|
||||
// of a variable object, we immediately set it back to natural with a second
|
||||
// var-set-format command. This is done in the getValue() method
|
||||
getCommandControl().queueCommand(
|
||||
new MacOSMIVarUpdate(getRootToUpdate().getControlDMContext(), getGdbName()),
|
||||
new DataRequestMonitor<MacOSMIVarUpdateInfo>(getSession().getExecutor(), rm) {
|
||||
@Override
|
||||
protected void handleCompleted() {
|
||||
currentState = STATE_READY;
|
||||
|
||||
if (isSuccess()) {
|
||||
setOutOfDate(false);
|
||||
|
||||
MIVarChange[] changes = getData().getMIVarChanges();
|
||||
if (changes.length > 0 && changes[0].isInScope() == false) {
|
||||
// Object is out-of-scope
|
||||
outOfScope = true;
|
||||
|
||||
// We can delete this root in GDB right away. This is safe, even
|
||||
// if the root has children, because they are also out-of-scope.
|
||||
// We -must- also remove this entry from our LRU. If we don't
|
||||
// we can end-up with a race condition that create this object
|
||||
// twice, or have an infinite loop while never re-creating the object.
|
||||
// The can happen if we update a child first then we request
|
||||
// the root later,
|
||||
getLRUCache().remove(getInternalId());
|
||||
|
||||
rm.setData(true);
|
||||
rm.done();
|
||||
} else {
|
||||
// The root object is now up-to-date, we must parse the changes, if any.
|
||||
processChanges(changes);
|
||||
|
||||
// We only mark this root as updated in our list if it is in-scope.
|
||||
// For out-of-scope object, we don't ever need to re-update them so
|
||||
// we don't need to add them to this list.
|
||||
rootVariableUpdated(MacOSGDBRootVariableObject.this);
|
||||
|
||||
rm.setData(false);
|
||||
rm.done();
|
||||
}
|
||||
|
||||
while (updatesPending.size() > 0) {
|
||||
DataRequestMonitor<Boolean> pendingRm = updatesPending.poll();
|
||||
pendingRm.setData(false);
|
||||
pendingRm.done();
|
||||
}
|
||||
} else {
|
||||
// We were not able to update for some reason
|
||||
rm.setData(false);
|
||||
rm.done();
|
||||
|
||||
while (updatesPending.size() > 0) {
|
||||
DataRequestMonitor<Boolean> pendingRm = updatesPending.poll();
|
||||
pendingRm.setStatus(getStatus());
|
||||
pendingRm.done();
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,36 @@
|
|||
/*******************************************************************************
|
||||
* Copyright (c) 2010 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
|
||||
*
|
||||
* Contributors:
|
||||
* Marc-Andre Laperle - Added support for Mac OS (separate factory)
|
||||
* Ericsson - Added a field for the specific Mac OS version scheme
|
||||
*******************************************************************************/
|
||||
package org.eclipse.cdt.dsf.gdb.service.macos;
|
||||
|
||||
import org.eclipse.cdt.dsf.debug.service.IExpressions;
|
||||
import org.eclipse.cdt.dsf.gdb.service.GdbDebugServicesFactory;
|
||||
import org.eclipse.cdt.dsf.service.DsfSession;
|
||||
|
||||
/** @since 2.1 */
|
||||
public class MacOSGdbDebugServicesFactory extends GdbDebugServicesFactory {
|
||||
|
||||
// Mac OS has it's own version of GDB, which does not follow the standard GDB version
|
||||
// We have to be careful not to compare that specific version number scheme with the
|
||||
// FSF GDB version scheme.
|
||||
// Use this variable when needing to differentiate between different Mac OS GDBs
|
||||
private final String fAppleVersion;
|
||||
|
||||
public MacOSGdbDebugServicesFactory(String gdbVersion, String appleVersion) {
|
||||
super(gdbVersion);
|
||||
fAppleVersion = appleVersion;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected IExpressions createExpressionService(DsfSession session) {
|
||||
return new MacOSGDBExpressions(session);
|
||||
}
|
||||
}
|
|
@ -1,5 +1,5 @@
|
|||
/*******************************************************************************
|
||||
* Copyright (c) 2006, 2008 Wind River Systems and others.
|
||||
* Copyright (c) 2010 Wind River Systems 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
|
||||
|
@ -452,7 +452,7 @@ public class MIExpressions extends AbstractDsfService implements IExpressions, I
|
|||
// to the back-end, through the MICommandControl service
|
||||
// It must be created after the ExpressionService is registered
|
||||
// since it will need to find it.
|
||||
varManager = new MIVariableManager(getSession(), getServicesTracker());
|
||||
varManager = createMIVariableManager();
|
||||
|
||||
// Create the meta command cache which will use the variable manager
|
||||
// to actually send MI commands to the back-end
|
||||
|
@ -463,6 +463,16 @@ public class MIExpressions extends AbstractDsfService implements IExpressions, I
|
|||
requestMonitor.done();
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates the MI variable manager to be used by this expression service.
|
||||
* Overriding classes may override to provide a custom services tracker.
|
||||
*
|
||||
* @since 2.1
|
||||
*/
|
||||
protected MIVariableManager createMIVariableManager() {
|
||||
return new MIVariableManager(getSession(), getServicesTracker());
|
||||
}
|
||||
|
||||
/**
|
||||
* This method shuts down this service. It unregisters the service, stops
|
||||
* receiving service events, and calls the superclass shutdown() method to
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
/*******************************************************************************
|
||||
* Copyright (c) 2008 Monta Vista and others.
|
||||
* Copyright (c) 2010 Monta Vista 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
|
||||
|
@ -697,7 +697,7 @@ public class MIVariableManager implements ICommandControl {
|
|||
}
|
||||
|
||||
if (childVar == null) {
|
||||
childVar = new MIVariableObject(childId, MIVariableObject.this);
|
||||
childVar = createVariableObject(childId, MIVariableObject.this);
|
||||
childVar.setGdbName(child.getVarName());
|
||||
childVar.setExpressionData(
|
||||
childFullExpression,
|
||||
|
@ -914,7 +914,19 @@ public class MIVariableManager implements ICommandControl {
|
|||
}
|
||||
}
|
||||
|
||||
private class MIRootVariableObject extends MIVariableObject {
|
||||
/**
|
||||
* Method to allow to override the MIVariableObject creation
|
||||
*
|
||||
* @since 2.1
|
||||
*/
|
||||
protected MIVariableObject createVariableObject(VariableObjectId id, MIVariableObject parentObj) {
|
||||
return new MIVariableObject(id, parentObj);
|
||||
}
|
||||
|
||||
/**
|
||||
* @since 2.1
|
||||
*/
|
||||
public class MIRootVariableObject extends MIVariableObject {
|
||||
|
||||
// Only root variables go through the GDB creation process
|
||||
protected static final int STATE_NOT_CREATED = 10;
|
||||
|
@ -925,7 +937,7 @@ public class MIVariableManager implements ICommandControl {
|
|||
// will have the same control context
|
||||
private ICommandControlDMContext fControlContext = null;
|
||||
|
||||
private boolean outOfDate = false;
|
||||
private boolean fOutOfDate = false;
|
||||
|
||||
// Modifiable descendants are any variable object that is a descendant or itself for
|
||||
// which the value can change.
|
||||
|
@ -940,8 +952,10 @@ public class MIVariableManager implements ICommandControl {
|
|||
public ICommandControlDMContext getControlDMContext() { return fControlContext; }
|
||||
|
||||
public boolean isUpdating() { return currentState == STATE_UPDATING; }
|
||||
|
||||
public void markAsOutOfDate() { outOfDate = true; }
|
||||
|
||||
public void setOutOfDate(boolean outOfDate) { fOutOfDate = outOfDate; }
|
||||
|
||||
public boolean getOutOfDate() { return fOutOfDate; }
|
||||
|
||||
// Remember that we must add ourself as a modifiable descendant if our value can change
|
||||
public void addModifiableDescendant(String gdbName, MIVariableObject descendant) {
|
||||
|
@ -1033,7 +1047,7 @@ public class MIVariableManager implements ICommandControl {
|
|||
// Object is not fully created or is being updated
|
||||
// so add RequestMonitor to pending queue
|
||||
updatesPending.add(rm);
|
||||
} else if (outOfDate == false) {
|
||||
} else if (getOutOfDate() == false) {
|
||||
rm.setData(false);
|
||||
rm.done();
|
||||
} else {
|
||||
|
@ -1063,7 +1077,7 @@ public class MIVariableManager implements ICommandControl {
|
|||
currentState = STATE_READY;
|
||||
|
||||
if (isSuccess()) {
|
||||
outOfDate = false;
|
||||
setOutOfDate(false);
|
||||
|
||||
MIVarChange[] changes = getData().getMIVarChanges();
|
||||
if (changes.length > 0 && changes[0].isInScope() == false) {
|
||||
|
@ -1088,7 +1102,7 @@ public class MIVariableManager implements ICommandControl {
|
|||
// We only mark this root as updated in our list if it is in-scope.
|
||||
// For out-of-scope object, we don't ever need to re-update them so
|
||||
// we don't need to add them to this list.
|
||||
updatedRootList.add(MIRootVariableObject.this);
|
||||
rootVariableUpdated(MIRootVariableObject.this);
|
||||
|
||||
rm.setData(false);
|
||||
rm.done();
|
||||
|
@ -1138,9 +1152,16 @@ public class MIVariableManager implements ICommandControl {
|
|||
} else {
|
||||
// Variable was never created or was already deleted, no need to do anything.
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Method to allow to override the MIRootVariableObject creation.
|
||||
*
|
||||
* @since 2.1
|
||||
*/
|
||||
protected MIRootVariableObject createRootVariableObject(VariableObjectId id) {
|
||||
return new MIRootVariableObject(id);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -1153,8 +1174,10 @@ public class MIVariableManager implements ICommandControl {
|
|||
*
|
||||
* Note that if no frameContext is specified (only Execution, or even only Container), which can
|
||||
* characterize a global variable for example, we will only use the available information.
|
||||
*
|
||||
* @since 2.1
|
||||
*/
|
||||
private class VariableObjectId {
|
||||
public class VariableObjectId {
|
||||
// We don't use the expression context because it is not safe to compare them
|
||||
// See bug 187718. So we store the expression itself, and it's parent execution context.
|
||||
String fExpression = null;
|
||||
|
@ -1163,6 +1186,9 @@ public class MIVariableManager implements ICommandControl {
|
|||
// the same frame will have a different level based on the current depth of the stack
|
||||
Integer fFrameId = null;
|
||||
|
||||
public VariableObjectId() {
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object other) {
|
||||
if (other instanceof VariableObjectId) {
|
||||
|
@ -1220,6 +1246,16 @@ public class MIVariableManager implements ICommandControl {
|
|||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Method to allow to override the VariableObjectId creation.
|
||||
*
|
||||
* @since 2.1
|
||||
*/
|
||||
protected VariableObjectId createVariableObjectId() {
|
||||
return new VariableObjectId();
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* This is the real work horse of managing our objects. Not only must every
|
||||
* value be unique to get inserted, this also creates an LRU (least recently
|
||||
|
@ -1338,6 +1374,34 @@ public class MIVariableManager implements ICommandControl {
|
|||
fSession.removeServiceEventListener(this);
|
||||
}
|
||||
|
||||
/**
|
||||
* @since 2.1
|
||||
*/
|
||||
protected DsfSession getSession() {
|
||||
return fSession;
|
||||
}
|
||||
|
||||
/**
|
||||
* @since 2.1
|
||||
*/
|
||||
protected ICommandControl getCommandControl() {
|
||||
return fCommandControl;
|
||||
}
|
||||
|
||||
/**
|
||||
* @since 2.1
|
||||
*/
|
||||
protected void rootVariableUpdated(MIRootVariableObject rootObj) {
|
||||
updatedRootList.add(rootObj);
|
||||
}
|
||||
|
||||
/**
|
||||
* @since 2.1
|
||||
*/
|
||||
protected Map<VariableObjectId, MIVariableObject> getLRUCache() {
|
||||
return lruVariableList;
|
||||
}
|
||||
|
||||
/**
|
||||
* This method returns a variable object based on the specified
|
||||
* ExpressionDMC, creating it in GDB if it was not created already.
|
||||
|
@ -1354,7 +1418,7 @@ public class MIVariableManager implements ICommandControl {
|
|||
final DataRequestMonitor<MIVariableObject> rm) {
|
||||
// Generate an id for this expression so that we can determine if we already
|
||||
// have a variable object tracking it. If we don't we'll need to create one.
|
||||
final VariableObjectId id = new VariableObjectId();
|
||||
final VariableObjectId id = createVariableObjectId();
|
||||
id.generateId(
|
||||
exprCtx,
|
||||
new RequestMonitor(fSession.getExecutor(), rm) {
|
||||
|
@ -1431,7 +1495,7 @@ public class MIVariableManager implements ICommandControl {
|
|||
|
||||
// Variable objects that are created directly like this, are considered ROOT variable objects
|
||||
// in comparison to variable objects that are children of other variable objects.
|
||||
final MIRootVariableObject newVarObj = new MIRootVariableObject(id);
|
||||
final MIRootVariableObject newVarObj = createRootVariableObject(id);
|
||||
|
||||
// We must put this object in our map right away, in case it is
|
||||
// requested again, before it completes its creation.
|
||||
|
@ -1443,7 +1507,7 @@ public class MIVariableManager implements ICommandControl {
|
|||
protected void handleCompleted() {
|
||||
if (isSuccess()) {
|
||||
// Also store the object as a varObj that is up-to-date
|
||||
updatedRootList.add(newVarObj);
|
||||
rootVariableUpdated(newVarObj);
|
||||
// VarObj can now be used by others
|
||||
newVarObj.creationCompleted(true);
|
||||
|
||||
|
@ -1625,7 +1689,7 @@ public class MIVariableManager implements ICommandControl {
|
|||
}
|
||||
});
|
||||
|
||||
} else if (command instanceof MIDataEvaluateExpression) {
|
||||
} else if (command instanceof MIDataEvaluateExpression<?>) {
|
||||
// This does not use the variable objects but sends the command directly to the back-end
|
||||
fCommandControl.queueCommand(command, rm);
|
||||
} else {
|
||||
|
@ -1684,7 +1748,7 @@ public class MIVariableManager implements ICommandControl {
|
|||
public void markAllOutOfDate() {
|
||||
MIRootVariableObject root;
|
||||
while ((root = updatedRootList.poll()) != null) {
|
||||
root.markAsOutOfDate();
|
||||
root.setOutOfDate(true);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -0,0 +1,49 @@
|
|||
/*******************************************************************************
|
||||
* Copyright (c) 2010 QNX Software Systems 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
|
||||
*
|
||||
* Contributors:
|
||||
* QNX Software Systems - Initial API and implementation
|
||||
* Wind River Systems - Modified for new DSF Reference Implementation
|
||||
* Ericsson - Modified for handling of frame contexts
|
||||
*******************************************************************************/
|
||||
|
||||
package org.eclipse.cdt.dsf.mi.service.command.commands.macos;
|
||||
|
||||
import org.eclipse.cdt.dsf.debug.service.command.ICommandControlService.ICommandControlDMContext;
|
||||
import org.eclipse.cdt.dsf.mi.service.command.commands.MICommand;
|
||||
import org.eclipse.cdt.dsf.mi.service.command.output.MIOutput;
|
||||
import org.eclipse.cdt.dsf.mi.service.command.output.macos.MacOSMIVarUpdateInfo;
|
||||
|
||||
/**
|
||||
*
|
||||
* -var-update [print-values] {NAME | "*"}
|
||||
*
|
||||
* Update the value of the variable object NAME by evaluating its
|
||||
* expression after fetching all the new values from memory or registers.
|
||||
* A `*' causes all existing variable objects to be updated.
|
||||
* If print-values has a value for of 0 or --no-values, print only the names of the variables;
|
||||
* if print-values is 1 or --all-values, also print their values;
|
||||
* if it is 2 or --simple-values print the name and value for simple data types and just
|
||||
* the name for arrays, structures and unions.
|
||||
*
|
||||
* It seems that for MacOS, we must use the full string for print-values, such as
|
||||
* --all-values.
|
||||
*
|
||||
* @since 2.1
|
||||
*/
|
||||
public class MacOSMIVarUpdate extends MICommand<MacOSMIVarUpdateInfo> {
|
||||
|
||||
public MacOSMIVarUpdate(ICommandControlDMContext dmc, String name) {
|
||||
// Must use --all-values instead of 1 for Mac OS
|
||||
super(dmc, "-var-update", new String[] { "--all-values", name }); //$NON-NLS-1$//$NON-NLS-2$
|
||||
}
|
||||
|
||||
@Override
|
||||
public MacOSMIVarUpdateInfo getResult(MIOutput out) {
|
||||
return new MacOSMIVarUpdateInfo(out);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,123 @@
|
|||
/*******************************************************************************
|
||||
* Copyright (c) 2010 QNX Software Systems 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
|
||||
*
|
||||
* Contributors:
|
||||
* QNX Software Systems - Initial API and implementation
|
||||
* Ericsson - Created version for Mac OS
|
||||
*******************************************************************************/
|
||||
package org.eclipse.cdt.dsf.mi.service.command.output.macos;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
import org.eclipse.cdt.dsf.mi.service.command.output.MIConst;
|
||||
import org.eclipse.cdt.dsf.mi.service.command.output.MIInfo;
|
||||
import org.eclipse.cdt.dsf.mi.service.command.output.MIList;
|
||||
import org.eclipse.cdt.dsf.mi.service.command.output.MIOutput;
|
||||
import org.eclipse.cdt.dsf.mi.service.command.output.MIResult;
|
||||
import org.eclipse.cdt.dsf.mi.service.command.output.MIResultRecord;
|
||||
import org.eclipse.cdt.dsf.mi.service.command.output.MITuple;
|
||||
import org.eclipse.cdt.dsf.mi.service.command.output.MIValue;
|
||||
import org.eclipse.cdt.dsf.mi.service.command.output.MIVarChange;
|
||||
|
||||
/**
|
||||
* GDB/MI var-update for Mac OS.
|
||||
* -var-update *
|
||||
* ^done,changelist=[varobj={name="var1",in_scope="true",type_changed="false"}],time={.....}
|
||||
*
|
||||
* @since 2.1
|
||||
*/
|
||||
public class MacOSMIVarUpdateInfo extends MIInfo {
|
||||
|
||||
MIVarChange[] changeList;
|
||||
|
||||
public MacOSMIVarUpdateInfo(MIOutput record) {
|
||||
super(record);
|
||||
List<MIVarChange> aList = new ArrayList<MIVarChange>();
|
||||
if (isDone()) {
|
||||
MIOutput out = getMIOutput();
|
||||
MIResultRecord rr = out.getMIResultRecord();
|
||||
if (rr != null) {
|
||||
MIResult[] results = rr.getMIResults();
|
||||
for (int i = 0; i < results.length; i++) {
|
||||
String var = results[i].getVariable();
|
||||
if (var.equals("changelist")) { //$NON-NLS-1$
|
||||
MIValue value = results[i].getMIValue();
|
||||
if (value instanceof MITuple) {
|
||||
parseChangeList((MITuple)value, aList);
|
||||
} else if (value instanceof MIList) {
|
||||
parseChangeList((MIList)value, aList);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
changeList = aList.toArray(new MIVarChange[aList.size()]);
|
||||
}
|
||||
|
||||
public MIVarChange[] getMIVarChanges() {
|
||||
return changeList;
|
||||
}
|
||||
|
||||
/**
|
||||
* For MI2 the format is now a MIList.
|
||||
* @param tuple
|
||||
* @param aList
|
||||
*/
|
||||
void parseChangeList(MIList miList, List<MIVarChange> aList) {
|
||||
// The MIList in Apple gdb contains MIResults instead of MIValues. It looks like:
|
||||
// ^done,changelist=[varobj={name="var1",in_scope="true",type_changed="false"}],time={.....}
|
||||
// Bug 250037
|
||||
MIResult[] results = miList.getMIResults();
|
||||
for (int i = 0; i < results.length; i++) {
|
||||
String var = results[i].getVariable();
|
||||
if (var.equals("varobj")) { //$NON-NLS-1$
|
||||
MIValue value = results[i].getMIValue();
|
||||
if (value instanceof MITuple) {
|
||||
parseChangeList((MITuple)value, aList);
|
||||
} else if (value instanceof MIList) {
|
||||
parseChangeList((MIList)value, aList);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void parseChangeList(MITuple tuple, List<MIVarChange> aList) {
|
||||
MIResult[] results = tuple.getMIResults();
|
||||
MIVarChange change = null;
|
||||
for (int i = 0; i < results.length; i++) {
|
||||
String var = results[i].getVariable();
|
||||
MIValue value = results[i].getMIValue();
|
||||
if (value instanceof MITuple) {
|
||||
parseChangeList((MITuple)value, aList);
|
||||
}
|
||||
else
|
||||
{
|
||||
String str = ""; //$NON-NLS-1$
|
||||
if (value instanceof MIConst) {
|
||||
str = ((MIConst)value).getString();
|
||||
}
|
||||
if (var.equals("name")) { //$NON-NLS-1$
|
||||
change = new MIVarChange(str);
|
||||
aList.add(change);
|
||||
} else if (var.equals("value")) { //$NON-NLS-1$
|
||||
if (change != null) {
|
||||
change.setValue(str);
|
||||
}
|
||||
} else if (var.equals("in_scope")) { //$NON-NLS-1$
|
||||
if (change != null) {
|
||||
change.setInScope("true".equals(str)); //$NON-NLS-1$
|
||||
}
|
||||
} else if (var.equals("type_changed")) { //$NON-NLS-1$
|
||||
if (change != null) {
|
||||
change.setChanged("true".equals(str)); //$NON-NLS-1$
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
Loading…
Add table
Reference in a new issue