Пример #1
0
        public void Attach(MDbgProcess process)
        {
            process.PostDebugEvent +=
                (sender, e) =>
                {
                    log.Log(e.CallbackType.ToString());

                    if (e.CallbackType == ManagedCallbackType.OnException2)
                    {
                        var ce = (CorException2EventArgs)e.CallbackArgs;

                        if (ce.EventType == CorDebugExceptionCallbackType.DEBUG_EXCEPTION_FIRST_CHANCE)
                        {
                            var thread = process.Threads.Lookup(ce.Thread);

                            foreach (var frame in thread.Frames)
                            {
                                if (!frame.IsManaged || frame.Function.FullName.StartsWith("System."))
                                    break;

                                log.Log("{0}({1})", frame.Function.FullName, string.Join(", ", frame.Function.GetArguments(frame).Select(
                                    arg => string.Format("{0} = {1}", arg.Name, arg.GetStringValue(false)))));
                            }
                        }
                    }
                };
        }
Пример #2
0
 /// <summary>
 /// Creates a new instance of the MDbgValue Object.
 /// This constructor is public so that applications can use this class to print values (CorValue).
 /// CorValue's can be returned for example by funceval(CorEval.Result).
 /// </summary>
 /// <param name="process">The Process that will own the Value.</param>
 /// <param name="value">The CorValue that this MDbgValue will start with.</param>
 public MDbgValue(MDbgProcess process, CorValue value)
 {
     // value can be null, but we should always know what process we are
     // looking at.
     Debug.Assert(process != null);
     Initialize(process, null, value);
 }
Пример #3
0
 internal MDbgAppDomain(MDbgProcess process, CorAppDomain appDomain, int number)
 {
     Debug.Assert(process != null);
     Debug.Assert(appDomain != null);
     m_process = process;
     m_appDomain = appDomain;
     m_number = number;
 }
Пример #4
0
 /// <summary>
 /// Creates an empty stepper.
 /// </summary>
 /// <param name="process">non-null process that this is stepping</param>
 public StepperDescriptor(MDbgProcess process)
 {
     if (process == null)
     {
         throw new ArgumentNullException("process");
     }
     m_process = process;
 }
Пример #5
0
 internal MDbgModule(MDbgProcess process, CorModule managedModule, int number)
 {
     Debug.Assert(process != null && managedModule != null);
     m_process = process;
     m_module = managedModule;
     m_functions = new MDbgFunctionMgr(this);
     m_number = number;
 }
Пример #6
0
 // Helper to append generic args from tyenum in pretty format.
 // This will add a string like '<int, Foo<string>>'
 internal static void AddGenericArgs(StringBuilder sb, MDbgProcess proc, IEnumerable tyenum)
 {
     int i = 0;
     foreach(CorType t1 in tyenum)
     {
         sb.Append((i == 0) ? '<' : ',');
         InternalUtil.PrintCorType(sb, proc, t1);
         i++;
     }
     if (i > 0)
     {
         sb.Append('>');
     }
 }
Пример #7
0
        /// <summary>
        /// Gets the current output of the template function.
        /// </summary>
        /// <remarks>
        /// Assumes that debuggedProc can be examined safely, and that the current output is stored in a static
        /// variable called __CurrentOutput in the class containing the template function.
        /// Alternatively, if the </remarks>
        /// <param name="debuggedProc">The Process that is being debugged.</param>
        /// <returns>The current output of the template function.</returns>
        private string GetCurrentOutput(MDbgProcess debuggedProc)
        {
            MDbgValue val = null;
            int lineNumber = (debuggedProc.Threads.HaveActive && debuggedProc.Threads.Active.HaveCurrentFrame &&
                              debuggedProc.Threads.Active.CurrentFrame.SourcePosition != null) ?
                                 debuggedProc.Threads.Active.CurrentFrame.SourcePosition.Line : 0;
            if (lineNumber == LAST_LINE_IN_MAIN)
            {
                val = debuggedProc.ResolveVariable("obj", debuggedProc.Threads.Active.CurrentFrame);
            }
            else if (debuggedProc.Threads.Active.CurrentFrame.SourcePosition != null)
            {
                if (debuggedProc.Threads.Active.CurrentFrame.SourcePosition.Path.Contains(Path.Combine("ArchAngel.Debugger.DebugProcess", "Commands.cs")))
                {
                    return "";
                }

                val = debuggedProc.ResolveVariable("instance", debuggedProc.Threads.Active.CurrentFrame)
                      ??
                      debuggedProc.ResolveVariable("this", debuggedProc.Threads.Active.CurrentFrame);

                if (val == null)
                    return "Could not get value of current output";
                string funcName = TestNamespace + "." + TestClassname + ".GetCurrentStringBuilder";
                val = ResolveFunction(debuggedProc, val, funcName);
                val = ResolveFunction(debuggedProc, val, "System.Text.StringBuilder.ToString");
            }

            if (val == null)
                return "Could not get value of current output";

            string currentOutput = val.GetStringValue(1);
            currentOutput = currentOutput.Remove(0, 1);
            currentOutput = currentOutput.Remove(currentOutput.Length - 1, 1);
            return currentOutput;
        }
