Невозможно функционировать с использованием Mdbg из-за исключения «код оптимизирован» - PullRequest
4 голосов
/ 20 марта 2012

Мы используем 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, но все они, похоже, имеют UserState, помеченный как USER_UNSAFE_POINT.

Существует очень скудная документация по этому вопросу, и мы стараемся изо всех сил пытаться выяснить, есть ли способ получить нить в точке, безопасной для GC, чтобы мы могли выполнить func-eval. Мы бы рассмотрели все, что позволяет нам детерминистически разбить процесс на поток, с которым он выполняет 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 команда, вы можете помочь?

Лучший, Mike

1 Ответ

2 голосов
/ 24 мая 2012

Это как-то связано с оптимизацией JIT?В моей программе я отключаю оптимизацию JIT (по техническим причинам, я думаю, что вы можете сделать это только с CreateProcess () и без использования Attach ()).

 proc = m_Debugger.CreateProcess(ProcessName, ProcessArgs, DebugModeFlag.Default, DebugEngineUtils.GetAssemblyRuntimeVersion(ProcessName,DefaultNetVersion));
 if (proc!=null) proc.CorProcess.OnCreateProcess += new Microsoft.Samples.Debugging.CorDebug.CorProcessEventHandler(CorProcess_OnCreateProcess);
 if (proc!=null) proc.CorProcess.OnModuleLoad += new Microsoft.Samples.Debugging.CorDebug.CorModuleEventHandler(CorProcess_OnModuleLoad);
 void CorProcess_OnModuleLoad(object sender, Microsoft.Samples.Debugging.CorDebug.CorModuleEventArgs e)
        {
            e.Module.JITCompilerFlags = Microsoft.Samples.Debugging.CorDebug.CorDebugJITCompilerFlags.CORDEBUG_JIT_DISABLE_OPTIMIZATION;
        }

 void CorProcess_OnCreateProcess(object sender, Microsoft.Samples.Debugging.CorDebug.CorProcessEventArgs e)
        {
            //try to disable optimization
            ((Microsoft.Samples.Debugging.CorDebug.CorProcess)sender).DesiredNGENCompilerFlags = Microsoft.Samples.Debugging.CorDebug.CorDebugJITCompilerFlags.CORDEBUG_JIT_DISABLE_OPTIMIZATION;
        }
...