Пример #1
0
        public static void LaunchProcessWithAttachedDebugger()
        {
            var filename = GetFilename();
            Console.WriteLine("Launching " + filename);

            var stop = new ManualResetEvent(false);
            var engine = new MDbgEngine();
            var process = engine.CreateProcess(filename, "", DebugModeFlag.Default, null);
            process.Go();

            process.PostDebugEvent +=
              (sender, e) =>
              {
                  if (e.CallbackType == ManagedCallbackType.OnBreakpoint)
                      process.Go();

                  if (e.CallbackType == ManagedCallbackType.OnProcessExit)
                      stop.Set();
              };

            //var p = Process.Start(filename);
            Console.WriteLine("Launched...");
            stop.WaitOne();
            Application.Exit();
        }
Пример #2
0
        public static string GetCurrentLocationInSource(MDbgEngine debugger, IShell shell)
        {
            if (!debugger.Processes.Active.Threads.HaveActive)
            {
                return "";                                     // we won't try to show current location
            }

            MDbgThread thr = debugger.Processes.Active.Threads.Active;

            MDbgSourcePosition pos = thr.CurrentSourcePosition;
            if (pos == null)
            {
                MDbgFrame f = thr.CurrentFrame;
                if (f.IsManaged)
                {
                    CorDebugMappingResult mappingResult;
                    uint ip;
                    f.CorFrame.GetIP(out ip, out mappingResult);
                    string s = "IP: " + ip + " @ " + f.Function.FullName + " - " + mappingResult;
                    return s;
                }
                else
                {
                    return "<Located in native code.>";
                }
            }
            else
            {
                string fileLoc = shell.FileLocator.GetFileLocation(pos.Path);
                if (fileLoc == null)
                {
                    // Using the full path makes debugging output inconsistant during automated test runs.
                    // For testing purposes we'll get rid of them.
                    //CommandBase.WriteOutput("located at line "+pos.Line + " in "+ pos.Path);
                    return "located at line " + pos.Line + " in " + System.IO.Path.GetFileName(pos.Path);
                }
                else
                {
                    IMDbgSourceFile file = shell.SourceFileMgr.GetSourceFile(fileLoc);
                    string prefixStr = pos.Line.ToString(CultureInfo.InvariantCulture) + ":";

                    if (pos.Line < 1 || pos.Line > file.Count)
                    {
                        shell.WriteLine("located at line " + pos.Line + " in " + pos.Path);
                        throw new Exception(string.Format("Could not display current location; file {0} doesn't have line {1}.",
                                                                   file.Path, pos.Line));
                    }
                    Debug.Assert((pos.Line > 0) && (pos.Line <= file.Count));
                    return file[pos.Line];
                }
            }
        }
Пример #3
0
        public static Dictionary<string, string> GetLocalVars(MDbgEngine pDebugger, List<string> specificVarNames = null, bool debuggerVarsOpt = false, bool noFuncevalOpt = false, int? expandDepthOpt = null)
        {
            Dictionary<string, string> retVal = new Dictionary<string, string>();
            //const string debuggerVarsOpt = "d";
            //const string noFuncevalOpt = "nf";
            //const string expandDepthOpt = "r";

            //ArgParser ap = new ArgParser(arguments, debuggerVarsOpt + ";" + noFuncevalOpt + ";" + expandDepthOpt + ":1");
            bool canDoFunceval = !noFuncevalOpt;

            int? expandDepth = null;			    // we use optional here because
            // different codes bellow has different
            // default values.
            if (expandDepthOpt != null)
            {
                expandDepth = (int)expandDepthOpt;
                if (expandDepth < 0)
                    throw new MDbgShellException("Depth cannot be negative.");
            }

            MDbgFrame frame = pDebugger.Processes.Active.Threads.Active.CurrentFrame;
            if (debuggerVarsOpt)
            {
                // let's print all debugger variables
                MDbgProcess p = pDebugger.Processes.Active;
                foreach (MDbgDebuggerVar dv in p.DebuggerVars)
                {
                    MDbgValue v = new MDbgValue(p, dv.CorValue);
                    string value = v.GetStringValue(expandDepth == null ? 0 : (int)expandDepth, canDoFunceval);
                    retVal.Add(dv.Name, value);
                }
            }
            else
            {
                //!debuggerVarsOpt && !noFuncevalOpt && expandDepthOpt == null &&
                if (specificVarNames == null || specificVarNames.Count == 0)
                {
                    // get all active variables
                    MDbgFunction f = frame.Function;

                    ArrayList vars = new ArrayList();
                    MDbgValue[] vals = f.GetActiveLocalVars(frame);
                    if (vals != null)
                    {
                        vars.AddRange(vals);
                    }

                    vals = f.GetArguments(frame);
                    if (vals != null)
                    {
                        vars.AddRange(vals);
                    }
                    foreach (MDbgValue v in vars)
                    {
                        string value = v.GetStringValue(expandDepth == null ? 0 : (int)expandDepth, canDoFunceval);
                        retVal.Add(v.Name, value);
                    }
                }
                else
                {
                    // user requested printing of specific variables
                    for (int j = 0; j < specificVarNames.Count; ++j)
                    {
                        MDbgValue var = pDebugger.Processes.Active.ResolveVariable(specificVarNames[j], frame);
                        if (var != null)
                        {
                            string value = var.GetStringValue(expandDepth == null ? 1 : (int)expandDepth, canDoFunceval);
                            retVal.Add(specificVarNames[j], value);
                        }
                        else
                        {
                            throw new MDbgShellException("Variable not found");
                        }
                    }
                }
            }
            return retVal;
        }