Пример #8
0
        /// <summary>Starts the debugging process. This is synchronised on the Debugger
        /// object it is called on.</summary>
        /// <remarks>
        /// Assumes that the DebuggerSync object has been set up correctly and that something
        /// is listening to the BackgroundWorker events. It will lock indefinitely if something
        /// doesn't tell it to continue by calling set on the DebuggerSync.ContinueDebugExecution
        /// object.
        /// </remarks>
        public void Run()
        {
            lock (this)
            {
                int pid = DebugProcess.GetDebugProcessId();

                CommandReceiver obj = DebugProcess.GetCommandReceiver();

                // Get Assembly Search paths. These are used for finding
                // any assemblies that are used by the template.
                List<string> assemblySearchPaths = new List<string>();

                foreach (string assemblyLocation in AssemblyLocations)
                {
                    string dir = Path.GetDirectoryName(assemblyLocation).ToLower();

                    if (assemblySearchPaths.BinarySearch(dir) < 0)
                    {
                        assemblySearchPaths.Add(dir);
                        assemblySearchPaths.Sort();
                    }
                }
                obj.ExecuteCommand(new RunFunctionCommand(CompiledAssemblyLocation, TestNamespace, TestClassname,
                                                          TestFunctionName, ArgumentList, UserOptions, AaprojXml, IsFunctionStatic));

                // This is a race condition, but it is required because we can't create the breakpoints
                // before attaching to the process.
                MDbgEngine debugger = new MDbgEngine();
                proc = debugger.Attach(pid);

                _CurrentlyRunningBreakpoints.Clear();

                foreach (int bp in _Breakpoints)
                {
                    _CurrentlyRunningBreakpoints.Add(bp,
                                                     proc.Breakpoints.CreateBreakpoint(CodeFilename, bp));
                }

                proc.Breakpoints.CreateBreakpoint("Commands.cs", LAST_LINE_IN_MAIN);
                proc.Breakpoints.CreateBreakpoint(CodeFilename, LAST_LINE_IN_FUNCTION);

                _CurrentlyRunningProcess = proc;

                while (proc.IsAlive)
                {
                    // Let the debuggee run and wait until it hits a debug event.
                    switch (_DebuggerSync.NextDebugAction)
                    {
                        case DebugActionType.Continue:
                            proc.Go().WaitOne();
                            break;
                        case DebugActionType.StepInto:
                            proc.StepInto(false).WaitOne();
                            break;
                        case DebugActionType.StepOver:
                            proc.StepOver(false).WaitOne();
                            break;
                        case DebugActionType.StepOut:
                            proc.StepOut().WaitOne();
                            break;
                        case DebugActionType.Stop:
                            _CurrentlyRunningProcess = null;
                            proc.Breakpoints.DeleteAll();
                            proc.Detach();
                            break;
                    }

                    if (!proc.IsAlive)
                    {
                        proc = null;
                        break;
                    }

                    // Get a DebugInformation object filled with the info we need.
                    DebugInformation di = GetDebugInformation(proc);

                    // If this is the last line, we need to stop debugging.
                    if (di.StartLineNumber == LAST_LINE_IN_MAIN)
                    {
                        di.Stopped = false;
                        di.StopReason = StopReason.DebuggerFinished;
                        di.StopReasonText = "Debugger Finished";
                        _DebuggerSync.DebugBackgroundWorker.ReportProgress(99, di);
                        _CurrentlyRunningProcess = null;
                        proc.Breakpoints.DeleteAll();
                        proc.Detach();

                        break;
                    }
                    // Any other lines in the main function should just be skipped.
                    if (di.SourceFile == "Commands.cs")
                    {
                        _DebuggerSync.NextDebugAction = DebugActionType.Continue;
                        continue;
                    }

                    if (di.StartLineNumber == LAST_LINE_IN_FUNCTION)
                    {
                        _DebuggerSync.NextDebugAction = DebugActionType.StepOut;
                        continue;
                    }
                    // If an exception was thrown, report it then stop debugging.
                    if (di.ExceptionThrown)
                    {
                        di.Stopped = false;
                        _DebuggerSync.DebugBackgroundWorker.ReportProgress(99, di);
                        _CurrentlyRunningProcess = null;
                        proc.Breakpoints.DeleteAll();
                        proc.Detach();

                        break;
                    }

                    di.Stopped = true;
                    _DebuggerSync.DebugBackgroundWorker.ReportProgress(50, di);
                    _DebuggerSync.ContinueDebugExecution.WaitOne();
                    continue;
                }
            }
            _CurrentlyRunningProcess = null;
        }
