MdbgCore.dll を使用して、スレッド コールスタックのパラメーターからプロパティを評価しています。
これを行うために、func-eval を実行しています。
残念ながら、func-eval を実行しようとする試みはすべて CORDBG_E_ILLEGAL_IN_OPTIMIZED_CODE で失敗しています。これは、func-eval に使用されているスレッドが GC セーフ ポイントにないためと思われます。
これは、http: //blogs.msdn.com/b/jmstall/archive/2005/11/15/funceval-rules.aspxに記載されています。
プロセス内のすべてのスレッドをスキャンして、GC セーフ ポイントにあるスレッドを見つけようとしましたが、それらはすべて、USER_UNSAFE_POINT でマークされた UserState を持っているようです。
この件に関するドキュメントは非常に乏しく、関数評価を実行できるように GC セーフ ポイントでスレッドを取得する方法があるかどうかを突き止めようとしているところです。func-eval を実行するスレッドを使用して決定論的にプロセスに割り込むことができるものは何でも検討します。
免責事項: 最適化されたアセンブリに存在するクラスのメソッドを評価しようとしているため、これが問題を引き起こしている可能性があるかどうかはわかりません。
サンプル コードは次のとおりです。
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 チーム、お手伝いできますか?
ベスト、マイク