Пример #4
0
        //////////////////////////////////////////////////////////////////////////////////
        //
        // Customization methods (to be overriden in aditional skins).
        //
        //////////////////////////////////////////////////////////////////////////////////
        protected virtual void Init(string[] commandLineArguments)
        {
            string[] initialCommands = null;

            // process startup commands
            if (commandLineArguments.Length != 0)
            {
                ArrayList startupCommands = new ArrayList();
                if (commandLineArguments[0].Length > 1 && commandLineArguments[0][0] == '!')
                {
                    // ! commands on command line
                    int i = 0;
                    while (i < commandLineArguments.Length)
                    {
                        StringBuilder sb = new StringBuilder();
                        Debug.Assert(commandLineArguments[i][0] == '!');
                        sb.Append(commandLineArguments[i].Substring(1));
                        ++i;
                        while (i < commandLineArguments.Length &&
                              !(commandLineArguments[i].Length > 1 && commandLineArguments[i][0] == '!'))
                        {
                            sb.Append(' ');
                            sb.Append(commandLineArguments[i]);
                            ++i;
                        }
                        startupCommands.Add(sb.ToString());
                    }
                }
                else
                {
                    // it is name of executable on the command line
                    StringBuilder sb = new StringBuilder("run");
                    for (int i = 0; i < commandLineArguments.Length; i++)
                    {
                        sb.Append(' ');
                        string arg = commandLineArguments[i];
                        if (arg.IndexOf(' ') != -1)
                        {
                            // argument contains spaces, need to quote it
                            sb.Append('\"').Append(arg).Append('\"');
                        }
                        else
                        {
                            sb.Append(arg);
                        }
                    }
                    startupCommands.Add(sb.ToString());
                }

                initialCommands = (string[])startupCommands.ToArray(typeof(string));
            }

            this.IO = new MDbgIO(this, initialCommands);

            MdbgCommands.Shell = this;

            m_debugger = new MDbgEngine();
            MdbgCommands.Initialize();

            OnCommandExecuted += new CommandExecutedEventHandler(MdbgCommands.WhenHandler);

            ProcessAutoExec();
        }
Пример #5
0
        public static void AttachCmd(int pid, MDbgEngine debugger)
        {
            const string versionArg = "ver";
            const string continuationEventArg = "attachEvent";
            const string pidArg = "pid";
            //ArgParser ap = new ArgParser(arguments, versionArg + ":1;" + continuationEventArg + ":1;" + pidArg + ":1");

            //if (ap.Count > 1)
            //{
            //    throw new MDbgShellException("Wrong # of arguments.");
            //}

            //if (!ap.Exists(0) && !ap.OptionPassed(pidArg))
            //{
            //    WriteOutput("Please choose some process to attach");
            //    ProcessEnumCmd("");
            //    return;
            //}

            //int pid;
            //if (ap.Exists(0))
            //{
            //    pid = ap.AsInt(0);
            //    if (ap.OptionPassed(pidArg))
            //    {
            //        //WriteOutput("Do not specify pid option when also passing pid as last argument");
            //        return;
            //    }
            //}
            //else
            //{
            //    Debug.Assert(ap.OptionPassed(pidArg)); // verified above
            //    pid = ap.GetOption(pidArg).AsInt;
            //}

            //
            // Do some sanity checks to give useful end-user errors.
            //

            // Can't attach to ourselves!
            if (Process.GetCurrentProcess().Id == pid)
            {
                throw new Exception("Cannot attach to myself!");
            }

            // Can't attach to a process that we're already debugging.
            // ICorDebug may enforce this, but the error may not be very descriptive for an end-user.
            // For example, ICD may propogate an error from the OS, and the OS may return
            // something like AccessDenied if another debugger is already attached.
            // This only checks for cases where this same instance of MDbg is already debugging
            // the process of interest.
            foreach (MDbgProcess procOther in debugger.Processes)
            {
                if (pid == procOther.CorProcess.Id)
                {
                    throw new Exception("Can't attach to process " + pid + " because it's already being debugged");
                }
            }

            // Get the OS handle if there was one
            ///SafeWin32Handle osEventHandle = null;
            ///if (ap.OptionPassed(continuationEventArg))
            ///{
            ///    osEventHandle = new SafeWin32Handle(new IntPtr(ap.GetOption(continuationEventArg).AsHexOrDecInt));
            ///}

            // determine the version to attach to
            string version = MdbgVersionPolicy.GetDefaultAttachVersion(pid);
            //}
            if (version == null)
            {
                throw new Exception("Can't determine what version of the CLR to attach to in process " +
                    pid + ". Use -ver to specify a version");
            }

            // attach
            MDbgProcess p;
            //p = debugger.Attach(pid, osEventHandle, version);
            p = debugger.Attach(pid, null, version);

            p.Go().WaitOne();

            //if (osEventHandle != null)
            //{
            //    osEventHandle.Dispose();
            //}
        }