Пример #9
0
        /// <summary>
        /// Creates a default 'source level step' on process with current active frame and active thread. 
        /// </summary>
        /// <param name="process">non-null process </param>
        /// <param name="type">type of step (in, out, over)</param>
        /// <param name="singleStepInstructions">false to step source level, true to step single instructions</param>
        /// <returns></returns>
        public static StepperDescriptor CreateSourceLevelStep(MDbgProcess process, StepperType type, bool singleStepInstructions)
        {
            StepperDescriptor s = new StepperDescriptor(process);
            s.StepperType = type;

            //
            // Handle Step-out case.
            //
            if (type == StepperType.Out)
            {
                 return s;
            }

            //
            // Handle step-over / step-in case
            //
            bool stepInto = (type == StepperType.In);

            // Cache current
            s.Thread = process.Threads.Active.CorThread;
            s.Frame = s.Thread.ActiveFrame;

            CorDebugMappingResult mappingResult;
            uint ip;

            if (!singleStepInstructions)
            {
                // For source-level stepping, skip some interceptors. These are random, and cause
                // random differences in stepping across different runtimes; and user generally don't care
                // about interceptors.
                // It's actually a debatable policy about which interceptors to skip and stop on.
                s.InterceptMask = CorDebugIntercept.INTERCEPT_ALL &
                    ~(CorDebugIntercept.INTERCEPT_SECURITY | CorDebugIntercept.INTERCEPT_CLASS_INIT);
            }

            s.Frame.GetIP(out ip, out mappingResult);
            if (singleStepInstructions ||
                (mappingResult != CorDebugMappingResult.MAPPING_EXACT &&
                 mappingResult != CorDebugMappingResult.MAPPING_APPROXIMATE))
            {
                // Leave step ranges null
            }
            else
            {
                // Getting the step ranges is what really makes this a source-level step.
                MDbgFunction f = process.Modules.LookupFunction(s.Frame.Function);
                COR_DEBUG_STEP_RANGE[] sr = f.GetStepRangesFromIP((int)ip);
                if (sr != null)
                {
                    s.SetStepRanges(sr, true);
                }
                else
                {
                    // Leave step ranges null.
                }
            }

            return s;
        }
Пример #10
0
 /// <summary>
 /// Creates a source level stepper
 /// </summary>
 /// <param name="process"></param>
 /// <param name="type"></param>
 /// <returns></returns>
 public static StepperDescriptor CreateSourceLevelStep(MDbgProcess process, StepperType type)
 {
     bool stepNativeCode = false;
     return CreateSourceLevelStep(process, type, stepNativeCode);
 }
Пример #11
0
        /// <summary>
        /// Skip past fake attach events.
        /// </summary>
        /// <param name="debugger"></param>
        /// <param name="proc"></param>
        public static void DrainAttach(MDbgEngine debugger, MDbgProcess proc)
        {
            bool fOldStatus = debugger.Options.StopOnNewThread;
            debugger.Options.StopOnNewThread = false; // skip while waiting for AttachComplete

            proc.Go().WaitOne();
            Debug.Assert(proc.StopReason is AttachCompleteStopReason);

            debugger.Options.StopOnNewThread = true; // needed for attach= true; // needed for attach

            // Drain the rest of the thread create events.
            while (proc.CorProcess.HasQueuedCallbacks(null))
            {
                proc.Go().WaitOne();
                Debug.Assert(proc.StopReason is ThreadCreatedStopReason);
            }

            debugger.Options.StopOnNewThread = fOldStatus;
        }
Пример #12
0
        /// <summary>
        /// Gets the output of a function using MDbg.
        /// </summary>
        /// <example>
        /// 	<code lang="CS" title="Getting the Message from an Exception" description="An example showing how you would get the value of the Message property of an Exception. The variable ex is a MDbgValue object that represents the exception you are examining.">
        /// MDbgValue returnValue = ResolveFunction(debuggedProc, ex, "System.Exception.get_Message");
        /// string message = returnValue.GetStringValue(true);
        ///     </code>
        /// </example>
        /// <param name="debuggedProc">The process we are debugging.</param>
        /// <param name="ex">The MDbgValue object to execute the function on.</param>
        /// <param name="function">The full name of the function in MDbg syntax.</param>
        /// <returns>The MDbgValue that contains the return value of the function. If the function
        /// could not be evaluated, it returns null.</returns>
        private MDbgValue ResolveFunction(MDbgProcess debuggedProc, MDbgValue ex, string function)
        {
            CorAppDomain appDomain = debuggedProc.Threads.Active.CorThread.AppDomain;
            MDbgFunction func = debuggedProc.ResolveFunctionNameFromScope(function, appDomain);
            if (func == null)
                throw new Exception("A required function is missing. Are you running a template compiled with an different version of ArchAngel?");
            CorEval eval = debuggedProc.Threads.Active.CorThread.CreateEval();
            eval.CallFunction(func.CorFunction, new[] { ex.CorValue });

            debuggedProc.Go().WaitOne();

            if (!(debuggedProc.StopReason is EvalCompleteStopReason))
            {
                return null;
            }

            eval = ((EvalCompleteStopReason)debuggedProc.StopReason).Eval;
            if (eval == null)
            {
                return null;
            }

            CorValue cv = eval.Result;
            if (cv != null)
            {
                MDbgValue mv = new MDbgValue(debuggedProc, cv);
                return mv;
            }

            return null;
        }
