public CorDebugFunctionBreakpoint(CorDebugFunction function, uint ilCLR) : base(function.AppDomain) { m_function = function; m_il = new Pdbx.IL(); m_il.CLR = ilCLR; m_il.nanoCLR = function.GetILnanoCLRFromILCLR(ilCLR); m_breakpointDef.m_IP = m_il.nanoCLR; m_breakpointDef.m_md = m_function.MethodDef_Index; this.Active = true; }
public static CorDebugFunction CorDebugFunctionFromMethodIndex(uint methodIndex, CorDebugAppDomain appDomain) { CorDebugFunction function = null; CorDebugAssembly assembly = appDomain.AssemblyFromIdx(nanoCLR_TypeSystem.IdxAssemblyFromIndex(methodIndex)); if (assembly != null) { uint tk = nanoCLR_TypeSystem.nanoCLRTokenFromMethodIndex(methodIndex); function = assembly.GetFunctionFromTokennanoCLR(tk); } return(function); }
private CorDebugFunction GetFunctionFromToken(uint tk, Hashtable ht) { CorDebugFunction function = null; Pdbx.Method method = ht[tk] as Pdbx.Method; if (method != null) { CorDebugClass c = new CorDebugClass(this, method.Class); function = new CorDebugFunction(c, method); } Debug.Assert(function != null); return(function); }
int ICorDebugEval.NewObject(ICorDebugFunction pConstructor, uint nArgs, ICorDebugValue[] ppArgs) { Debug.Assert(nArgs == ppArgs.Length); CorDebugFunction f = (CorDebugFunction)pConstructor; CorDebugClass c = f.Class; this.Process.SetCurrentAppDomain(this.AppDomain); Engine.AllocateObjectAsync(GetScratchPadLocation(), c.TypeDef_Index).Wait(); ICorDebugValue[] args = new ICorDebugValue[nArgs + 1]; args[0] = GetResultValue(); ppArgs.CopyTo(args, 1); ((ICorDebugEval)this).CallFunction(pConstructor, (uint)args.Length, args); return(COM_HResults.S_OK); }
public CorDebugCode(CorDebugFunction function) { m_function = function; }
int ICorDebugEval.CallFunction(ICorDebugFunction pFunction, uint nArgs, ICorDebugValue[] ppArgs) { try { //CreateThread will cause a thread create event to occur. This is a virtual thread, so //we need to suspend processing of nanoCLR commands until we have created the thread ourselves //and the processing of a new virtual thread will be ignored. Process.SuspendCommands(true); //need to flush the breakpoints in case new breakpoints were waiting until process was resumed. Process.UpdateBreakpoints(); Debug.Assert(nArgs == ppArgs.Length); Debug.Assert(Process.IsExecutionPaused); CorDebugFunction function = (CorDebugFunction)pFunction; uint md = function.MethodDef_Index; if (function.IsVirtual && function.IsInstance) { Debug.Assert(nArgs > 0); var getMethod = this.Engine.GetVirtualMethodAsync(function.MethodDef_Index, ((CorDebugValue)ppArgs[0]).RuntimeValue); getMethod.Wait(); md = getMethod.Result; } this.Process.SetCurrentAppDomain(this.AppDomain); //Send the selected thread ID to the device so calls that use Thread.CurrentThread work as the user expects. var createThread = this.Engine.CreateThreadAsync(md, GetScratchPadLocation(), m_threadReal.ID); createThread.Wait(); uint pid = createThread.Result; if (pid == uint.MaxValue) { throw new ArgumentException("nanoCLR cannot call this function. Possible reasons include: ByRef arguments not supported"); } //If anything below fails, we need to clean up by killing the thread if (nArgs > 0) { RuntimeValue[] args = new RuntimeValue[0]; using (CancellationTokenSource cts = new CancellationTokenSource()) { var getStack = this.Engine.GetStackFrameValueAllAsync(pid, 0, function.NumArg, Engine.StackValueKind.Argument, cts.Token); getStack.Wait(); args = getStack.Result; } for (int iArg = 0; iArg < nArgs; iArg++) { CorDebugValue valSrc = (CorDebugValue)ppArgs[iArg]; CorDebugValue valDst = CorDebugValue.CreateValue(args[iArg], m_appDomain); var assignTask = valDst.RuntimeValue.AssignAsync(valSrc.RuntimeValue); assignTask.Wait(); if (assignTask.Result == null) { throw new ArgumentException("nanoCLR cannot set argument " + iArg); } } } m_threadVirtual = new CorDebugThread(this.Process, pid, this); m_threadReal.AttachVirtualThread(m_threadVirtual); Debug.Assert(!m_fActive); m_fActive = true; //It is possible that a hard breakpoint is hit, the first line of the function //to evaluate. If that is the case, than breakpoints need to be drained so the //breakpoint event is fired, to avoid a race condition, where cpde resumes //execution to start the function eval before it gets the breakpoint event //This is primarily due to the difference in behavior of the nanoCLR and the desktop. //In the desktop, the hard breakpoint will not get hit until execution is resumed. //The nanoCLR can hit the breakpoint during the Thread_Create call. Process.DrainBreakpoints(); } finally { Process.SuspendCommands(false); } return(COM_HResults.S_OK); }