diff options
7 files changed, 98 insertions, 41 deletions
diff --git a/docs/TCF Service - Run Control.html b/docs/TCF Service - Run Control.html index 785770f04..b018a68e6 100644 --- a/docs/TCF Service - Run Control.html +++ b/docs/TCF Service - Run Control.html @@ -273,6 +273,19 @@ to context's children. Only contexts with HasState = true can be resumed.</p> </li> </ul> +<p>Resume parameters names:</p> + <ul> + <li> + <code>RP_RANGE_START = "RangeStart"</code> + starting address of step range, inclusive. + </li> + <li> + <code>RP_RANGE_END = "RangeEnd"</code> + ending address of step range, exclusive. + </li> + </ul> + + <p>Result message:</p> <pre><b><font face="Courier New" size=2 color=#333399> diff --git a/plugins/org.eclipse.tm.tcf.core/src/org/eclipse/tm/tcf/services/IRunControl.java b/plugins/org.eclipse.tm.tcf.core/src/org/eclipse/tm/tcf/services/IRunControl.java index c47bb7d17..d23c24ef4 100644 --- a/plugins/org.eclipse.tm.tcf.core/src/org/eclipse/tm/tcf/services/IRunControl.java +++ b/plugins/org.eclipse.tm.tcf.core/src/org/eclipse/tm/tcf/services/IRunControl.java @@ -134,7 +134,7 @@ public interface IRunControl extends IService { /** * Step over instructions until PC is outside the specified range. - * If any function call within the range is considered to be in range. + * Any function call within the range is considered to be in range. */ RM_STEP_OVER_RANGE = 12, @@ -178,6 +178,17 @@ public interface IRunControl extends IService { STATE_BREAKPOINT_IDS = "BPs"; /** + * Optional parameters of resume command. + */ + static final String + /** Integer - starting address of step range, inclusive */ + RP_RANGE_START = "RangeStart", + + /** Integer - ending address of step range, exclusive */ + RP_RANGE_END = "RangeEnd"; + + + /** * Retrieve context properties for given context ID. * * @param id – context ID. @@ -347,7 +358,7 @@ public interface IRunControl extends IService { * Also resumes children if context is a container. * @param mode - defines how to resume the context, see RM_*. * @param count - if mode implies stepping, defines how many steps to perform. - * @param params - resume parameters, for example, step range definition. + * @param params - resume parameters, for example, step range definition, see RP_*. * @param done - command result call back object. * @return pending command handle, can be used to cancel the command. */ diff --git a/plugins/org.eclipse.tm.tcf.debug.ui/src/org/eclipse/tm/internal/tcf/debug/ui/commands/StepIntoCommand.java b/plugins/org.eclipse.tm.tcf.debug.ui/src/org/eclipse/tm/internal/tcf/debug/ui/commands/StepIntoCommand.java index 1a050b818..451792c57 100644 --- a/plugins/org.eclipse.tm.tcf.debug.ui/src/org/eclipse/tm/internal/tcf/debug/ui/commands/StepIntoCommand.java +++ b/plugins/org.eclipse.tm.tcf.debug.ui/src/org/eclipse/tm/internal/tcf/debug/ui/commands/StepIntoCommand.java @@ -23,7 +23,6 @@ import org.eclipse.tm.internal.tcf.debug.ui.model.TCFNodeExecContext; import org.eclipse.tm.internal.tcf.debug.ui.model.TCFNodeStackFrame; import org.eclipse.tm.tcf.protocol.IChannel; import org.eclipse.tm.tcf.services.IRunControl; -import org.eclipse.tm.tcf.services.IStackTrace.StackTraceContext; import org.eclipse.tm.tcf.util.TCFDataCache; @@ -58,13 +57,6 @@ public class StepIntoCommand extends StepCommand implements IStepIntoHandler { } @Override - protected TCFDataCache<StackTraceContext> getStackFrame() { - if (frame == null) frame = node.getStackTrace().getTopFrame(); - if (frame == null) return null; - return frame.getStackTraceContext(); - } - - @Override protected int getStackFrameIndex() { if (frame == null) frame = node.getStackTrace().getTopFrame(); if (frame == null) return 0; diff --git a/plugins/org.eclipse.tm.tcf.debug.ui/src/org/eclipse/tm/internal/tcf/debug/ui/model/TCFNodeExecContext.java b/plugins/org.eclipse.tm.tcf.debug.ui/src/org/eclipse/tm/internal/tcf/debug/ui/model/TCFNodeExecContext.java index caacd2681..9f2a1a4d9 100644 --- a/plugins/org.eclipse.tm.tcf.debug.ui/src/org/eclipse/tm/internal/tcf/debug/ui/model/TCFNodeExecContext.java +++ b/plugins/org.eclipse.tm.tcf.debug.ui/src/org/eclipse/tm/internal/tcf/debug/ui/model/TCFNodeExecContext.java @@ -610,6 +610,7 @@ public class TCFNodeExecContext extends TCFNode implements ISymbolOwner { void onContextChanged(IMemory.MemoryContext context) { assert !disposed; + line_info_cache.clear(); mem_context.reset(context); for (TCFNodeSymbol s : symbols.values()) s.onMemoryMapChanged(); postAllChangedDelta(); @@ -704,6 +705,7 @@ public class TCFNodeExecContext extends TCFNode implements ISymbolOwner { } void onMemoryMapChanged() { + line_info_cache.clear(); memory_map.reset(); children_exec.onMemoryMapChanged(); children_stack.onMemoryMapChanged(); 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 ae4c8f7d8..39bc2b370 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 @@ -85,7 +85,6 @@ public class TCFNodeStackFrame extends TCFNode { return false; } }; - final Map<BigInteger,TCFSourceRef> line_info_cache = parent.getLineInfoCache(); line_info = new TCFDataCache<TCFSourceRef>(channel) { @Override protected boolean startDataRetrieval() { @@ -107,6 +106,11 @@ public class TCFNodeStackFrame extends TCFNode { } p = p.parent; } + if (p == null) { + set(null, null, null); + return true; + } + final Map<BigInteger,TCFSourceRef> line_info_cache = ((TCFNodeExecContext)p).getLineInfoCache(); TCFSourceRef l = line_info_cache.get(n); if (l != null) { l.context = mem_ctx; @@ -124,15 +128,27 @@ public class TCFNodeStackFrame extends TCFNode { final BigInteger n0 = n; final BigInteger n1 = n0.add(BigInteger.valueOf(1)); final IMemory.MemoryContext ctx = mem_ctx; - command = ln.mapToSource(parent.id, n0, n1, new ILineNumbers.DoneMapToSource() { + command = ln.mapToSource(p.id, n0, n1, new ILineNumbers.DoneMapToSource() { public void doneMapToSource(IToken token, Exception error, ILineNumbers.CodeArea[] areas) { TCFSourceRef l = new TCFSourceRef(); l.context = ctx; l.address = n0; if (error == null && areas != null && areas.length > 0) { for (ILineNumbers.CodeArea area : areas) { - if (l.area == null || area.start_line < l.area.start_line) { - l.area = area; + BigInteger a0 = toBigInteger(area.start_address); + BigInteger a1 = toBigInteger(area.end_address); + if (n0.compareTo(a0) >= 0 && n0.compareTo(a1) < 0) { + if (l.area == null || area.start_line < l.area.start_line) { + if (area.start_address != a0 || area.end_address != a1) { + area = new ILineNumbers.CodeArea(area.directory, area.file, + area.start_line, area.start_column, + area.end_line, area.end_column, + a0, a1, area.isa, + area.is_statement, area.basic_block, + area.prologue_end, area.epilogue_begin); + } + l.area = area; + } } } } @@ -156,7 +172,7 @@ public class TCFNodeStackFrame extends TCFNode { return true; } if (n != null) { - set(null, null, new BigInteger(n.toString())); + set(null, null, toBigInteger(n)); return true; } } @@ -215,11 +231,7 @@ public class TCFNodeStackFrame extends TCFNode { assert Protocol.isDispatchThread(); if (!stack_trace_context.isValid()) return null; IStackTrace.StackTraceContext ctx = stack_trace_context.getData(); - if (ctx != null) { - Number n = ctx.getReturnAddress(); - if (n instanceof BigInteger) return (BigInteger)n; - if (n != null) return new BigInteger(n.toString()); - } + if (ctx != null) return toBigInteger(ctx.getReturnAddress()); return null; } @@ -337,6 +349,12 @@ public class TCFNodeStackFrame extends TCFNode { return true; } + private BigInteger toBigInteger(Number n) { + if (n == null) return null; + if (n instanceof BigInteger) return (BigInteger)n; + return new BigInteger(n.toString()); + } + private String getModuleName(BigInteger pc, Runnable done) { TCFDataCache<IRunControl.RunControlContext> parent_dc = ((TCFNodeExecContext)parent).getRunContext(); if (!parent_dc.validate(done)) return null; diff --git a/plugins/org.eclipse.tm.tcf.debug/src/org/eclipse/tm/internal/tcf/debug/actions/TCFActionStepInto.java b/plugins/org.eclipse.tm.tcf.debug/src/org/eclipse/tm/internal/tcf/debug/actions/TCFActionStepInto.java index 83ba8aa79..0a9689628 100644 --- a/plugins/org.eclipse.tm.tcf.debug/src/org/eclipse/tm/internal/tcf/debug/actions/TCFActionStepInto.java +++ b/plugins/org.eclipse.tm.tcf.debug/src/org/eclipse/tm/internal/tcf/debug/actions/TCFActionStepInto.java @@ -11,6 +11,7 @@ package org.eclipse.tm.internal.tcf.debug.actions; import java.math.BigInteger; +import java.util.HashMap; import java.util.Map; import org.eclipse.tm.internal.tcf.debug.model.TCFContextState; @@ -20,7 +21,6 @@ import org.eclipse.tm.tcf.protocol.IToken; import org.eclipse.tm.tcf.protocol.Protocol; import org.eclipse.tm.tcf.services.ILineNumbers; import org.eclipse.tm.tcf.services.IRunControl; -import org.eclipse.tm.tcf.services.IStackTrace; import org.eclipse.tm.tcf.services.IRunControl.RunControlContext; import org.eclipse.tm.tcf.util.TCFDataCache; @@ -48,7 +48,6 @@ public abstract class TCFActionStepInto extends TCFAction implements IRunControl protected abstract TCFDataCache<TCFContextState> getContextState(); protected abstract TCFDataCache<TCFSourceRef> getLineInfo(); protected abstract TCFDataCache<?> getStackTrace(); - protected abstract TCFDataCache<IStackTrace.StackTraceContext> getStackFrame(); protected abstract int getStackFrameIndex(); public void run() { @@ -123,11 +122,8 @@ public abstract class TCFActionStepInto extends TCFAction implements IRunControl exit(null); return; } + BigInteger pc = new BigInteger(state.getData().suspend_pc); if (step_cnt > 0) { - TCFDataCache<IStackTrace.StackTraceContext> frame = getStackFrame(); - if (!frame.validate(this)) return; - Number addr = frame.getData().getInstructionAddress(); - BigInteger pc = addr instanceof BigInteger ? (BigInteger)addr : new BigInteger(addr.toString()); if (pc == null || pc0 == null || pc1 == null) { exit(null); return; @@ -135,24 +131,37 @@ public abstract class TCFActionStepInto extends TCFAction implements IRunControl if (pc.compareTo(pc0) < 0 || pc.compareTo(pc1) >= 0) { if (!line_info.validate(this)) return; TCFSourceRef ref = line_info.getData(); - if (ref != null && ref.area != null) { - if (isSameLine(source_ref.area, ref.area)) { - source_ref = ref; - ILineNumbers.CodeArea area = source_ref.area; - if (area.start_address instanceof BigInteger) pc0 = (BigInteger)area.start_address; - else if (area.start_address != null) pc0 = new BigInteger(area.start_address.toString()); - if (area.end_address instanceof BigInteger) pc1 = (BigInteger)area.end_address; - else if (area.end_address != null) pc1 = new BigInteger(area.end_address.toString()); - } - else { - exit(null); - return; - } + if (ref == null || ref.area == null) { + // No line info for current PC, continue stepping + } + else if (isSameLine(source_ref.area, ref.area)) { + source_ref = ref; + ILineNumbers.CodeArea area = source_ref.area; + if (area.start_address instanceof BigInteger) pc0 = (BigInteger)area.start_address; + else if (area.start_address != null) pc0 = new BigInteger(area.start_address.toString()); + if (area.end_address instanceof BigInteger) pc1 = (BigInteger)area.end_address; + else if (area.end_address != null) pc1 = new BigInteger(area.end_address.toString()); + } + else { + exit(null); + return; } } } step_cnt++; - if (ctx.canResume(IRunControl.RM_STEP_INTO)) { + if (ctx.canResume(IRunControl.RM_STEP_INTO_RANGE) && + pc != null && pc0 != null && pc1 != null && + pc.compareTo(pc0) >= 0 && pc.compareTo(pc1) < 0) { + HashMap<String,Object> args = new HashMap<String,Object>(); + args.put(IRunControl.RP_RANGE_START, pc0); + args.put(IRunControl.RP_RANGE_END, pc1); + ctx.resume(IRunControl.RM_STEP_INTO_RANGE, 1, args, new IRunControl.DoneCommand() { + public void doneCommand(IToken token, Exception error) { + if (error != null) exit(error); + } + }); + } + else if (ctx.canResume(IRunControl.RM_STEP_INTO)) { ctx.resume(IRunControl.RM_STEP_INTO, 1, new IRunControl.DoneCommand() { public void doneCommand(IToken token, Exception error) { if (error != null) exit(error); diff --git a/plugins/org.eclipse.tm.tcf.debug/src/org/eclipse/tm/internal/tcf/debug/actions/TCFActionStepOver.java b/plugins/org.eclipse.tm.tcf.debug/src/org/eclipse/tm/internal/tcf/debug/actions/TCFActionStepOver.java index ba60c4318..40141fb37 100644 --- a/plugins/org.eclipse.tm.tcf.debug/src/org/eclipse/tm/internal/tcf/debug/actions/TCFActionStepOver.java +++ b/plugins/org.eclipse.tm.tcf.debug/src/org/eclipse/tm/internal/tcf/debug/actions/TCFActionStepOver.java @@ -164,13 +164,13 @@ public abstract class TCFActionStepOver extends TCFAction implements IRunControl }); bp = null; } + BigInteger pc = new BigInteger(state.getData().suspend_pc); if (step_cnt > 0) { if (pc0 == null && pc1 == null || state.getData().suspend_pc == null) { exit(null); return; } assert src_step; - BigInteger pc = new BigInteger(state.getData().suspend_pc); if (pc.compareTo(pc0) < 0 || pc.compareTo(pc1) >= 0) { if (!line_info.validate(this)) return; TCFSourceRef ref = line_info.getData(); @@ -203,6 +203,18 @@ public abstract class TCFActionStepOver extends TCFAction implements IRunControl } }); } + else if (ctx.canResume(IRunControl.RM_STEP_INTO_RANGE) && + pc != null && pc0 != null && pc1 != null && + pc.compareTo(pc0) >= 0 && pc.compareTo(pc1) < 0) { + HashMap<String,Object> args = new HashMap<String,Object>(); + args.put(IRunControl.RP_RANGE_START, pc0); + args.put(IRunControl.RP_RANGE_END, pc1); + ctx.resume(IRunControl.RM_STEP_INTO_RANGE, 1, args, new IRunControl.DoneCommand() { + public void doneCommand(IToken token, Exception error) { + if (error != null) exit(error); + } + }); + } else if (ctx.canResume(IRunControl.RM_STEP_INTO)) { ctx.resume(IRunControl.RM_STEP_INTO, 1, new IRunControl.DoneCommand() { public void doneCommand(IToken token, Exception error) { |