Пример #13
0
 private ProcessSample GetCallstacks(MDbgProcess proc, bool onlyMainThread , bool withArgs = false, bool originFirst = false)
 {
     if (onlyMainThread)
         return DebuggerUtils.GetCallstacks(proc, m_intMainThreadId, withArgs, originFirst);
     else
         return DebuggerUtils.GetCallstacks(proc, -1, withArgs, originFirst);
 }
Пример #14
0
 private void Initialize(MDbgProcess process, string name, CorValue value)
 {
     m_process = process;
     m_name = name;
     m_corValue = value;
 }
Пример #15
0
        public void StartListening()
        {
            if (m_processId == -1)
                return;

            if (m_blnIsListening)
                return;

            m_debugger = new MDbgEngine();
            m_process = null;
            m_blnIsListening = true;
            Task t = Task.Factory.StartNew(() =>
            {
                try
                {

                    string timeString1 = DebuggerUtils.GetTimeString(true);
                    m_process = DebuggerUtils.AttachToProcess(m_processId, m_debugger);
                    LastLogFileName = Path.Combine(LogFileDirectory, m_process.Name + "(" + m_processId + ") T" + timeString1 + ".log");
                }
                catch (Exception ex)
                {
                    DebuggerUtils.HandleException(ex);
                }

                try
                {
                    //m_process.Go();
                    //m_process.Go().WaitOne();
                    //m_process.Detach();
                    //m_debugger.Options.StopOnLogMessage = true;
                    m_debugger.Options.StopOnException = true;
                    //m_debugger.Options.StopOnExceptionEnhanced = false;
                    m_debugger.Options.StopOnUnhandledException = true;
                    m_blnIsListening = true;
                    while (m_process.IsAlive)
                    {

                        //if (e.CallbackType == ManagedCallbackType.OnException2)
                        //{
                        //    var ce = (CorException2EventArgs)e.CallbackArgs;

                        //    if (ce.EventType == CorDebugExceptionCallbackType.DEBUG_EXCEPTION_FIRST_CHANCE)
                        //    {
                        //        var thread = process.Threads.Lookup(ce.Thread);

                        //        foreach (var frame in thread.Frames)
                        //        {
                        //            if (!frame.IsManaged || frame.Function.FullName.StartsWith("System."))
                        //                break;

                        //            log.Log("{0}({1})", frame.Function.FullName, string.Join(", ", frame.Function.GetArguments(frame).Select(
                        //                arg => string.Format("{0} = {1}", arg.Name, arg.GetStringValue(false)))));
                        //        }
                        //    }
                        //}

                        try
                        {
                            m_process.Go().WaitOne();
                            //if (e.CallbackType == ManagedCallbackType.OnBreakpoint)
                            //m_process.Go().WaitOne();
                            object o = m_process.StopReason;
                            ExceptionThrownStopReason stopReason = o as ExceptionThrownStopReason;
                            if (stopReason != null)
                            {
                                if (stopReason.EventType == Microsoft.Samples.Debugging.CorDebug.NativeApi.CorDebugExceptionCallbackType.DEBUG_EXCEPTION_UNHANDLED)
                                {
                                    string timeString = DebuggerUtils.GetTimeString(true);

                                    if (WriteDumpOnUncaughtExceptions)
                                    {
                                        m_strLastDumpFileName = Path.Combine(m_strDumpFileDirectory, m_process.Name + timeString + ".dmp");
                                        DumpWriter.WriteDump(m_process.CorProcess.Id, m_strLastDumpFileName, DumpOptions.WithFullMemory);
                                    }
                                }

                                if (LogExceptions)
                                {
                                    //File.AppendAllText(LastLogFileName, DateTime.Now.ToString("dd\\MM\\yyyy mm:hh:ss.fff]") + DebuggerUtils.GetExceptionDescFromProcess(m_process) + "\n");
                                    try
                                    {
                                        string exceptionDesc = DebuggerUtils.GetExceptionDescFromProcess(m_process, true);
                                        //Console.Out.WriteLine("----------------------------------------------------");
                                        //Console.Out.WriteLine(exceptionDesc);
                                        File.AppendAllText(LastLogFileName, "----------------------------------------------------\n" + DateTime.Now.ToString("dd\\MM\\yyyy mm:hh:ss.fff]") + exceptionDesc + "\n");
                                        m_sbProcessLog.AppendLine("----------------------------------------------------\n");
                                        m_sbProcessLog.AppendLine(DateTime.Now.ToString("dd/MM/yyyy HH:mm:ss.fff"));
                                        m_sbProcessLog.AppendLine(exceptionDesc);
                                    }
                                    catch (Exception ex)
                                    {
                                        DebuggerUtils.HandleException(ex);
                                    }
                                    //m_process.Go();
                                }
                            }
                        }
                        catch (Exception ex)
                        {
                            DebuggerUtils.HandleException(ex);
                        }
                    }
                    m_blnIsListening = false;
                }
                catch (Exception ex)
                {
                    DebuggerUtils.HandleException(ex);
                }
                //m_process.PostDebugEvent += m_processEventHandler;
            });
        }
