// These methods are not currently called by the Visual Studio debugger, so they don't need to be implemented int IDebugThread2.GetLogicalThread(IDebugStackFrame2 stackFrame, out IDebugLogicalThread2 logicalThread) { Debug.Fail("This function is not called by the debugger"); logicalThread = null; return(VSConstants.E_NOTIMPL); }
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// public int EnumCodePaths(string pszHint, IDebugCodeContext2 pStart, IDebugStackFrame2 pFrame, int fSource, out IEnumCodePaths2 ppEnum, out IDebugCodeContext2 ppSafety) { // // Enumerates the code paths of this program. // LoggingUtils.PrintFunction(); ppEnum = null; ppSafety = null; try { if (AttachedEngine == null) { throw new InvalidOperationException(); } LoggingUtils.RequireOk(AttachedEngine.NativeDebugger.NativeProgram.EnumCodePaths(pszHint, pStart, pFrame, fSource, out ppEnum, out ppSafety)); //LoggingUtils.RequireOk (AttachedEngine.JavaDebugger.JavaProgram.EnumCodePaths (pszHint, pStart, pFrame, fSource, out ppEnum, out ppSafety)); return(Constants.S_OK); } catch (Exception e) { LoggingUtils.HandleException(e); return(Constants.E_FAIL); } }
// Sets the next statement to the given stack frame and code context. int IDebugThread2.SetNextStatement(IDebugStackFrame2 stackFrame, IDebugCodeContext2 codeContext) { // CLRDBG TODO: This implementation should be changed to call an MI command ulong addr = ((AD7MemoryAddress)codeContext).Address; AD7StackFrame frame = ((AD7StackFrame)stackFrame); if (frame.ThreadContext.Level != 0 || frame.Thread != this || !frame.ThreadContext.pc.HasValue || _engine.DebuggedProcess.MICommandFactory.Mode == MIMode.Clrdbg) { return(Constants.S_FALSE); } string toFunc = EngineUtils.GetAddressDescription(_engine.DebuggedProcess, addr); string fromFunc = EngineUtils.GetAddressDescription(_engine.DebuggedProcess, frame.ThreadContext.pc.Value); if (toFunc != fromFunc) { return(Constants.S_FALSE); } string result = frame.EvaluateExpression("$pc=" + EngineUtils.AsAddr(addr)); if (result != null) { _engine.DebuggedProcess.ThreadCache.MarkDirty(); return(Constants.S_OK); } return(Constants.S_FALSE); }
public int EnumCodePaths(string pszHint, IDebugCodeContext2 pStart, IDebugStackFrame2 pFrame, int fSource, out IEnumCodePaths2 ppEnum, out IDebugCodeContext2 ppSafety) { ppEnum = null; ppSafety = null; return(VSConstants.E_NOTIMPL); }
public int EnumCodePaths(string pszHint, IDebugCodeContext2 pStart, IDebugStackFrame2 pFrame, int fSource, out IEnumCodePaths2 ppEnum, out IDebugCodeContext2 ppSafety) { DLog.Debug(DContext.VSDebuggerComCall, "IDebugProgram2.EnumCodePaths"); ppEnum = null; ppSafety = null; return(VSConstants.E_NOTIMPL); }
/// <summary> /// Dump memory with options from window /// </summary> /// <param name="program">VS internal program</param> /// <param name="frame">VS internal frame</param> private void DoDumpMemory(IDebugProgram2 program, IDebugStackFrame2 frame) { IsBusy = true; Progress = 0; uint left = _len; try { using (FileStream file = File.OpenWrite(Path)) { byte[] buffer = new byte[BUFFER_SIZE]; while (left > 0) { uint read = left < BUFFER_SIZE ? left : BUFFER_SIZE; if (!MemoryAction(program, frame, ref buffer, read, true, string.Format("{0}+{1}", _addr_expr, _len - left))) { break; } file.Write(buffer, 0, (int)read); left -= read; Progress = (float)(_len - left) / _len * 100; } if (left == 0) { MsgBox.Show(Resources.DumpSuccessText, Resources.SuccessDialogTitle, MessageBoxButton.OK, MessageBoxImage.Information); } } } catch (Exception ex) { ShowError(string.Format(Resources.DumpErrorText, ex.Message, left)); } IsBusy = false; Progress = 0; }
/// <summary> /// EnumCodePaths is used for the step-into specific feature -- right click on the current statment and decide which /// function to step into. This is not something that the SampleEngine supports. /// </summary> /// <param name="hint">The hint.</param> /// <param name="start">The start.</param> /// <param name="frame">The frame.</param> /// <param name="fSource">The f source.</param> /// <param name="pathEnum">The path enum.</param> /// <param name="safetyContext">The safety context.</param> /// <returns>If successful, returns S_OK; otherwise, returns an error code.</returns> public int EnumCodePaths(string hint, IDebugCodeContext2 start, IDebugStackFrame2 frame, int fSource, out IEnumCodePaths2 pathEnum, out IDebugCodeContext2 safetyContext) { pathEnum = null; safetyContext = null; return(E_NOTIMPL); }
/// <summary> /// Load memory with options from window /// </summary> /// <param name="program">VS internal program</param> /// <param name="frame">VS internal frame</param> private void DoLoadMemory(IDebugProgram2 program, IDebugStackFrame2 frame) { IsBusy = true; Progress = 0; uint pos = 0; try { using (FileStream file = File.OpenRead(Path)) { byte[] buffer = new byte[BUFFER_SIZE]; long len = file.Length; uint read; while ((read = (uint)file.Read(buffer, 0, BUFFER_SIZE)) != 0) { if (!MemoryAction(program, frame, ref buffer, read, false, string.Format("{0}+{1}", _addr_expr, pos))) { break; } pos += read; Progress = (float)pos / len * 100; } if (read == 0) { MsgBox.Show(Resources.LoadSuccessText, Resources.SuccessDialogTitle, MessageBoxButton.OK, MessageBoxImage.Information); } } } catch (Exception ex) { ShowError(string.Format(Resources.LoadErrorText, ex.Message, pos)); } IsBusy = false; Progress = 0; }
public int CanSetNextStatement(IDebugStackFrame2 pStackFrame, IDebugCodeContext2 pCodeContext) { DLog.Debug(DContext.VSDebuggerComCall, "IDebugThread2.CanSetNextStatement"); var stack = (DebugStackFrame)pStackFrame; var ctx = (DebugCodeContext)pCodeContext; if (stack == null || ctx == null) return VSConstants.E_FAIL; if (ctx.Location.Equals(stack.Location)) return VSConstants.S_OK; if (!ctx.Location.IsSameMethod(stack.Location)) return HResults.E_CANNOT_SETIP_TO_DIFFERENT_FUNCTION; // for now, only allow to set the position above the current position. if(ctx.Location.Index >= stack.Location.Index) return VSConstants.E_FAIL; // don't check existence of special code, so that we can produce a warning // below. //var loc = stack.GetDocumentLocationAsync().Await(DalvikProcess.VmTimeout); //if (loc.Document == null) // return VSConstants.E_FAIL; return VSConstants.S_OK; }
// Sets the next statement to the given stack frame and code context. int IDebugThread2.SetNextStatement(IDebugStackFrame2 stackFrame, IDebugCodeContext2 codeContext) { ulong addr = ((AD7MemoryAddress)codeContext).Address; AD7StackFrame frame = ((AD7StackFrame)stackFrame); if (frame.ThreadContext.Level != 0 || frame.Thread != this || !frame.ThreadContext.pc.HasValue) { return(Constants.S_FALSE); } string toFunc = EngineUtils.GetAddressDescription(_engine.DebuggedProcess, addr); string fromFunc = EngineUtils.GetAddressDescription(_engine.DebuggedProcess, frame.ThreadContext.pc.Value); if (toFunc != fromFunc) { return(Constants.S_FALSE); } string result = frame.EvaluateExpression("$pc=" + EngineUtils.AsAddr(addr, _engine.DebuggedProcess.Is64BitArch)); if (result != null) { _engine.DebuggedProcess.ThreadCache.MarkDirty(); return(Constants.S_OK); } return(Constants.S_FALSE); }
private IDebugStackFrame2 GetCurrentStackFrame(IDebugThread2 thread) { IEnumDebugFrameInfo2 enumDebugFrameInfo2; thread.EnumFrameInfo(enum_FRAMEINFO_FLAGS.FIF_FRAME, 10, out enumDebugFrameInfo2); uint pCeltFetched = 0; IDebugStackFrame2 stackFrame = null; uint count; enumDebugFrameInfo2.GetCount(out count); FRAMEINFO[] frameinfo = new FRAMEINFO[1]; if (count > 0 && enumDebugFrameInfo2.Next(1, frameinfo, ref pCeltFetched) == VSConstants.S_OK) { stackFrame = frameinfo[0].m_pFrame; } else { throw new InvalidOperationException("IDebugStackFrame2 is not available"); } return(stackFrame); }
public int EnumCodePaths( string hint, IDebugCodeContext2 start, IDebugStackFrame2 frame, int source, out IEnumCodePaths2 pathsEnum, out IDebugCodeContext2 safety) { pathsEnum = null; safety = null; return(VSConstants.E_NOTIMPL); }
// These methods are not currently called by the Visual Studio debugger, so they don't need to be implemented public int GetLogicalThread(IDebugStackFrame2 stackFrame, out IDebugLogicalThread2 logicalThread) { logicalThread = null; Debug.Fail("This function is not called by the debugger"); return(E_NOTIMPL); }
public int /*IDebugProgram3*/ EnumCodePaths(string pszHint, IDebugCodeContext2 pStart, IDebugStackFrame2 pFrame, int fSource, out IEnumCodePaths2 ppEnum, out IDebugCodeContext2 ppSafety) { throw new NotImplementedException(); }
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// #region IDebugThread2 Members //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// public int CanSetNextStatement(IDebugStackFrame2 stackFrame, IDebugCodeContext2 codeContext) { // // Determines whether the next statement can be set to the given stack frame and code context. // LoggingUtils.PrintFunction(); return(Constants.S_OK); }
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// public virtual int SetNextStatement(IDebugStackFrame2 stackFrame, IDebugCodeContext2 codeContext) { // // Sets the next statement to the given stack frame and code context. // LoggingUtils.PrintFunction(); return(Constants.E_NOTIMPL); }
// Sets the next statement to the given stack frame and code context. int IDebugThread2.SetNextStatement(IDebugStackFrame2 stackFrame, IDebugCodeContext2 codeContext) { var frame = (AD7StackFrame)stackFrame; var context = (AD7MemoryAddress)codeContext; if (frame.StackFrame.SetLineNumber((int)context.LineNumber + 1)) { return(VSConstants.S_OK); } return(VSConstants.E_FAIL); }
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// public int GetLogicalThread(IDebugStackFrame2 stackFrame, out IDebugLogicalThread2 logicalThread) { // // Gets the logical thread associated with this physical thread. Not implemented. // LoggingUtils.PrintFunction(); logicalThread = null; return(Constants.E_NOTIMPL); }
// Sets the next statement to the given stack frame and code context. int IDebugThread2.SetNextStatement(IDebugStackFrame2 stackFrame, IDebugCodeContext2 codeContext) { // CLRDBG TODO: This implementation should be changed to call an MI command ulong addr = ((AD7MemoryAddress)codeContext).Address; AD7StackFrame frame = ((AD7StackFrame)stackFrame); if (frame.ThreadContext.Level != 0 || frame.Thread != this || !frame.ThreadContext.pc.HasValue) { return(VSConstants.S_FALSE); } return(VSConstants.S_FALSE); }
public int CanSetNextStatement(IDebugStackFrame2 stackFrameOrigin, IDebugCodeContext2 codeContextDestination) { stackFrameOrigin.GetThread(out IDebugThread2 threadOrigin); if (threadOrigin == null) { return(VSConstants.E_FAIL); } threadOrigin.GetThreadId(out uint threadIdOrigin); if (threadIdOrigin != _id) { return(VSConstants.S_FALSE); } var contextInfosDestination = new CONTEXT_INFO[1]; int result = codeContextDestination.GetInfo( enum_CONTEXT_INFO_FIELDS.CIF_ADDRESS | enum_CONTEXT_INFO_FIELDS.CIF_FUNCTION, contextInfosDestination); if (result != VSConstants.S_OK) { return(result); } string functionNameOrigin; if (!DebugEngineUtil.GetAddressFromString(contextInfosDestination[0].bstrAddress, out ulong addressPc)) { return(VSConstants.E_FAIL); } if (stackFrameOrigin is IDebugStackFrame stackFrameOriginCast) { stackFrameOriginCast.GetNameWithSignature(out functionNameOrigin); } else { stackFrameOrigin.GetName(out functionNameOrigin); } if (addressPc != _remoteThread.GetFrameAtIndex(0).GetPC() && contextInfosDestination[0].bstrFunction != functionNameOrigin) { return(VSConstants.S_FALSE); } return(VSConstants.S_OK); }
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// public override int SetNextStatement(IDebugStackFrame2 stackFrame, IDebugCodeContext2 codeContext) { // // Sets the next statement to the given stack frame and code context. // LoggingUtils.PrintFunction(); try { CONTEXT_INFO [] contextInfo = new CONTEXT_INFO [1]; LoggingUtils.RequireOk(codeContext.GetInfo(enum_CONTEXT_INFO_FIELDS.CIF_ADDRESSABSOLUTE, contextInfo)); string location = "*" + contextInfo [0].bstrAddressAbsolute; m_debugProgram.AttachedEngine.NativeDebugger.RunInterruptOperation(delegate(CLangDebugger debugger) { // // Create a temporary breakpoint to stop -exec-jump continuing when we'd rather it didn't. // string command = string.Format("-break-insert -t \"{0}\"", location); MiResultRecord resultRecord = debugger.GdbClient.SendSyncCommand(command); MiResultRecord.RequireOk(resultRecord, command); // // Jump to the specified address location. // command = string.Format("-exec-jump --thread {0} \"{1}\"", m_threadId, location); resultRecord = debugger.GdbClient.SendSyncCommand(command); MiResultRecord.RequireOk(resultRecord, command); }); return(Constants.S_OK); } catch (Exception e) { LoggingUtils.HandleException(e); return(Constants.E_FAIL); } }
// Sets the next statement to the given stack frame and code context. int IDebugThread2.SetNextStatement(IDebugStackFrame2 stackFrame, IDebugCodeContext2 codeContext) { var frame = (AD7StackFrame)stackFrame; var context = (AD7MemoryAddress)codeContext; if (frame.StackFrame.SetLineNumber((int)context.LineNumber + 1)) { return(VSConstants.S_OK); } else if (frame.StackFrame.Thread.Process.StoppedForException) { return(E_CANNOT_SET_NEXT_STATEMENT_ON_EXCEPTION); } return(VSConstants.E_FAIL); }
// Sets the next statement to the given stack frame and code context. int IDebugThread2.SetNextStatement(IDebugStackFrame2 stackFrame, IDebugCodeContext2 codeContext) { AD7StackFrame frame = (AD7StackFrame)stackFrame; AD7MemoryAddress context = (AD7MemoryAddress)codeContext; if (TaskHelpers.RunSynchronouslyOnUIThread(ct => frame.StackFrame.SetLineNumber((int)context.LineNumber + 1, ct))) { return(VSConstants.S_OK); } else if (frame.StackFrame.Thread.Process.StoppedForException) { return(E_CANNOT_SET_NEXT_STATEMENT_ON_EXCEPTION); } return(VSConstants.E_FAIL); }
public int CanSetNextStatement(IDebugStackFrame2 pStackFrame, IDebugCodeContext2 pCodeContext) { #if HIDE_THREADS return(VSConstants.S_FALSE); #endif JavaDebugStackFrame stackFrame = pStackFrame as JavaDebugStackFrame; JavaDebugCodeContext codeContext = pCodeContext as JavaDebugCodeContext; if (stackFrame == null || codeContext == null) { return(VSConstants.E_INVALIDARG); } // TODO: implement Set Next Statement return(VSConstants.S_FALSE); }
/// <summary> /// Sets the next statement to the given stack frame and code context. /// </summary> /// <param name="stackFrame">The stack frame.</param> /// <param name="codeContext">The code context.</param> /// <returns>If successful, returns S_OK; otherwise, returns an error code.</returns> public int SetNextStatement(IDebugStackFrame2 stackFrame, IDebugCodeContext2 codeContext) { IDebugDocumentContext2 context; codeContext.GetDocumentContext(out context); string fileName; context.GetName(enum_GETNAME_TYPE.GN_FILENAME, out fileName); // fileName = engine.TranslateToBuildServerPath(fileName); var startPosition = new TEXT_POSITION[1]; var endPosition = new TEXT_POSITION[1]; context.GetStatementRange(startPosition, endPosition); EventHandler <TargetEventArgs> stepFinished = null; // var waiter = new AutoResetEvent(false); stepFinished = (sender, args) => { _lineNumberOverride = null; // if (true || args.Thread.Backtrace.GetFrame(0).SourceLocation.Line == startPosition[0].dwLine) // { _engine.Program.Session.TargetStopped -= stepFinished; // waiter.Set(); // engine.Send(new MonoBreakpointEvent(new MonoBoundBreakpointsEnumerator(new IDebugBoundBreakpoint2[0])), MonoStepCompleteEvent.Iid, engine.ThreadManager[args.Thread]); // } // else // { // engine.Session.NextInstruction(); // } }; _engine.Program.Session.TargetStopped += stepFinished; _engine.Program.Session.SetNextStatement(fileName, (int)startPosition[0].dwLine, (int)startPosition[0].dwColumn + 1); _lineNumberOverride = (int)startPosition[0].dwLine; // engine.Session.Stop(); // engine.Session.NextInstruction(); // waiter.WaitOne(); return(S_OK); }
// Determines whether the next statement can be set to the given stack frame and code context. int IDebugThread2.CanSetNextStatement(IDebugStackFrame2 stackFrame, IDebugCodeContext2 codeContext) { // CLRDBG TODO: This implementation should be changed to compare the method token ulong addr = ((AD7MemoryAddress)codeContext).Address; AD7StackFrame frame = ((AD7StackFrame)stackFrame); if (frame.ThreadContext.Level != 0 || frame.Thread != this || !frame.ThreadContext.pc.HasValue || _engine.DebuggedProcess.MICommandFactory.Mode == MIMode.Clrdbg) { return Constants.S_FALSE; } if (addr == frame.ThreadContext.pc) { return Constants.S_OK; } string toFunc = EngineUtils.GetAddressDescription(_engine.DebuggedProcess, addr); string fromFunc = EngineUtils.GetAddressDescription(_engine.DebuggedProcess, frame.ThreadContext.pc.Value); if (toFunc != fromFunc) { return Constants.S_FALSE; } return Constants.S_OK; }
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// public override int SetNextStatement (IDebugStackFrame2 stackFrame, IDebugCodeContext2 codeContext) { // // Sets the next statement to the given stack frame and code context. // LoggingUtils.PrintFunction (); try { throw new NotImplementedException (); return Constants.S_OK; } catch (Exception e) { LoggingUtils.HandleException (e); return Constants.E_FAIL; } }
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// public override int SetNextStatement(IDebugStackFrame2 stackFrame, IDebugCodeContext2 codeContext) { // // Sets the next statement to the given stack frame and code context. // LoggingUtils.PrintFunction(); try { throw new NotImplementedException(); return(Constants.S_OK); } catch (Exception e) { LoggingUtils.HandleException(e); return(Constants.E_FAIL); } }
// Determines whether the next statement can be set to the given stack frame and code context. int IDebugThread2.CanSetNextStatement(IDebugStackFrame2 stackFrame, IDebugCodeContext2 codeContext) { ulong addr = ((AD7MemoryAddress)codeContext).Address; AD7StackFrame frame = ((AD7StackFrame)stackFrame); if (frame.ThreadContext.Level != 0 || frame.Thread != this || !frame.ThreadContext.pc.HasValue) { return(Constants.S_FALSE); } if (addr == frame.ThreadContext.pc) { return(Constants.S_OK); } string toFunc = EngineUtils.GetAddressDescription(_engine.DebuggedProcess, addr); string fromFunc = EngineUtils.GetAddressDescription(_engine.DebuggedProcess, frame.ThreadContext.pc.Value); if (toFunc != fromFunc) { return(Constants.S_FALSE); } return(Constants.S_OK); }
// Determines whether the next statement can be set to the given stack frame and code context. int IDebugThread2.CanSetNextStatement(IDebugStackFrame2 stackFrame, IDebugCodeContext2 codeContext) { // CLRDBG TODO: This implementation should be changed to compare the method token ulong addr = ((AD7MemoryAddress)codeContext).Address; AD7StackFrame frame = ((AD7StackFrame)stackFrame); if (frame.ThreadContext.Level != 0 || frame.Thread != this || !frame.ThreadContext.pc.HasValue || _engine.DebuggedProcess.MICommandFactory.Mode == MIMode.Clrdbg) { return(Constants.S_FALSE); } if (addr == frame.ThreadContext.pc) { return(Constants.S_OK); } string toFunc = EngineUtils.GetAddressDescription(_engine.DebuggedProcess, addr); string fromFunc = EngineUtils.GetAddressDescription(_engine.DebuggedProcess, frame.ThreadContext.pc.Value); if (toFunc != fromFunc) { return(Constants.S_FALSE); } return(Constants.S_OK); }
public int CanSetNextStatement(IDebugStackFrame2 pStackFrame, IDebugCodeContext2 pCodeContext) { DLog.Debug(DContext.VSDebuggerComCall, "IDebugThread2.CanSetNextStatement"); var stack = (DebugStackFrame)pStackFrame; var ctx = (DebugCodeContext)pCodeContext; if (stack == null || ctx == null) { return(VSConstants.E_FAIL); } if (ctx.Location.Equals(stack.Location)) { return(VSConstants.S_OK); } if (!ctx.Location.IsSameMethod(stack.Location)) { return(HResults.E_CANNOT_SETIP_TO_DIFFERENT_FUNCTION); } // for now, only allow to set the position above the current position. if (ctx.Location.Index >= stack.Location.Index) { return(VSConstants.E_FAIL); } // don't check existence of special code, so that we can produce a warning // below. //var loc = stack.GetDocumentLocationAsync().Await(DalvikProcess.VmTimeout); //if (loc.Document == null) // return VSConstants.E_FAIL; return(VSConstants.S_OK); }
int IDebugProgram2.EnumCodePaths(string pszHint, IDebugCodeContext2 pStart, IDebugStackFrame2 pFrame, int fSource, out IEnumCodePaths2 ppEnum, out IDebugCodeContext2 ppSafety) { Debug.WriteLine("AD7ProgramNode: Entering EnumCodePaths"); throw new NotImplementedException(); }
int IDebugThread2.GetLogicalThread(IDebugStackFrame2 pStackFrame, out IDebugLogicalThread2 ppLogicalThread) { ppLogicalThread = null; return VSConstants.E_NOTIMPL; }
public int GetLogicalThread(IDebugStackFrame2 pStackFrame, out IDebugLogicalThread2 ppLogicalThread) { DLog.Debug(DContext.VSDebuggerComCall, "IDebugThread2.GetLogicalThread"); throw new NotImplementedException(); }
// Determines whether the next statement can be set to the given stack frame and code context. // We need to try the step to verify it accurately so we allow say ok here. int IDebugThread2.CanSetNextStatement(IDebugStackFrame2 stackFrame, IDebugCodeContext2 codeContext) { return(VSConstants.S_OK); }
int IDebugThread2.GetLogicalThread(IDebugStackFrame2 pStackFrame, out IDebugLogicalThread2 ppLogicalThread) { ppLogicalThread = null; return(VSConstants.E_NOTIMPL); }
/// <summary> /// Debug engines do not implement this method. /// </summary> /// <param name="pStackFrame">An IDebugStackFrame2 object that represents the stack frame.</param> /// <param name="ppLogicalThread">Returns an IDebugLogicalThread2 interface that represents the associated logical thread. A debug engine implementation should set this to a null value.</param> /// <returns>Debug engine implementations always return E_NOTIMPL.</returns> public virtual int GetLogicalThread( IDebugStackFrame2 pStackFrame, out IDebugLogicalThread2 ppLogicalThread ) { Logger.Debug( string.Empty ); ppLogicalThread = null; return VSConstants.E_NOTIMPL; }
int IDebugProgram3.EnumCodePaths(string pszHint, IDebugCodeContext2 pStart, IDebugStackFrame2 pFrame, int fSource, out IEnumCodePaths2 ppEnum, out IDebugCodeContext2 ppSafety) { throw new NotSupportedException("This method has been replaced by IDebugProgramEnhancedStep90.EnumCodePaths."); }
int IDebugThread2.GetLogicalThread(IDebugStackFrame2 pStackFrame, out IDebugLogicalThread2 ppLogicalThread) { Debug.WriteLine("AD7ProgramNode: Entering GetLogicalThread"); throw new NotImplementedException(); }
public int GetLogicalThread(IDebugStackFrame2 pStackFrame, out IDebugLogicalThread2 ppLogicalThread) { throw new NotImplementedException(); }
public int SetNextStatement(IDebugStackFrame2 pStackFrame, IDebugCodeContext2 pCodeContext) { return VSConstants.S_FALSE; }
int Microsoft.VisualStudio.Debugger.Interop.IDebugProgram2.EnumCodePaths(string pszHint, IDebugCodeContext2 pStart, IDebugStackFrame2 pFrame, int fSource, out IEnumCodePaths2 ppEnum, out IDebugCodeContext2 ppSafety) { ppEnum = null; ppSafety = null; return Utility.COM_HResults.S_OK; }
public int GetLogicalThread(IDebugStackFrame2 pStackFrame, out IDebugLogicalThread2 ppLogicalThread) { Log.Debug("Thread: GetLogicalThread"); ppLogicalThread = null; return VSConstants.E_NOTIMPL; }
public int SetNextStatement(IDebugStackFrame2 pStackFrame, IDebugCodeContext2 pCodeContext) { Log.Debug("Thread: SetNextStatement"); return VSConstants.S_OK; }
// These methods are not currently called by the Visual Studio debugger, so they don't need to be implemented int IDebugThread2.GetLogicalThread(IDebugStackFrame2 stackFrame, out IDebugLogicalThread2 logicalThread) { Debug.Fail("This function is not called by the debugger"); logicalThread = null; return Constants.E_NOTIMPL; }
int IDebugThread2.CanSetNextStatement(IDebugStackFrame2 pStackFrame, IDebugCodeContext2 pCodeContext) { Debug.WriteLine("AD7ProgramNode: Entering CanSetNextStatement"); return VSConstants.S_OK; }
// Sets the next statement to the given stack frame and code context. int IDebugThread2.SetNextStatement(IDebugStackFrame2 stackFrame, IDebugCodeContext2 codeContext) { // CLRDBG TODO: This implementation should be changed to call an MI command ulong addr = ((AD7MemoryAddress)codeContext).Address; AD7StackFrame frame = ((AD7StackFrame)stackFrame); if (frame.ThreadContext.Level != 0 || frame.Thread != this || !frame.ThreadContext.pc.HasValue || _engine.DebuggedProcess.MICommandFactory.Mode == MIMode.Clrdbg) { return Constants.S_FALSE; } string toFunc = EngineUtils.GetAddressDescription(_engine.DebuggedProcess, addr); string fromFunc = EngineUtils.GetAddressDescription(_engine.DebuggedProcess, frame.ThreadContext.pc.Value); if (toFunc != fromFunc) { return Constants.S_FALSE; } string result = frame.EvaluateExpression("$pc=" + EngineUtils.AsAddr(addr)); if (result != null) { _engine.DebuggedProcess.ThreadCache.MarkDirty(); return Constants.S_OK; } return Constants.S_FALSE; }
public int EnumCodePaths(string pszHint, IDebugCodeContext2 pStart, IDebugStackFrame2 pFrame, int fSource, out IEnumCodePaths2 ppEnum, out IDebugCodeContext2 ppSafety) { ppEnum = null; ppSafety = null; return VSConstants.E_NOTIMPL; }
int IDebugThread2.SetNextStatement(IDebugStackFrame2 pStackFrame, IDebugCodeContext2 pCodeContext) { //TODO set next line number Debug.WriteLine("AD7ProgramNode: Entering SetNextStatement"); return VSConstants.S_OK; }
int IDebugThread2.CanSetNextStatement(IDebugStackFrame2 pStackFrame, IDebugCodeContext2 pCodeContext) { return VSConstants.S_OK; }
/// <summary> /// Determines whether the current instruction pointer can be set to the given stack frame. /// </summary> /// <param name="pStackFrame">Reserved for future use; set to a null value. If this is a null value, use the current stack frame.</param> /// <param name="pCodeContext">An IDebugCodeContext2 object that describes the code location about to be executed and its context.</param> /// <returns>If successful, returns S_OK; otherwise, returns an error code.</returns> /// <remarks>If this method returns S_OK, then call the IDebugThread2::SetNextStatement method to actually set the next statement.</remarks> public virtual int CanSetNextStatement( IDebugStackFrame2 pStackFrame, IDebugCodeContext2 pCodeContext ) { Logger.Debug( string.Empty ); return VSConstants.E_NOTIMPL; }
public int EnumCodePaths(string pszHint, IDebugCodeContext2 pStart, IDebugStackFrame2 pFrame, int fSource, out IEnumCodePaths2 ppEnum, out IDebugCodeContext2 ppSafety) { throw new NotImplementedException(); }
/// <summary> /// /// </summary> public int SetNextStatement(IDebugStackFrame2 pStackFrame, IDebugCodeContext2 pCodeContext) { // TODO: move this code to DalvikThread, or to a SetNextInstructionManager DLog.Debug(DContext.VSDebuggerComCall, "IDebugThread2.SetNextStatement"); var stack = (DebugStackFrame)pStackFrame; var ctx = (DebugCodeContext)pCodeContext; // nothing to do. if (ctx.Location.Equals(stack.Location)) return VSConstants.S_OK; if (!ctx.Location.IsSameMethod(stack.Location)) return HResults.E_CANNOT_SETIP_TO_DIFFERENT_FUNCTION; var loc = stack.GetDocumentLocationAsync().Await(DalvikProcess.VmTimeout); if (loc.MethodEntry == null) { DLog.Info(DContext.VSStatusBar, "Can not set next instruction: Debug info not available."); return HResults.E_CANNOT_SET_NEXT_STATEMENT_GENERAL; } var nextInstrVar = loc.MethodEntry.Variables.FirstOrDefault(v => v.Name == DebuggerConstants.SetNextInstructionVariableName); if (nextInstrVar == null) { DLog.Info(DContext.VSStatusBar, "Can not set next instruction: missing compiler setting or method optimized."); return HResults.E_CANNOT_SET_NEXT_STATEMENT_GENERAL; } // make sure there are no branch instructions // between the current instruction and our branch instruction. // note that for convinence, we *do* allow assignments to // fields of objects, even though these are visible to the // program. var disassembly = Program.DisassemblyProvider.GetFromLocation(loc); if (disassembly == null) return HResults.E_CANNOT_SET_NEXT_STATEMENT_GENERAL; var body = disassembly.Method.Body; int idx = body.Instructions.FindIndex(i => (ulong)i.Offset == loc.Location.Index); if(idx == -1) return HResults.E_CANNOT_SET_NEXT_STATEMENT_GENERAL; bool foundSetNextInstruction = false; for (;idx < body.Instructions.Count; ++idx) { var ins = body.Instructions[idx]; foundSetNextInstruction = ins.OpCode == OpCodes.If_nez && ins.Registers.Count == 1 && ins.Registers[0].Index == nextInstrVar.Register; if (foundSetNextInstruction) break; if (ins.OpCode.IsJump()) break; } if (!foundSetNextInstruction) { DLog.Info(DContext.VSStatusBar, "Can not set next instruction from current position. Try again at a later position if any."); return HResults.E_CANNOT_SET_NEXT_STATEMENT_GENERAL; } DLog.Info(DContext.VSStatusBar, "Setting next instruction to beginning of block."); // find target instruction. var targetIns = (Instruction)body.Instructions[idx].Operand; idx = body.Instructions.FindIndex(p => p.Offset == targetIns.Offset); idx = FindNextLocationWithSource(disassembly, idx) ?? idx; targetIns = body.Instructions[idx]; var targetLoc = loc.Location.GetAtIndex(targetIns.Offset); // set a temporary breakpoint. The reset logic could get into a "DalvikTemporaryBreakpoint" class. var bp = new DalvikAwaitableBreakpoint(targetLoc); var waitBp = bp.WaitUntilHit(); var waitBound = Debugger.Process.BreakpointManager.SetBreakpoint(bp); try { if (!waitBound.Await(DalvikProcess.VmTimeout)) return HResults.E_CANNOT_SET_NEXT_STATEMENT_GENERAL; // set the special variable. var newSlotVal = new SlotValue(nextInstrVar.Register, Jdwp.Tag.Int, 1); Debugger.StackFrame.SetValuesAsync(stack.Thread.Id, stack.Id, newSlotVal) .Await(DalvikProcess.VmTimeout); // resume the process. Debugger.Process.ResumeAsync(); // wait for breakpoint to be hit. try { waitBp.Await(1000); } catch (Exception) { // ups. something went wrong. suspend again. if (!Debugger.Process.IsSuspended) Debugger.Process.SuspendAsync(); return VSConstants.E_FAIL; } return VSConstants.S_OK; } finally { // clear the breakpoint again. Debugger.Process.BreakpointManager.ResetAsync(bp) .Await(DalvikProcess.VmTimeout); // reset the special variable, in case this was not performed automatically. // (should not happen, but maybe the set value code got optimized away per // accident) var newSlotVal = new SlotValue(nextInstrVar.Register, Jdwp.Tag.Int, 0); Debugger.StackFrame.SetValuesAsync(stack.Thread.Id, stack.Id, newSlotVal) .Await(DalvikProcess.VmTimeout); } }
int IDebugThread2.SetNextStatement(IDebugStackFrame2 pStackFrame, IDebugCodeContext2 pCodeContext) { return VSConstants.E_NOTIMPL; }
// Determines whether the next statement can be set to the given stack frame and code context. // The sample debug engine does not support set next statement, so S_FALSE is returned. int IDebugThread2.CanSetNextStatement(IDebugStackFrame2 stackFrame, IDebugCodeContext2 codeContext) { return Constants.S_FALSE; }
int IDebugThread2.CanSetNextStatement(IDebugStackFrame2 pStackFrame, IDebugCodeContext2 pCodeContext) { ThrowIfDisposed(); return VSConstants.S_FALSE; }
// Determines whether the next statement can be set to the given stack frame and code context. // NOTE: VS2013 and earlier do not use the result to disable the "set next statement" command int IDebugThread2.CanSetNextStatement(IDebugStackFrame2 stackFrame, IDebugCodeContext2 codeContext) { throw new NotSupportedException("Set Next Statement is not supported by Node.js."); }
// Sets the next statement to the given stack frame and code context. int IDebugThread2.SetNextStatement(IDebugStackFrame2 stackFrame, IDebugCodeContext2 codeContext) { var frame = (AD7StackFrame)stackFrame; var context = (AD7MemoryAddress)codeContext; if (frame.StackFrame.SetLineNumber((int)context.LineNumber + 1)) { return VSConstants.S_OK; } else if (frame.StackFrame.Thread.Process.StoppedForException) { return E_CANNOT_SET_NEXT_STATEMENT_ON_EXCEPTION; } return VSConstants.E_FAIL; }
// EnumCodePaths is used for the step-into specific feature -- right click on the current statment and decide which // function to step into. This is not something that the SampleEngine supports. public int EnumCodePaths(string hint, IDebugCodeContext2 start, IDebugStackFrame2 frame, int fSource, out IEnumCodePaths2 pathEnum, out IDebugCodeContext2 safetyContext) { pathEnum = null; safetyContext = null; return Constants.E_NOTIMPL; }
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// public int EnumCodePaths (string pszHint, IDebugCodeContext2 pStart, IDebugStackFrame2 pFrame, int fSource, out IEnumCodePaths2 ppEnum, out IDebugCodeContext2 ppSafety) { // // Enumerates the code paths of this program. // LoggingUtils.PrintFunction (); try { // // Get the entire call-stack for the current thread, and enumerate. // CLangDebuggeeStackFrame stackFrame = pFrame as CLangDebuggeeStackFrame; IDebugThread2 thread; LoggingUtils.RequireOk (stackFrame.GetThread (out thread)); CLangDebuggeeThread stackFrameThread = thread as CLangDebuggeeThread; List<DebuggeeStackFrame> threadCallStack = stackFrameThread.StackTrace (uint.MaxValue); List <CODE_PATH> threadCodePaths = new List <CODE_PATH> (); for (int i = 0; i < threadCallStack.Count; ++i) { string frameName; IDebugCodeContext2 codeContext; DebuggeeStackFrame frame = threadCallStack [i] as DebuggeeStackFrame; LoggingUtils.RequireOk (frame.GetName (out frameName)); LoggingUtils.RequireOk (frame.GetCodeContext (out codeContext)); if (codeContext != null) { CODE_PATH codePath = new CODE_PATH (); codePath.bstrName = frameName; codePath.pCode = codeContext; threadCodePaths.Add (codePath); } } ppEnum = new DebuggeeProgram.EnumeratorCodePaths (threadCodePaths); ppSafety = null; return Constants.S_OK; } catch (Exception e) { LoggingUtils.HandleException (e); ppEnum = null; ppSafety = null; return Constants.E_FAIL; } }