diff options
author | eutarass | 2008-06-04 20:57:08 +0000 |
---|---|---|
committer | eutarass | 2008-06-04 20:57:08 +0000 |
commit | 72cddcac552c4ae7d945157e34bd5d737d6e801d (patch) | |
tree | 11a73bbf915d49c38629b161f468e31565976411 | |
parent | c8ed77ecfd7c897791825f30846b5f5c09d534af (diff) | |
download | org.eclipse.tcf-72cddcac552c4ae7d945157e34bd5d737d6e801d.tar.gz org.eclipse.tcf-72cddcac552c4ae7d945157e34bd5d737d6e801d.tar.xz org.eclipse.tcf-72cddcac552c4ae7d945157e34bd5d737d6e801d.zip |
1. Source line breakpoints are implemented.
2. TCF agent bug fixed: hash functions could return negative number causing memory corruption.
3. TCF agent: switched to latest version of dbghelp.dll - Windows XP comes with broken version of the DLL.
4. TCF agent: fixed a bug in DWARF line number information reader.
7 files changed, 200 insertions, 40 deletions
diff --git a/plugins/org.eclipse.tm.tcf.debug.ui/src/org/eclipse/tm/internal/tcf/debug/ui/launch/TCFMainTab.java b/plugins/org.eclipse.tm.tcf.debug.ui/src/org/eclipse/tm/internal/tcf/debug/ui/launch/TCFMainTab.java index ce3998550..c7d700abc 100644 --- a/plugins/org.eclipse.tm.tcf.debug.ui/src/org/eclipse/tm/internal/tcf/debug/ui/launch/TCFMainTab.java +++ b/plugins/org.eclipse.tm.tcf.debug.ui/src/org/eclipse/tm/internal/tcf/debug/ui/launch/TCFMainTab.java @@ -177,6 +177,7 @@ public class TCFMainTab extends AbstractLaunchConfigurationTab { public void createControl(Composite parent) { display = parent.getDisplay(); + assert display != null; Font font = parent.getFont(); Composite comp = new Composite(parent, SWT.NONE); diff --git a/plugins/org.eclipse.tm.tcf.debug.ui/src/org/eclipse/tm/internal/tcf/debug/ui/model/TCFModel.java b/plugins/org.eclipse.tm.tcf.debug.ui/src/org/eclipse/tm/internal/tcf/debug/ui/model/TCFModel.java index 402c10a38..6445d105a 100644 --- a/plugins/org.eclipse.tm.tcf.debug.ui/src/org/eclipse/tm/internal/tcf/debug/ui/model/TCFModel.java +++ b/plugins/org.eclipse.tm.tcf.debug.ui/src/org/eclipse/tm/internal/tcf/debug/ui/model/TCFModel.java @@ -16,6 +16,7 @@ import java.util.Map; import java.util.TreeSet; import org.eclipse.core.runtime.CoreException; +import org.eclipse.debug.core.ILaunchConfiguration; import org.eclipse.debug.core.commands.IDisconnectHandler; import org.eclipse.debug.core.commands.IResumeHandler; import org.eclipse.debug.core.commands.IStepIntoHandler; @@ -81,6 +82,9 @@ public class TCFModel implements IElementContentProvider, IElementLabelProvider, private final Map<Class,Object> commands = new HashMap<Class,Object>(); private final TreeSet<FutureTask> queue = new TreeSet<FutureTask>(); + private static final Map<ILaunchConfiguration,IEditorInput> editor_not_found = + new HashMap<ILaunchConfiguration,IEditorInput>(); + private TCFNodeLaunch launch_node; private boolean disposed; @@ -548,7 +552,11 @@ public class TCFModel implements IElementContentProvider, IElementLabelProvider, source_element = ((ISourceLookupDirector)locator).getSourceElement(src_ref.area); } if (source_element == null) { - editor_input = new CommonSourceNotFoundEditorInput(src_ref.area); + ILaunchConfiguration cfg = launch.getLaunchConfiguration(); + editor_input = editor_not_found.get(cfg); + if (editor_input == null) { + editor_not_found.put(cfg, editor_input = new CommonSourceNotFoundEditorInput(cfg)); + } editor_id = IDebugUIConstants.ID_COMMON_SOURCE_NOT_FOUND_EDITOR; } else { @@ -638,7 +646,7 @@ public class TCFModel implements IElementContentProvider, IElementLabelProvider, try { IDocument document = provider.getDocument(input); if (document != null) - return document.getLineInformation(lineNumber); + return document.getLineInformation(lineNumber - 1); } catch (BadLocationException e) { } diff --git a/plugins/org.eclipse.tm.tcf.debug.ui/src/org/eclipse/tm/internal/tcf/debug/ui/model/TCFNodeStackFrame.java b/plugins/org.eclipse.tm.tcf.debug.ui/src/org/eclipse/tm/internal/tcf/debug/ui/model/TCFNodeStackFrame.java index 017735dec..c4b9fa308 100644 --- a/plugins/org.eclipse.tm.tcf.debug.ui/src/org/eclipse/tm/internal/tcf/debug/ui/model/TCFNodeStackFrame.java +++ b/plugins/org.eclipse.tm.tcf.debug.ui/src/org/eclipse/tm/internal/tcf/debug/ui/model/TCFNodeStackFrame.java @@ -243,7 +243,7 @@ public class TCFNodeStackFrame extends TCFNode { else { String label = makeHexAddrString(l.address); if (l.area != null && l.area.file != null) { - label += ": " + l.area.file + ", line " + (l.area.start_line + 1); + label += ": " + l.area.file + ", line " + l.area.start_line; } result.setLabel(label, 0); } diff --git a/plugins/org.eclipse.tm.tcf.debug/src/org/eclipse/tm/internal/tcf/debug/launch/TCFSourceLookupParticipant.java b/plugins/org.eclipse.tm.tcf.debug/src/org/eclipse/tm/internal/tcf/debug/launch/TCFSourceLookupParticipant.java index 717af08e3..5ef55e5ee 100644 --- a/plugins/org.eclipse.tm.tcf.debug/src/org/eclipse/tm/internal/tcf/debug/launch/TCFSourceLookupParticipant.java +++ b/plugins/org.eclipse.tm.tcf.debug/src/org/eclipse/tm/internal/tcf/debug/launch/TCFSourceLookupParticipant.java @@ -10,7 +10,13 @@ *******************************************************************************/ package org.eclipse.tm.internal.tcf.debug.launch; +import java.io.File; + +import org.eclipse.core.resources.IFile; +import org.eclipse.core.resources.ResourcesPlugin; import org.eclipse.core.runtime.CoreException; +import org.eclipse.core.runtime.IPath; +import org.eclipse.core.runtime.Path; import org.eclipse.debug.core.sourcelookup.AbstractSourceLookupParticipant; import org.eclipse.tm.tcf.services.ILineNumbers; @@ -21,10 +27,40 @@ import org.eclipse.tm.tcf.services.ILineNumbers; public class TCFSourceLookupParticipant extends AbstractSourceLookupParticipant { public String getSourceName(Object object) throws CoreException { + if (object instanceof String) { + return (String)object; + } if (object instanceof ILineNumbers.CodeArea) { ILineNumbers.CodeArea area = (ILineNumbers.CodeArea)object; + // TODO: map file path from remote file system to local + if (area.directory != null && area.file != null) { + return new File(area.directory, area.file).getAbsolutePath(); + } return area.file; } return null; } + + @Override + public Object[] findSourceElements(Object object) throws CoreException { + String name = getSourceName(object); + if (name != null) { + IPath path = new Path(name); + if (path.isAbsolute()) { + IFile[] arr = ResourcesPlugin.getWorkspace().getRoot().findFilesForLocation(path); + if (arr != null && arr.length > 0) return arr; + } + } + Object[] res = super.findSourceElements(name); + if (name != null && (res == null || res.length == 0)) { + // Remove file path and search by file base name + String base = name; + int i = name.lastIndexOf('/'); + int j = name.lastIndexOf('\\'); + if (i > j) base = name.substring(i + 1); + if (j > i) base = name.substring(j + 1); + res = super.findSourceElements(base); + } + return res; + } } diff --git a/plugins/org.eclipse.tm.tcf.debug/src/org/eclipse/tm/internal/tcf/debug/model/TCFBreakpointsModel.java b/plugins/org.eclipse.tm.tcf.debug/src/org/eclipse/tm/internal/tcf/debug/model/TCFBreakpointsModel.java index 00ae04f60..a38779f98 100644 --- a/plugins/org.eclipse.tm.tcf.debug/src/org/eclipse/tm/internal/tcf/debug/model/TCFBreakpointsModel.java +++ b/plugins/org.eclipse.tm.tcf.debug/src/org/eclipse/tm/internal/tcf/debug/model/TCFBreakpointsModel.java @@ -44,7 +44,6 @@ import org.eclipse.tm.tcf.services.IBreakpoints; */ public class TCFBreakpointsModel implements IBreakpointListener, IBreakpointManagerListener { - private static final String PROP_ID = "ID"; private final IBreakpointManager bp_manager = DebugPlugin.getDefault().getBreakpointManager(); public TCFBreakpointsModel() { @@ -66,20 +65,31 @@ public class TCFBreakpointsModel implements IBreakpointListener, IBreakpointMana return true; } + private String getBreakpointID(IBreakpoint bp) throws CoreException { + IMarker marker = bp.getMarker(); + String id = (String)marker.getAttributes().get(ITCFConstants.ID_TCF_DEBUG_MODEL + '.' + IBreakpoints.PROP_ID); + if (id != null) return id; + id = marker.getResource().getLocationURI().toString(); + if (id == null) return null; + return id + ':' + marker.getId(); + } + @SuppressWarnings("unchecked") public void downloadBreakpoints(final IChannel channel, final Runnable done) throws IOException, CoreException { assert Protocol.isDispatchThread(); IBreakpoints service = channel.getRemoteService(IBreakpoints.class); if (service != null) { - IBreakpoint[] arr = bp_manager.getBreakpoints(ITCFConstants.ID_TCF_DEBUG_MODEL); + IBreakpoint[] arr = bp_manager.getBreakpoints(); if (arr != null && arr.length > 0) { Map<String,Object>[] bps = new Map[arr.length]; for (int i = 0; i < arr.length; i++) { if (!isSupported(channel, arr[i])) continue; + String id = getBreakpointID(arr[i]); + if (id == null) continue; IMarker marker = arr[i].getMarker(); String file = getFilePath(marker.getResource()); - bps[i] = toBreakpointAttributes(file, marker.getAttributes()); + bps[i] = toBreakpointAttributes(id, file, marker.getAttributes()); } service.set(bps, new IBreakpoints.DoneCommand() { public void doneCommand(IToken token, Exception error) { @@ -95,15 +105,15 @@ public class TCFBreakpointsModel implements IBreakpointListener, IBreakpointMana public void breakpointManagerEnablementChanged(final boolean enabled) { try { - IBreakpoint[] arr = bp_manager.getBreakpoints(ITCFConstants.ID_TCF_DEBUG_MODEL); + IBreakpoint[] arr = bp_manager.getBreakpoints(); if (arr == null || arr.length == 0) return; final Map<String,IBreakpoint> map = new HashMap<String,IBreakpoint>(); for (int i = 0; i < arr.length; i++) { IMarker marker = arr[i].getMarker(); Boolean b = marker.getAttribute(IBreakpoint.ENABLED, Boolean.FALSE); if (!b.booleanValue()) continue; - String id = marker.getAttribute(ITCFConstants.ID_TCF_DEBUG_MODEL + - '.' + IBreakpoints.PROP_ID, (String)null); + String id = getBreakpointID(arr[i]); + if (id == null) continue; map.put(id, arr[i]); } if (map.isEmpty()) return; @@ -162,6 +172,7 @@ public class TCFBreakpointsModel implements IBreakpointListener, IBreakpointMana private final ILaunch[] launches; private final Map<String,Object> marker_attrs; private final String marker_file; + private final String marker_id; IBreakpoints service; IBreakpoints.DoneCommand done; @@ -172,6 +183,7 @@ public class TCFBreakpointsModel implements IBreakpointListener, IBreakpointMana this.breakpoint = breakpoint; marker_attrs = new HashMap<String,Object>(breakpoint.getMarker().getAttributes()); marker_file = getFilePath(breakpoint.getMarker().getResource()); + marker_id = getBreakpointID(breakpoint); launches = DebugPlugin.getDefault().getLaunchManager().getLaunches(); } @@ -182,22 +194,24 @@ public class TCFBreakpointsModel implements IBreakpointListener, IBreakpointMana } public void run() { - tcf_attrs = toBreakpointAttributes(marker_file, marker_attrs); - for (int i = 0; i < launches.length; i++) { - if (launches[i] instanceof TCFLaunch) { - final TCFLaunch launch = (TCFLaunch)launches[i]; - final IChannel channel = launch.getChannel(); - if (channel == null) continue; - if (channel.getState() != IChannel.STATE_OPEN) continue; - service = channel.getRemoteService(IBreakpoints.class); - if (service == null) continue; - if (!isSupported(channel, breakpoint)) continue; - done = new IBreakpoints.DoneCommand() { - public void doneCommand(IToken token, Exception error) { - if (error != null) channel.terminate(error); - } - }; - update(); + if (marker_id != null) { + tcf_attrs = toBreakpointAttributes(marker_id, marker_file, marker_attrs); + for (int i = 0; i < launches.length; i++) { + if (launches[i] instanceof TCFLaunch) { + final TCFLaunch launch = (TCFLaunch)launches[i]; + final IChannel channel = launch.getChannel(); + if (channel == null) continue; + if (channel.getState() != IChannel.STATE_OPEN) continue; + service = channel.getRemoteService(IBreakpoints.class); + if (service == null) continue; + if (!isSupported(channel, breakpoint)) continue; + done = new IBreakpoints.DoneCommand() { + public void doneCommand(IToken token, Exception error) { + if (error != null) channel.terminate(error); + } + }; + update(); + } } } Protocol.sync(new Runnable() { @@ -221,7 +235,6 @@ public class TCFBreakpointsModel implements IBreakpointListener, IBreakpointMana public void breakpointAdded(IBreakpoint breakpoint) { try { - if (!breakpoint.getModelIdentifier().equals(ITCFConstants.ID_TCF_DEBUG_MODEL)) return; new BreakpointUpdate(breakpoint) { @Override void update() { @@ -259,7 +272,6 @@ public class TCFBreakpointsModel implements IBreakpointListener, IBreakpointMana public void breakpointChanged(IBreakpoint breakpoint, IMarkerDelta delta) { try { - if (!breakpoint.getModelIdentifier().equals(ITCFConstants.ID_TCF_DEBUG_MODEL)) return; final Set<String> s = calcMarkerDeltaKeys(breakpoint.getMarker(), delta); if (s.isEmpty()) return; new BreakpointUpdate(breakpoint) { @@ -268,10 +280,10 @@ public class TCFBreakpointsModel implements IBreakpointListener, IBreakpointMana if (s.size() == 1 && s.contains(IBreakpoint.ENABLED)) { Boolean enabled = (Boolean)tcf_attrs.get(IBreakpoints.PROP_ENABLED); if (enabled == null || !enabled.booleanValue()) { - service.disable(new String[]{ (String)tcf_attrs.get(PROP_ID) }, done); + service.disable(new String[]{ (String)tcf_attrs.get(IBreakpoints.PROP_ID) }, done); } else { - service.enable(new String[]{ (String)tcf_attrs.get(PROP_ID) }, done); + service.enable(new String[]{ (String)tcf_attrs.get(IBreakpoints.PROP_ID) }, done); } } else { @@ -287,11 +299,10 @@ public class TCFBreakpointsModel implements IBreakpointListener, IBreakpointMana public void breakpointRemoved(IBreakpoint breakpoint, IMarkerDelta delta) { try { - if (!breakpoint.getModelIdentifier().equals(ITCFConstants.ID_TCF_DEBUG_MODEL)) return; new BreakpointUpdate(breakpoint) { @Override void update() { - service.remove(new String[]{ (String)tcf_attrs.get(PROP_ID) }, done); + service.remove(new String[]{ (String)tcf_attrs.get(IBreakpoints.PROP_ID) }, done); } }.exec(); } @@ -324,7 +335,7 @@ public class TCFBreakpointsModel implements IBreakpointListener, IBreakpointMana m.put(IMarker.MESSAGE, "Breakpoint: " + msg); Number line = (Number)p.get(IBreakpoints.PROP_LINE); if (line != null) { - m.put(IMarker.LINE_NUMBER, new Integer(line.intValue() + 1)); + m.put(IMarker.LINE_NUMBER, new Integer(line.intValue())); Number column = (Number)p.get(IBreakpoints.PROP_COLUMN); if (column != null) { m.put(IMarker.CHAR_START, new Integer(column.intValue())); @@ -334,9 +345,10 @@ public class TCFBreakpointsModel implements IBreakpointListener, IBreakpointMana return m; } - public Map<String,Object> toBreakpointAttributes(String file, Map<String,Object> p) { + public Map<String,Object> toBreakpointAttributes(String id, String file, Map<String,Object> p) { assert Protocol.isDispatchThread(); Map<String,Object> m = new HashMap<String,Object>(); + m.put(IBreakpoints.PROP_ID, id); for (Iterator<Map.Entry<String,Object>> i = p.entrySet().iterator(); i.hasNext();) { Map.Entry<String,Object> e = i.next(); String key = e.getKey(); @@ -349,14 +361,24 @@ public class TCFBreakpointsModel implements IBreakpointListener, IBreakpointMana m.put(IBreakpoints.PROP_ENABLED, enabled); } if (file != null) { - m.put(IBreakpoints.PROP_FILE, file); + // Map file path to remote file system + int i = file.lastIndexOf('/'); + int j = file.lastIndexOf('\\'); + String name = file; + if (i > j) name = file.substring(i + 1); + else if (i < j) name = file.substring(j + 1); + m.put(IBreakpoints.PROP_FILE, name); Integer line = (Integer)p.get(IMarker.LINE_NUMBER); if (line != null) { - m.put(IBreakpoints.PROP_LINE, new Integer(line.intValue() - 1)); + m.put(IBreakpoints.PROP_LINE, new Integer(line.intValue())); Integer column = (Integer)p.get(IMarker.CHAR_START); if (column != null) m.put(IBreakpoints.PROP_COLUMN, column); } } + String condition = (String)p.get("org.eclipse.cdt.debug.core.condition"); + if (condition != null && condition.length() > 0) m.put(IBreakpoints.PROP_CONDITION, condition); + Integer skip_count = (Integer)p.get("org.eclipse.cdt.debug.core.ignoreCount"); + if (skip_count != null && skip_count.intValue() > 0) m.put(IBreakpoints.PROP_SKIP_COUNT, skip_count); return m; } } diff --git a/plugins/org.eclipse.tm.tcf.dsf/src/org/eclipse/tm/internal/tcf/dsf/services/TCFDSFStack.java b/plugins/org.eclipse.tm.tcf.dsf/src/org/eclipse/tm/internal/tcf/dsf/services/TCFDSFStack.java index bd2e3ef45..c53702243 100644 --- a/plugins/org.eclipse.tm.tcf.dsf/src/org/eclipse/tm/internal/tcf/dsf/services/TCFDSFStack.java +++ b/plugins/org.eclipse.tm.tcf.dsf/src/org/eclipse/tm/internal/tcf/dsf/services/TCFDSFStack.java @@ -189,13 +189,13 @@ public class TCFDSFStack extends AbstractDsfService implements IStack { } public int getLine() { - if (code_area == null) return -1; - return code_area.start_line + 1; + if (code_area == null) return 0; + return code_area.start_line; } public int getColumn() { - if (code_area == null) return -1; - return code_area.start_column + 1; + if (code_area == null) return 0; + return code_area.start_column; } } diff --git a/plugins/org.eclipse.tm.tcf/src/org/eclipse/tm/tcf/services/ILineNumbers.java b/plugins/org.eclipse.tm.tcf/src/org/eclipse/tm/tcf/services/ILineNumbers.java index e562e6c60..4a4e11f81 100644 --- a/plugins/org.eclipse.tm.tcf/src/org/eclipse/tm/tcf/services/ILineNumbers.java +++ b/plugins/org.eclipse.tm.tcf/src/org/eclipse/tm/tcf/services/ILineNumbers.java @@ -10,6 +10,8 @@ *******************************************************************************/ package org.eclipse.tm.tcf.services; +import java.math.BigInteger; + import org.eclipse.tm.tcf.protocol.IService; import org.eclipse.tm.tcf.protocol.IToken; @@ -24,7 +26,7 @@ public interface ILineNumbers extends IService { /** * TextArea represent a continues area in source text mapped to * continues range of code addresses. - * Line and columns are counted starting from 0. + * Line and columns are counted starting from 1. * File name can be relative path, in such case client should * use TextArea directory name as origin for the path. * File and directory names are valid on a host where code was compiled. @@ -63,6 +65,97 @@ public interface ILineNumbers extends IService { this.prologue_end = prologue_end; this.epilogue_begin = epilogue_begin; } + + @Override + public boolean equals(Object o) { + if (this == o) return true; + if (!(o instanceof CodeArea)) return false; + CodeArea a = (CodeArea)o; + if (start_line != a.start_line) return false; + if (start_column != a.start_column) return false; + if (end_line != a.end_line) return false; + if (end_column != a.end_column) return false; + if (isa != a.isa) return false; + if (is_statement != a.is_statement) return false; + if (basic_block != a.basic_block) return false; + if (prologue_end != a.prologue_end) return false; + if (epilogue_begin != a.epilogue_begin) return false; + if (start_address != null && !start_address.equals(a.start_address)) return false; + if (start_address == null && a.start_address != null) return false; + if (end_address != null && !end_address.equals(a.end_address)) return false; + if (end_address == null && a.end_address != null) return false; + if (file != null && !file.equals(a.file)) return false; + if (file == null && a.file != null) return false; + if (directory != null && !directory.equals(a.directory)) return false; + if (directory == null && a.directory != null) return false; + return true; + } + + @Override + public int hashCode() { + int h = 0; + if (file != null) h += file.hashCode(); + return h + start_line + start_column + end_line + end_column; + } + + @Override + public String toString() { + StringBuffer bf = new StringBuffer(); + bf.append('['); + if (directory != null) { + bf.append(directory); + bf.append(':'); + } + if (file != null) { + bf.append(file); + bf.append(':'); + } + bf.append(start_line); + if (start_column != 0) { + bf.append('.'); + bf.append(start_column); + } + bf.append(".."); + bf.append(end_line); + if (end_column != 0) { + bf.append('.'); + bf.append(end_column); + } + bf.append(" -> "); + if (start_address != null) { + bf.append("0x"); + bf.append(new BigInteger(start_address.toString()).toString(16)); + } + else { + bf.append('0'); + } + bf.append(".."); + if (end_address != null) { + bf.append("0x"); + bf.append(new BigInteger(end_address.toString()).toString(16)); + } + else { + bf.append('0'); + } + if (isa != 0) { + bf.append(",isa "); + bf.append(isa); + } + if (is_statement) { + bf.append(",statement"); + } + if (basic_block) { + bf.append(",basic block"); + } + if (prologue_end) { + bf.append(",prologue end"); + } + if (epilogue_begin) { + bf.append(",epilogue begin"); + } + bf.append(']'); + return bf.toString(); + } } IToken mapToSource(String context_id, Number start_address, Number end_address, DoneMapToSource done); |