Пример #16
0
 public MDbgValue ParseExpression(string variableName, MDbgProcess process, MDbgFrame scope)
 {
     Debug.Assert(process != null);
     return process.ResolveVariable(variableName, scope);
 }
Пример #17
0
 public CorValue ParseExpression2(string value, MDbgProcess process, MDbgFrame scope)
 {
     if (value.Length == 0)
     {
         return null;
     }
     CorGenericValue result;
     if (TryCreatePrimitiveValue(value, out result))
     {
         //value is a primitive type
         return result;
     }
     if (value[0] == '"' && value[value.Length - 1] == '"')
     {
         //value is a string
         return CreateString(value);
     }
     //value is some variable
     Debug.Assert(process != null);
     MDbgValue var = process.ResolveVariable(value, scope);
     return (var == null ? null : var.CorValue);
 }
Пример #18
0
        public static string GetExceptionDescFromProcess(MDbgProcess process, bool printInnerExcptions = false)
        {
            object o = process.StopReason;
            ExceptionThrownStopReason m = o as ExceptionThrownStopReason;
            StringBuilder retVal = new StringBuilder();

            string strEventType = "";
            if (m != null)
                strEventType = m.EventType.ToString();
            MDbgThread activeThread = null;

            if (process.Threads.HaveActive && process.Threads.Active.CurrentException.TypeName != "N/A")
            {
                activeThread = process.Threads.Active;
            }
            else
            {
                foreach (MDbgThread t in process.Threads)
                {
                    if (t.CurrentException.TypeName != "N/A")
                    {
                        activeThread = t;
                        break;
                    }
                }
            }

            if (activeThread.CurrentException == null)
                return null;

            retVal.AppendLine(strEventType);
            //collect exception data
            MDbgValue ex = activeThread.CurrentException;
            retVal.Append(GetStringFromException(activeThread, ex));

            if (printInnerExcptions)
            {
                ex = ex.GetField("_innerException");
                for (uint i = 1; !ex.IsNull; ex = ex.GetField("_innerException"), i++)
                {
                    retVal.AppendLine("---InnerException" + i + ": ");
                    retVal.Append(GetStringFromException(null, ex));
                }
            }

            return retVal.ToString();
        }
Пример #19
0
        /// <summary>
        /// 
        /// </summary>
        /// <param name="proc">the process</param>
        /// <param name="threadId">a specific thread to read -1 = all threads</param>
        /// <param name="withArgs">evaluate arguments (more detail)</param>
        /// <returns></returns>
        public static ProcessSample GetCallstacks(MDbgProcess proc, int threadId = -1, bool withArgs = false, bool originFirst = false)
        {
            ProcessSample samples = new ProcessSample();
            MDbgThreadCollection tc = proc.Threads;
            //Console.WriteLine("Attached to pid:{0}", proc.CorProcess.Id);
            foreach (MDbgThread t in tc)
            {
                if (threadId != -1 && t.Id != threadId)
                    continue;

                if (!DebuggerUtils.CheckValidState(t))
                    continue;

                StackSample sample = GetThreadStacks(t, withArgs, originFirst);
                samples.Samples.Add(sample);
            }
            return samples;
        }