Пример #6
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;
        }
Пример #7
0
 internal MDbgProcessCollection(MDbgEngine engine)
 {
     m_engine = engine;
 }
Пример #8
0
        static void Main(string[] args)
        {
            if (args.Length < 1) {
                Usage();
                return;
            }

            int samples = 10;
            int sampleInterval = 1000;

            var state = ParseState.Unknown;
            foreach (var arg in args.Skip(1)) {
                switch (state) {
                    case ParseState.Unknown:
                        if (arg.ToLower() == "/s") {
                            state = ParseState.Samples;
                        } else if (arg.ToLower() == "/i") {
                            state = ParseState.Interval;
                        } else {
                            Usage();
                            return;
                        }
                        break;
                    case ParseState.Samples:
                        if (!Int32.TryParse(arg, out samples)) {
                            Usage();
                            return;
                        }
                        state = ParseState.Unknown;
                        break;
                    case ParseState.Interval:
                        if (!Int32.TryParse(arg, out sampleInterval)) {
                            Usage();
                            return;
                        }
                        state = ParseState.Unknown;
                        break;
                    default:
                        break;
                }
            }

            string pidOrProcess = args[0];

            var stats = new Dictionary<int, List<ThreadSnapshot>>();
            var debugger = new MDbgEngine();
            int pid = -1;

            var processes = Process.GetProcessesByName(pidOrProcess);
            if (processes.Length < 1) {
                try {
                    pid = Int32.Parse(pidOrProcess);
                } catch {
                    Console.WriteLine("Error: could not find any processes with that name or pid");
                    return;
                }
            } else {
                if (processes.Length > 1) {
                    Console.WriteLine("Warning: multiple processes share that name, attaching to the first");
                }
                pid = processes[0].Id;
            }

            MDbgProcess attached = null;
            try {
                attached = debugger.Attach(pid);
            } catch(Exception e) {
                Console.WriteLine("Error: failed to attach to process: " + e);
                return;
            }

            attached.Go().WaitOne();

            for (int i = 0; i < samples; i++) {

                foreach (MDbgThread thread in attached.Threads) {
                    var snapshot = ThreadSnapshot.GetThreadSnapshot(thread);
                    List<ThreadSnapshot> snapshots;
                    if (!stats.TryGetValue(snapshot.Id, out snapshots)) {
                        snapshots = new List<ThreadSnapshot>();
                        stats[snapshot.Id] = snapshots;
                    }

                    snapshots.Add(snapshot);
                }

                attached.Go();
                Thread.Sleep(sampleInterval);
                attached.AsyncStop().WaitOne();
            }

            attached.Detach().WaitOne();

            // perform basic analysis to see which are the top N stack traces observed,
            //  weighted on cost

            Dictionary<Guid, long> costs = new Dictionary<Guid,long>();
            Dictionary<Guid, string> stacks = new Dictionary<Guid, string>();

            foreach (var stat in stats.Values)
            {
                long prevTime = -1;
                foreach (var snapshot in stat)
                {
                    long time = snapshot.KernelTime + snapshot.UserTime;
                    if (prevTime != -1)
                    {
                        foreach (var tuple in snapshot.StackHashes)
                        {
                            if (costs.ContainsKey(tuple.Item1))
                            {
                                costs[tuple.Item1] += time - prevTime;
                            }
                            else
                            {
                                costs[tuple.Item1] = time - prevTime;
                                stacks[tuple.Item1] = tuple.Item2;
                            }
                        }
                    }
                    prevTime = time;
                }
            }

            Console.WriteLine("Most expensive stacks");
            Console.WriteLine("------------------------------------");
            foreach (var group in costs.OrderByDescending(p => p.Value).GroupBy(p => p.Value))
            {
                List<string> stacksToShow = new List<string>();

                foreach (var pair in group.OrderByDescending(p => stacks[p.Key].Length))
                {
                    if (!stacksToShow.Any(s => s.Contains(stacks[pair.Key])))
                    {
                        stacksToShow.Add(stacks[pair.Key]);
                    }
                }

                foreach (var stack in stacksToShow)
                {
                    Console.WriteLine(stack);
                    Console.WriteLine("===> Cost ({0})", group.Key);
                    Console.WriteLine();
                }
            }

            var offenders = stats.Values
               .Select(_ => ThreadSnapshotStats.FromSnapshots(_))
               .OrderBy(stat => stat.TotalKernelTime + stat.TotalUserTime)
               .Reverse();

            foreach (var stat in offenders) {
                Console.WriteLine("------------------------------------");
                Console.WriteLine(stat.ThreadId);
                Console.WriteLine("Kernel: {0} User: {1}", stat.TotalKernelTime, stat.TotalUserTime);
                foreach (var method in stat.CommonStack) {
                    Console.WriteLine(method);
                }
                Console.WriteLine("Other Stacks:");
                var prev = new List<string>();
                foreach (var trace in stats[stat.ThreadId].Select(_ => _.StackTrace)) {
                    if (!prev.SequenceEqual(trace)) {
                        Console.WriteLine();
                        foreach (var method in trace) {
                            Console.WriteLine(method);
                        }
                    } else {
                        Console.WriteLine("<skipped>");
                    }
                    prev = trace;
                }
                Console.WriteLine("------------------------------------");

            }
        }
