Skip to main content
aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorUwe Stieber2013-10-21 08:28:36 +0000
committerUwe Stieber2013-10-21 08:28:36 +0000
commit5e1cb0caed52d984280f4888456f6a98188284f8 (patch)
tree9951d963413d5e495a2c3b45bcbd15cc133427bf
parent6322a18981c38177a19ea842860612ca74f5cb3e (diff)
downloadorg.eclipse.tcf-5e1cb0caed52d984280f4888456f6a98188284f8.tar.gz
org.eclipse.tcf-5e1cb0caed52d984280f4888456f6a98188284f8.tar.xz
org.eclipse.tcf-5e1cb0caed52d984280f4888456f6a98188284f8.zip
TCF Debugger: Fix launch overwrites path map rules set by other clients on the same channel.
This changes applies to the "Remote Debug" launch configuration type only. Behavior of the "Target Communication Launch" launch configuration type is unchanged.
-rw-r--r--plugins/org.eclipse.tcf.debug/src/org/eclipse/tcf/internal/debug/model/TCFLaunch.java36
-rw-r--r--target_explorer/plugins/org.eclipse.tcf.te.tcf.launch.core/src/org/eclipse/tcf/te/tcf/launch/core/delegates/Launch.java71
-rw-r--r--target_explorer/plugins/org.eclipse.tcf.te.tcf.launch.core/src/org/eclipse/tcf/te/tcf/launch/core/internal/services/PathMapService.java26
3 files changed, 125 insertions, 8 deletions
diff --git a/plugins/org.eclipse.tcf.debug/src/org/eclipse/tcf/internal/debug/model/TCFLaunch.java b/plugins/org.eclipse.tcf.debug/src/org/eclipse/tcf/internal/debug/model/TCFLaunch.java
index 1302258a3..38b86592e 100644
--- a/plugins/org.eclipse.tcf.debug/src/org/eclipse/tcf/internal/debug/model/TCFLaunch.java
+++ b/plugins/org.eclipse.tcf.debug/src/org/eclipse/tcf/internal/debug/model/TCFLaunch.java
@@ -42,12 +42,12 @@ import org.eclipse.tcf.protocol.IToken;
import org.eclipse.tcf.protocol.JSON;
import org.eclipse.tcf.protocol.Protocol;
import org.eclipse.tcf.services.IContextQuery;
+import org.eclipse.tcf.services.IDPrintf;
import org.eclipse.tcf.services.IFileSystem;
import org.eclipse.tcf.services.IFileSystem.FileSystemException;
import org.eclipse.tcf.services.IFileSystem.IFileHandle;
import org.eclipse.tcf.services.IMemory;
import org.eclipse.tcf.services.IMemory.MemoryContext;
-import org.eclipse.tcf.services.IDPrintf;
import org.eclipse.tcf.services.IMemoryMap;
import org.eclipse.tcf.services.IPathMap;
import org.eclipse.tcf.services.IProcesses;
@@ -726,11 +726,22 @@ public class TCFLaunch extends Launch {
host_path_map.addAll(TCFLaunchDelegate.parseSourceLocatorMemento(s));
readCustomPathMapConfiguration(channel, cfg, host_path_map);
int cnt = 0;
- String id = Activator.getClientID();
- for (IPathMap.PathMapRule r : host_path_map) r.getProperties().put(IPathMap.PROP_ID, id + "/" + cnt++);
+ String id = getClientID();
+ if (id != null) {
+ for (IPathMap.PathMapRule r : host_path_map) r.getProperties().put(IPathMap.PROP_ID, id + "/" + cnt++);
+ }
}
/**
+ * Returns the client ID to use to mark the path map rules managed by this client.
+ *
+ * @return The client ID.
+ */
+ protected String getClientID() {
+ return Activator.getClientID();
+ }
+
+ /**
* Add custom path map rules to the host path map before applying the path map.
*
* @param channel The channel. Must not be <code>null</code>.
@@ -743,8 +754,8 @@ public class TCFLaunch extends Launch {
private void downloadPathMaps(ILaunchConfiguration cfg, final Runnable done) throws Exception {
readPathMapConfiguration(cfg);
- final IPathMap path_map_service = getService(IPathMap.class);
- path_map_service.set(host_path_map.toArray(new IPathMap.PathMapRule[host_path_map.size()]), new IPathMap.DoneSet() {
+ applyPathMap(channel, host_path_map.toArray(new IPathMap.PathMapRule[host_path_map.size()]), new IPathMap.DoneSet() {
+ @Override
public void doneSet(IToken token, Exception error) {
if (error != null) channel.terminate(error);
else done.run();
@@ -752,6 +763,18 @@ public class TCFLaunch extends Launch {
});
}
+ /**
+ * Apply the path map to the given channel.
+ *
+ * @param channel The channel. Must not be <code>null</code>.
+ * @param map The path map. Must not be <code>null</code>.
+ * @param done The done to invoke. Must not be <code>null</code>.
+ */
+ protected void applyPathMap(final IChannel channel, final IPathMap.PathMapRule[] map, final IPathMap.DoneSet done) {
+ IPathMap path_map_service = getService(IPathMap.class);
+ path_map_service.set(map, done);
+ }
+
private String[] toArgsArray(String file, String cmd) {
// Create arguments list from a command line.
int i = 0;
@@ -1207,8 +1230,7 @@ public class TCFLaunch extends Launch {
if (update_memory_maps != null) update_memory_maps.run();
if (host_path_map != null) {
readPathMapConfiguration(cfg);
- final IPathMap path_map_service = getService(IPathMap.class);
- path_map_service.set(host_path_map.toArray(new IPathMap.PathMapRule[host_path_map.size()]), new IPathMap.DoneSet() {
+ applyPathMap(channel, host_path_map.toArray(new IPathMap.PathMapRule[host_path_map.size()]), new IPathMap.DoneSet() {
public void doneSet(IToken token, Exception error) {
if (error != null) channel.terminate(error);
done(false);
diff --git a/target_explorer/plugins/org.eclipse.tcf.te.tcf.launch.core/src/org/eclipse/tcf/te/tcf/launch/core/delegates/Launch.java b/target_explorer/plugins/org.eclipse.tcf.te.tcf.launch.core/src/org/eclipse/tcf/te/tcf/launch/core/delegates/Launch.java
index 4424b0f00..d48ec0682 100644
--- a/target_explorer/plugins/org.eclipse.tcf.te.tcf.launch.core/src/org/eclipse/tcf/te/tcf/launch/core/delegates/Launch.java
+++ b/target_explorer/plugins/org.eclipse.tcf.te.tcf.launch.core/src/org/eclipse/tcf/te/tcf/launch/core/delegates/Launch.java
@@ -9,8 +9,10 @@
*******************************************************************************/
package org.eclipse.tcf.te.tcf.launch.core.delegates;
+import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashMap;
+import java.util.Iterator;
import java.util.List;
import java.util.Map;
@@ -20,6 +22,9 @@ import org.eclipse.debug.core.ILaunch;
import org.eclipse.debug.core.ILaunchConfiguration;
import org.eclipse.tcf.internal.debug.model.TCFLaunch;
import org.eclipse.tcf.protocol.IChannel;
+import org.eclipse.tcf.protocol.IToken;
+import org.eclipse.tcf.services.IPathMap;
+import org.eclipse.tcf.services.IPathMap.DoneSet;
import org.eclipse.tcf.services.IPathMap.PathMapRule;
import org.eclipse.tcf.te.runtime.interfaces.properties.IPropertiesContainer;
import org.eclipse.tcf.te.runtime.properties.PropertiesContainer;
@@ -103,6 +108,72 @@ public final class Launch extends TCFLaunch {
}
/* (non-Javadoc)
+ * @see org.eclipse.tcf.internal.debug.model.TCFLaunch#applyPathMap(org.eclipse.tcf.protocol.IChannel, org.eclipse.tcf.services.IPathMap.PathMapRule[], org.eclipse.tcf.services.IPathMap.DoneSet)
+ */
+ @Override
+ protected void applyPathMap(final IChannel channel, final PathMapRule[] map, final DoneSet done) {
+ // Get the client ID
+ final String clientID = getClientID();
+ // If we have a client ID, we can identify path map rules set by other clients
+ // and leave them alone. Otherwise, just set the path map.
+ if (clientID != null) {
+ final IPathMap svc = getService(IPathMap.class);
+ if (svc != null) {
+ // Get the old path maps first. Keep path map rules not coming from us
+ svc.get(new IPathMap.DoneGet() {
+ @Override
+ public void doneGet(IToken token, Exception error, PathMapRule[] oldMap) {
+ // Merge the maps to a new list
+ List<PathMapRule> rules = new ArrayList<PathMapRule>();
+
+ if (oldMap != null && oldMap.length > 0) {
+ for (PathMapRule rule : oldMap) {
+ if (rule.getID() == null || !rule.getID().startsWith(clientID)) {
+ rules.add(rule);
+ }
+ }
+ }
+
+ rules.addAll(Arrays.asList(map));
+
+ // Determine if the map has changed
+ boolean changed = oldMap != null ? oldMap.length != rules.size() : !rules.isEmpty();
+ if (!changed && !rules.isEmpty()) {
+ // Make a copy of new map and remove all rules listed
+ // by the old map. If not empty at the end, the new map
+ // is different from the old map.
+ List<PathMapRule> copy = new ArrayList<PathMapRule>(rules);
+ for (PathMapRule rule : oldMap) {
+ Iterator<PathMapRule> iter = copy.iterator();
+ while (iter.hasNext()) {
+ PathMapRule r = iter.next();
+ if (r.equals(rule)) {
+ iter.remove();
+ break;
+ }
+ }
+ }
+
+ changed = !copy.isEmpty();
+ }
+
+ // If the path map has changed, apply the map
+ if (changed) {
+ svc.set(rules.toArray(new PathMapRule[rules.size()]), done);
+ } else {
+ done.doneSet(token, null);
+ }
+ }
+ });
+ } else {
+ done.doneSet(null, null);
+ }
+ } else {
+ super.applyPathMap(channel, map, done);
+ }
+ }
+
+ /* (non-Javadoc)
* @see org.eclipse.debug.core.Launch#getAdapter(java.lang.Class)
*/
@Override
diff --git a/target_explorer/plugins/org.eclipse.tcf.te.tcf.launch.core/src/org/eclipse/tcf/te/tcf/launch/core/internal/services/PathMapService.java b/target_explorer/plugins/org.eclipse.tcf.te.tcf.launch.core/src/org/eclipse/tcf/te/tcf/launch/core/internal/services/PathMapService.java
index 6679182bb..423ed62a5 100644
--- a/target_explorer/plugins/org.eclipse.tcf.te.tcf.launch.core/src/org/eclipse/tcf/te/tcf/launch/core/internal/services/PathMapService.java
+++ b/target_explorer/plugins/org.eclipse.tcf.te.tcf.launch.core/src/org/eclipse/tcf/te/tcf/launch/core/internal/services/PathMapService.java
@@ -11,6 +11,7 @@ package org.eclipse.tcf.te.tcf.launch.core.internal.services;
import java.util.ArrayList;
import java.util.Arrays;
+import java.util.Iterator;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
@@ -340,7 +341,30 @@ public class PathMapService extends AbstractService implements IPathMapService {
}
rules.addAll(Arrays.asList(configuredMap));
- if (!rules.isEmpty()) {
+
+ // Determine if the map has changed
+ boolean changed = map != null ? map.length != rules.size() : !rules.isEmpty();
+ if (!changed && !rules.isEmpty()) {
+ // Make a copy of new map and remove all rules listed
+ // by the old map. If not empty at the end, the new map
+ // is different from the old map.
+ List<PathMapRule> copy = new ArrayList<PathMapRule>(rules);
+ for (PathMapRule rule : map) {
+ Iterator<PathMapRule> iter = copy.iterator();
+ while (iter.hasNext()) {
+ PathMapRule r = iter.next();
+ if (r.equals(rule)) {
+ iter.remove();
+ break;
+ }
+ }
+ }
+
+ changed = !copy.isEmpty();
+ }
+
+ // If the path map has changed, apply the map
+ if (changed) {
svc.set(rules.toArray(new PathMapRule[rules.size()]), new IPathMap.DoneSet() {
@Override
public void doneSet(IToken token, Exception error) {

Back to the top