Пример #20
0
        /// <summary>Gets information about the current state of the debugger.</summary>
        /// <returns>A filled DebugInformation object. Contains exception information if available.</returns>
        /// <remarks>Assumes that the process is safe to examine.</remarks>
        /// <param name="debuggedProc">The Process to examine.</param>
        private DebugInformation GetDebugInformation(MDbgProcess debuggedProc)
        {
            DebugInformation di = new DebugInformation();

            object stopReason = debuggedProc.StopReason;

            if (debuggedProc.Threads.HaveActive && debuggedProc.Threads.Active.HaveCurrentFrame)
            {
                di.LocalVariableInformation = GetScopeVariables(debuggedProc.Threads.Active.CurrentFrame);
            }

            // AttachComplete is triggered once the debugger
            if (stopReason is AttachCompleteStopReason)
            {
                di.CurrentOutput = "";
                di.Stopped = true;
                di.StartLineNumber = 0;
                GetStopReasonInfo(stopReason, out di.StopReasonText, out di.StopReason);
                return di;
            }

            if (stopReason is ExceptionThrownStopReason || stopReason is UnhandledExceptionThrownStopReason)
            {
                ExceptionInformation ei = GetExceptionInformation(debuggedProc);

                di.ExceptionInformation = ei;
                di.ExceptionThrown = true;
            }

            GetStopReasonInfo(stopReason, out di.StopReasonText, out di.StopReason);

            if (debuggedProc.Threads.HaveActive == false || debuggedProc.Threads.Active.HaveCurrentFrame == false ||
                  debuggedProc.Threads.Active.CurrentFrame.SourcePosition == null)
            {
                di.Stopped = false;
                di.StartLineNumber = int.MinValue;
                di.EndLineNumber = int.MinValue;
                di.StartColumnNumber = int.MinValue;
                di.EndColumnNumber = int.MinValue;
            }
            else
            {
                MDbgFrame currentFrame = debuggedProc.Threads.Active.CurrentFrame;
                if (currentFrame.SourcePosition != null)
                {
                    di.StartLineNumber = currentFrame.SourcePosition.Line;
                    di.StartColumnNumber = currentFrame.SourcePosition.StartColumn - 1;
                    di.EndColumnNumber = currentFrame.SourcePosition.EndColumn - 1;
                    di.EndLineNumber = currentFrame.SourcePosition.EndLine;
                }
                else
                {
                    di.StartLineNumber = 0;
                    di.StartColumnNumber = 0;
                    di.EndColumnNumber = 0;
                    di.EndLineNumber = 0;
                }
                di.CurrentOutput = GetCurrentOutput(debuggedProc);
                if (di.CurrentOutput == null)
                {
                    di.Stopped = false;
                    di.StopReason = StopReason.StepComplete;
                    di.StartLineNumber = int.MinValue;
                    di.EndLineNumber = int.MinValue;
                    di.StartColumnNumber = int.MinValue;
                    di.EndColumnNumber = int.MinValue;
                }
            }

            return di;
        }
Пример #21
0
        /// <summary>
        /// Fills an ExceptionInformation object with information about the
        /// current exception in the active thread. 
        /// </summary>
        /// <param name="debuggedProc">The Process to extract exception from.</param>
        /// <returns>A filled ExceptionInformation object, or null if there is no current exception.</returns>
        private ExceptionInformation GetExceptionInformation(MDbgProcess debuggedProc)
        {
            ExceptionInformation ei = new ExceptionInformation();
            //ei.StackTrace = GetStackTrace(debuggedProc.Threads.Active);

            ExceptionInformation inner = ei;

            MDbgValue ex = debuggedProc.ResolveVariable("$exception", debuggedProc.Threads.Active.CurrentFrame);
            if (ex == null)
                return null;
            do
            {
                MDbgValue messageValue = ResolveFunction(debuggedProc, ex, "System.Exception.get_Message");
                if (messageValue != null)
                {
                    inner.Message = messageValue.GetStringValue(true);
                }
                else
                {
                    inner.Message = "Could not retrieve the exception message";
                }

                MDbgValue stackTrace = ResolveFunction(debuggedProc, ex, "System.Exception.get_StackTrace");
                if (stackTrace != null)
                {
                    inner.StackTraceString = stackTrace.GetStringValue(true);
                }
                else
                {
                    inner.StackTraceString = "Could not retrieve stack trace";
                }

                ex = ResolveFunction(debuggedProc, ex, "System.Exception.get_InnerException");
                if (ex != null && ex.IsNull != true)
                {
                    inner.InnerExceptionInfo = new ExceptionInformation();
                    inner = inner.InnerExceptionInfo;
                }
            } while (ex != null && ex.IsNull != true);

            return ei;
        }
Пример #22
0
        // Set whether the GUI is in "Run-mode" or "Break-mode"
        // OnOff = true if we're stopping; false if we're going to start running
        // This must be called on the UI thread.
        // This will also set the ActiveProcess property so that other events on the 
        // UI thread can see if it's safe to access Mdbg objects.
        private void SetCommandInputState(bool OnOff)
        {
            // Enable / disable UI elements.
            cmdInput.Enabled = OnOff;
            breakCmd.Enabled=!OnOff;

            // Although the underlying MDbg engine supports multiple processes,
            // We'll only support 1 process from the UI to keep things simple.             
            bool fHasProcess = GuiExtension.Debugger.Processes.HaveActive;

            // If we're stopped, and we don't already have a process, then allow creating one.
            bool fAllowCreate = OnOff && !fHasProcess;
            menuItemLaunch.Enabled = fAllowCreate;
            menuItemAttach.Enabled = fAllowCreate;

            // If we're stopped, and we do have a process, allow killing it.
            bool fAllowKill = OnOff && fHasProcess;
            menuItemDetach.Enabled = fAllowKill;
            menuItemKill.Enabled = fAllowKill;

           
            SetTitle(OnOff);

            if(OnOff)
            {
                // Enter "Break" Mode
                if (fHasProcess)
                {
                    m_process = GuiExtension.Debugger.Processes.Active;
                }
                else
                {
                    m_process = null;
                }

                Activate();                                 // bring GUI up when we e.g. hit breakpoint 
                this.Cursor = Cursors.Default;

                ShowCurrentLocation(); // calculate current source location.
                SourceViewerForm.OnBreak();

                WritePrompt();
                cmdInput.Focus();
            }
            else
            {
                m_process = null;
                
                // Enter "Run" mode
                m_CurrentSourcePosition = null;
                SourceViewerForm.OnRun();

                this.Cursor = Cursors.AppStarting;
            }            
        }