Пример #9
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;
        }
Пример #10
0
 public FuncEvalSerializer(MDbgEngine debugger, bool useLoadFrom, IShell shell)
 {
     this.debugger = debugger;
     this.shell = shell;
     this.useLoadFrom = useLoadFrom;
 }
Пример #11
0
        private void InitDebugging()
        {
            this.configuration = ReadConfiguration(options.Config);
            SymbolCache = new MDbgSymbolCache();
            Debugger = new MDbgEngine();
            BreakpointParser = new DefaultBreakpointParser(this);
            FileLocator = new MDbgFileLocator();
            SourceFileMgr = new MDbgSourceFileMgr();
            PdbSymbolCache = new PdbSymbolCache(configuration.assemblies.Select(a => a.path), this);
            languageUtils = new List<ILanguageUtil>(new[] { new CSharpLanguageUtil() });

            methodLocators = new Dictionary<string, MethodLocator>();
            foreach (var assembly in configuration.assemblies)
            {
                methodLocators[assembly.path] = new MethodLocator(assembly.path, assembly.language, this);
            }
        }
Пример #12
0
        private static Dictionary<int, List<ThreadSnapshot>> CollectStats(SamplingParams sampling)
        {
            var stats = new Dictionary<int, List<ThreadSnapshot>>();
            var debugger = new MDbgEngine();

            MDbgProcess attached = null;
            try {
                attached = debugger.Attach(sampling.Pid);
            }
            catch (Exception e) {
                Console.WriteLine("Error: failed to attach to process: " + e);
                return stats;
            }

            attached.Go().WaitOne();

            for (int i = 0; i < sampling.Samples; i++) {
                foreach (MDbgThread thread in attached.Threads) {
                    try {
                        var snapshot = ThreadSnapshot.GetThreadSnapshot(thread);
                        List<ThreadSnapshot> snapshots;
                        if (!stats.TryGetValue(snapshot.Id, out snapshots))
                        {
                            snapshots = new List<ThreadSnapshot>();
                            stats[snapshot.Id] = snapshots;
                        }

                        snapshots.Add(snapshot);
                    }
                    catch (Exception ex) {
                        Console.WriteLine("Exception getting sample #{0} from PID {1} : {2}", i, sampling.Pid, ex.ToString());
                    }

                }

                attached.Go();
                Thread.Sleep(sampling.SampleInterval);
                attached.AsyncStop().WaitOne();
            }

            attached.Detach().WaitOne();

            return stats;
        }
