We use MdbgCore.dll to evaluate the property with the parameter in the freeze frame of the stream.
To do this, we run func-eval.
Unfortunately, all our attempts to execute func-eval fail with CORDBG_E_ILLEGAL_IN_OPTIMIZED_CODE, which is apparently due to the fact that the stream is used to prevent func-eval from being in the GC security point.
This is described here: http://blogs.msdn.com/b/jmstall/archive/2005/11/15/funceval-rules.aspx .
We tried to check all the threads in the process to find the thread that is in the GC security point, but they all seem to have a UserState marked USER_UNSAFE_POINT.
There is very little documentation on this, and we are pulling our hair trying to figure out if there is a way to get the thread at the GC security point so that we can execute func-eval. We will look at everything that allows us to break into a process deterministically using a thread to perform func-eval with.
Disclaimer: we are trying to evaluate a method for a class that is in an optimized assembly, so we are not sure if this could also cause a problem.
The following is sample code:
if (argument.TypeName.EndsWith( "WorkerRequest", StringComparison.OrdinalIgnoreCase) && !argument.IsNull) { try { // Invoke the "GetUriPath()" function to obtain the URI string functionName = "System.Web.HttpWorkerRequest.GetUriPath"; MDbgFunction func = debugger.Processes.Active.ResolveFunctionNameFromScope( functionName, thread.CorThread.AppDomain ); if (null == func) { throw new InvalidOperationException( String.Format("Could not resolve {0}", functionName)); } // Setup the eval CorEval eval = threadForFuncEvals.CorThread.CreateEval(); // Setup the function parameters List<CorValue> values = new List<CorValue>(); // Add the worker request "this" pointer values.Add( argument.CorValue ); // resume the thread being used to do the func-eval threadForFuncEvals.CorThread.DebugState = CorDebugThreadState.THREAD_RUN; // Queue the function for execution // EXCEPTION THROWN BELOW // EXCEPTION THROWN BELOW // EXCEPTION THROWN BELOW eval.CallFunction(func.CorFunction, values.ToArray()); // BUGBUG: Should we pause all other threads to prevent them from moving? // Continue the process to execute the function if (!proc.Go().WaitOne(settings.BreakTimeout)) { throw new InvalidOperationException("Timeout while evaluating function"); } // get the returned string var result = eval.Result; if (result != null) { MDbgValue mv = new MDbgValue(proc, result); string returnedValue = mv.GetStringValue(false); threadInfo.Url = returnedValue; } } catch (Exception e) { // BUGBUG: Ignoring exception } finally { // suspend the thread again if (threadForFuncEvals != null) { threadForFuncEvals.CorThread.DebugState = CorDebugThreadState.THREAD_SUSPEND; } }
}
Microsoft / Mdbg team, can you help?
Best, Mike
source share