Пример #23
0
        /// <summary>
        /// returns a list of samples (in time) of list (per thread) of CallstackSamples
        /// </summary>
        /// <param name="pid">the process id to attach to</param>
        /// <param name="numOfSamples"></param>
        /// <param name="timeBetweenSamplesInMillis"></param>
        /// <returns></returns>
        public List<ProcessSample> GetSample(MDbgProcess proc, int numOfSamples, int timeBetweenSamplesInMillis, bool extraDetails = false, bool originFirst = false)
        {
            List<ProcessSample> samples = new List<ProcessSample>();

            try
            {
                m_intMainThreadId = -1;

                if (m_onlyMainThread)
                {
                    MDbgThread mainthread = GetMainThread(proc);

                    m_intMainThreadId = mainthread.Id;
                    //if (e.CallbackType == ManagedCallbackType.OnException2)
                    //{
                    //    var ce = (CorException2EventArgs)e.CallbackArgs;

                    //    if (ce.EventType == CorDebugExceptionCallbackType.DEBUG_EXCEPTION_FIRST_CHANCE)
                    //    {
                    //        var thread = process.Threads.Lookup(ce.Thread);

                    //        foreach (var frame in thread.Frames)
                    //        {
                    //            if (!frame.IsManaged || frame.Function.FullName.StartsWith("System."))
                    //                break;

                    //            log.Log("{0}({1})", frame.Function.FullName, string.Join(", ", frame.Function.GetArguments(frame).Select(
                    //                arg => string.Format("{0} = {1}", arg.Name, arg.GetStringValue(false)))));
                    //        }
                    //    }
                    //}
                }

                if (m_intMainThreadId == -1)
                {
                    m_onlyMainThread = false;
                }

                Console.WriteLine("startTime: " + DateTime.Now.ToString("hh:mm:ss.fff"));
                int sleepTime = timeBetweenSamplesInMillis;
                Stopwatch s = Stopwatch.StartNew();
                for (int i = 0; i < numOfSamples; i++)
                {

                    ProcessSample frames = GetCallstacks(proc, m_onlyMainThread, extraDetails, originFirst);
                    samples.Add(frames);
                    //samples.Insert(0,frames);
                    s.Reset();
                    s.Start();
                    proc.Go();
                    //sleepTime -= (int)s.ElapsedMilliseconds;

                    //sleep
                    if (sleepTime > 0)
                        Thread.Sleep(sleepTime);

                    //reset sleep time
                    sleepTime = timeBetweenSamplesInMillis;

                    s.Reset();
                    s.Start();
                    proc.AsyncStop().WaitOne();
                    //sleepTime -= (int)s.ElapsedMilliseconds;
                }
                Console.WriteLine("EndTime: " + DateTime.Now.ToString("hh:mm:ss.fff"));
            }
            finally
            {
                //if (proc != null) { proc.Detach().WaitOne(); }
            }

            return samples;
        }