Пример #13
0
 /// <summary>
 /// Creates an MdbgProcess that can be compatible with dump debuggees.
 /// </summary>
 /// <param name="engine">owning engine object</param>
 /// <param name="stopGo">stopGo controller to provide policy for execution of process.</param>
 internal MDbgProcess(MDbgEngine engine, IStopGoController stopGo)
 {
     CommonInit(engine);
     m_stopGo = stopGo;
 }
Пример #14
0
 /// <summary>
 /// Creates an MdbgProcess that can be compatible with the native pipeline
 /// debugging architecture
 /// </summary>
 /// <param name="engine">owning engine object</param>
 /// <param name="stopGo">stopGo controller to provide policy for execution of process.</param>
 public MDbgProcess(MDbgEngine engine)
 {
     CommonInit(engine);
 }
Пример #15
0
        /// <summary>Creates an empty process object.
        /// This object can be used to start a debugging session by calling
        /// CreateProcess or Attach method on it.
        /// </summary>
        /// <param name="engine">Root engine object that manages this process.</param>
        /// <param name="debugger">CorDebugger object that will be used to do an actual
        /// debugging</param>
        public MDbgProcess(MDbgEngine engine, CorDebugger debugger)
        {
            Debug.Assert(debugger != null);
            if (debugger == null)
                throw new ArgumentNullException("debugger");

            m_corDebugger = debugger;

            CommonInit(engine);
        }
Пример #16
0
 /// <summary>
 /// 
 /// attach and detach first to make sure that the process can be attached.
 /// next attach will be fast since the assembly loading is done on the first attach.
 /// </summary>
 /// <param name="pid"></param>
 public Task InitialAttach()
 {
     Task t = Task.Factory.StartNew(() =>
     {
         MDbgEngine debugger = new MDbgEngine();
         MDbgProcess process = DebuggerUtils.AttachToProcess(m_processId, debugger);
         process.CorProcess.Stop(0);
         process.Detach();
     });
     return t;
 }
Пример #17
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;
            });
        }
Пример #18
0
        public static MDbgProcess AttachToProcess(int pid, MDbgEngine debugger)
        {
            debugger.Options.SymbolPath = "";
            string ver = null;
            try
            {
                ver = CorDebugger.GetDebuggerVersionFromPid(pid);
            }
            catch (Exception ex)
            {
                //a problem getting the version doesn't mean that we can't attach, try with the default ver
                ver = CorDebugger.GetDefaultDebuggerVersion();
            }

            MDbgProcess proc = debugger.Attach(pid, null, ver);
            DebuggerUtils.DrainAttach(debugger, proc);
            return proc;
        }
Пример #19
0
        public List<ProcessSample> GetSample(int pid, int numOfSamples, int timeBetweenSamplesInMillis, bool extraDetails = false, bool originFirst = false)
        {
            List<ProcessSample> sample = null;
            MDbgProcess proc = null;
            try
            {
                MDbgEngine debugger = new MDbgEngine();

                proc = DebuggerUtils.AttachToProcess(pid, debugger);

                sample = GetSample(proc, numOfSamples, timeBetweenSamplesInMillis, extraDetails, originFirst);
            }
            finally
            {
                if (proc != null)
                    proc.Detach().WaitOne();
            }
            return sample;
        }
Пример #20
0
        public static MDbgProcess AttachToProcessWithName(string name)
        {
            MDbgEngine debugger = new MDbgEngine();
            MDbgProcess retval = null;

            Process p = DebuggerUtils.GetFirstProcessWithName(name);
            if (p != null)
                retval = DebuggerUtils.AttachToProcess(p.Id, debugger);

            return retval;
        }
Пример #21
0
        public static void DetachCmd(MDbgEngine debugger)
        {
            MDbgProcess active = debugger.Processes.Active;
            active.Breakpoints.DeleteAll();

            active.Detach();

            // We can't wait for targets that never run (e.g. NoninvasiveStopGoController against a dump)
            if (active.CanExecute())
                active.StopEvent.WaitOne();
        }
Пример #22
0
        // Do common initiliazation and add to the process collection.
        void CommonInit(MDbgEngine engine)
        {
            Debug.Assert(engine != null);
            if (engine == null)
                throw new ArgumentException("Value cannot be null.", "engine");

            m_engine = engine;

            m_threadMgr = new MDbgThreadCollection(this);
            m_appDomainMgr = new MDbgAppDomainCollection(this);
            m_moduleMgr = new MDbgModuleCollection(this);
            m_breakpointMgr = new MDbgBreakpointCollection(this);
            m_debuggerVarMgr = new MDbgDebuggerVarCollection(this);

            // we'll register as last code, so that other fields are already registered.
            m_number = engine.Processes.RegisterProcess(this);
        }