Пример #24
0
 // Print CorType to the given string builder.
 // Will print generic info. 
 
 internal static void PrintCorType(StringBuilder sb, MDbgProcess proc, CorType ct)
 {
     switch (ct.Type) 
     {
     case CorElementType.ELEMENT_TYPE_CLASS:
     case CorElementType.ELEMENT_TYPE_VALUETYPE:
         // We need to get the name from the metadata. We can get a cached metadata importer
         // from a MDbgModule, or we could get a new one from the CorModule directly.
         // Is this hash lookup to get a MDbgModule cheaper than just re-querying for the importer?
         CorClass cc = ct.Class;
         MDbgModule m = proc.Modules.Lookup(cc.Module);
         Type tn = m.Importer.GetType(cc.Token);
 
         sb.Append(tn.FullName);
         AddGenericArgs(sb, proc, ct.TypeParameters);
     return;
 
     // Primitives
     case CorElementType.ELEMENT_TYPE_BOOLEAN:       
         sb.Append("System.Boolean"); return;
     case CorElementType.ELEMENT_TYPE_CHAR:          
         sb.Append("System.Char"); return;
     case CorElementType.ELEMENT_TYPE_I1:            
         sb.Append("System.SByte"); return;
     case CorElementType.ELEMENT_TYPE_U1:            
         sb.Append("System.Byte"); return;
     case CorElementType.ELEMENT_TYPE_I2:            
         sb.Append("System.Int16"); return;
     case CorElementType.ELEMENT_TYPE_U2:            
         sb.Append("System.UInt16"); return;
     case CorElementType.ELEMENT_TYPE_I4:            
         sb.Append("System.Int32"); return;
     case CorElementType.ELEMENT_TYPE_U4:            
         sb.Append("System.Uint32"); return;
     case CorElementType.ELEMENT_TYPE_I8:            
         sb.Append("System.Int64"); return;
     case CorElementType.ELEMENT_TYPE_U8:            
         sb.Append("System.UInt64"); return;
     case CorElementType.ELEMENT_TYPE_I:            
         sb.Append("System.IntPtr"); return;
     case CorElementType.ELEMENT_TYPE_U:            
         sb.Append("System.UIntPtr"); return;
     case CorElementType.ELEMENT_TYPE_R4:            
         sb.Append("System.Single"); return;
     case CorElementType.ELEMENT_TYPE_R8:            
         sb.Append("System.Double"); return;
 
     // Well known class-types.
     case CorElementType.ELEMENT_TYPE_OBJECT:        
         sb.Append("System.Object"); return;
     case CorElementType.ELEMENT_TYPE_STRING:        
         sb.Append("System.String"); return;
 
 
     // Special compound types. Based off first type-param
     case CorElementType.ELEMENT_TYPE_SZARRAY:
     case CorElementType.ELEMENT_TYPE_ARRAY:
     case CorElementType.ELEMENT_TYPE_BYREF:
     case CorElementType.ELEMENT_TYPE_PTR:
         CorType t = ct.FirstTypeParameter;
         PrintCorType(sb, proc, t);
         switch(ct.Type)
         {
         case CorElementType.ELEMENT_TYPE_SZARRAY: 
             sb.Append("[]"); 
             return;
         case CorElementType.ELEMENT_TYPE_ARRAY:   
             int rank = ct.Rank;
             sb.Append('[');
             for(int i = 0; i < rank - 1; i++)
             {
                 
                 sb.Append(',');
             }
             sb.Append(']'); 
             return;
         case CorElementType.ELEMENT_TYPE_BYREF:   
             sb.Append("&"); 
             return;
         case CorElementType.ELEMENT_TYPE_PTR:     
             sb.Append("*"); 
             return;                    
         }
         Debug.Assert(false); // shouldn't have gotten here.             
         return;
     
     case CorElementType.ELEMENT_TYPE_FNPTR:
         sb.Append("*(...)");
         return;
     case CorElementType.ELEMENT_TYPE_TYPEDBYREF:
         sb.Append("typedbyref");
         return;
     default:
         sb.Append("<unknown>");
         return;
     }
 } // end PrintClass
Пример #25
0
        private MDbgThread GetMainThread(MDbgProcess proc)
        {
            MDbgThread mainthread = null;
            foreach (MDbgThread thread in proc.Threads)
            {
                if (DebuggerUtils.CheckValidState(thread))
                {
                    MDbgFrame[] frames = new MDbgFrame[0];

                    try
                    {
                        frames = thread.Frames.ToArray();
                    }
                    catch { }

                    foreach (MDbgFrame f in frames)
                    {
                        string line = DebuggerUtils.GetFrameString(f);

                        if (line.Contains("System.Windows.Application.Run") ||
                            line.Contains("Program.Main") ||
                            line.Contains("System.Windows.Forms.Application.Run"))
                        {
                            mainthread = thread;
                            //m_intMainThreadId = thread.Id;
                            break;
                        }
                    }
                }
            }
            return mainthread;
        }
Пример #26
0
 /// <summary>
 /// Creates a new instance of the MDbgValue Object.
 /// This constructor is public so that applications can use this class to print values (CorValue).
 /// CorValue's can be returned for example by funceval(CorEval.Result).
 /// </summary>
 /// <param name="process">The Process that will own the Value.</param>
 /// <param name="name">The name of the variable.</param>
 /// <param name="value">The CorValue that this MDbgValue will start with.</param>
 public MDbgValue(MDbgProcess process, string name, CorValue value)
 {
     Debug.Assert(process != null && name != null);
     // corValue can be null for native variables in MC++
     Initialize(process, name, value);
 }
Пример #27
0
 internal MDbgModuleCollection(MDbgProcess process)
 {
     Debug.Assert(process != null);
     m_process = process;
 }
Пример #28
0
 internal MDbgThreadCollection(MDbgProcess process)
 {
     m_process = process;
     m_freeThreadNumber = 0;
 }
Пример #29
0
 internal MDbgBreakpointCollection(MDbgProcess process)
 {
     Debug.Assert(process != null);
     m_process = process;
 }
Пример #30
0
 internal MDbgDebuggerVarCollection(MDbgProcess process)
 {
     m_process = process;
 }