示例#1
0
 void DetachProcess()
 {
     if (_detached)
     {
         return;
     }
     if (!DebuggingNativeMethods.DebugActiveProcessStop(_pid))
     {
         _logger.Write("Exception occured when detaching from the process: {0}",
                       Marshal.GetExceptionForHR(Marshal.GetHRForLastWin32Error()));
     }
     _detached = true;
 }
示例#2
0
        private static DEBUG_EVENT?WaitForDebugEvent(uint timeout)
        {
            DEBUG_EVENT debugEvent;
            var         success = DebuggingNativeMethods.WaitForDebugEvent(out debugEvent, timeout);

            if (!success)
            {
                int hr = Marshal.GetHRForLastWin32Error();
                if (hr == HResults.HR_ERROR_SEM_TIMEOUT)
                {
                    return(null);
                }

                Marshal.ThrowExceptionForHR(hr);
            }
            return(debugEvent);
        }
示例#3
0
        private void WaitForDebugEvents()
        {
            using (var miniDumper = CreateMiniDumper()) {
                if (_options.NoDumpOptionSelected)
                {
                    miniDumper.DumpWithoutReason();
                    DetachProcess();
                    return;
                }

                while (!_detached)
                {
                    var debugEvent = WaitForDebugEvent(1000);
                    if (_shouldDeatch)
                    {
                        DetachProcess();
                        return;
                    }
                    if (debugEvent.HasValue)
                    {
                        switch (debugEvent.Value.dwDebugEventCode)
                        {
                        case DEBUG_EVENT_CODE.EXIT_PROCESS_DEBUG_EVENT:
                            if (_options.DumpOnProcessTerminate)
                            {
                                miniDumper.DumpOnProcessExit(debugEvent.Value.ExitProcess.dwExitCode);
                            }
                            _shouldDeatch = true;
                            break;

                        case DEBUG_EVENT_CODE.EXCEPTION_DEBUG_EVENT:
                            var exception = debugEvent.Value.Exception;
                            if (_options.DumpOnException == 1 && exception.dwFirstChance == 1 ||
                                _options.DumpOnException == 2 && exception.dwFirstChance == 0)
                            {
                                miniDumper.DumpOnException((uint)debugEvent.Value.dwThreadId, exception.ExceptionRecord);
                            }
                            break;

                        case DEBUG_EVENT_CODE.OUTPUT_DEBUG_STRING_EVENT:
                            if (_options.Verbose)
                            {
                                miniDumper.PrintDebugString(debugEvent.Value.DebugString);
                            }
                            break;

                        default:
                            break;
                        }
                        if (!_shouldDeatch && miniDumper.NumberOfDumpsTaken >= _options.NumberOfDumps)
                        {
                            Console.WriteLine("Number of dumps exceeded the specified limit - detaching.");
                            _shouldDeatch = true;
                        }
                        if (_shouldDeatch)
                        {
                            DetachProcess();
                            return;
                        }
                        if (_detached)
                        {
                            return;
                        }
                        var continueStatus = HandleDebugEvent(debugEvent.Value);
                        if (!DebuggingNativeMethods.ContinueDebugEvent(debugEvent.Value.dwProcessId,
                                                                       debugEvent.Value.dwThreadId, continueStatus))
                        {
                            throw new LastWin32ErrorException("Error in ContinueDebugEvent");
                        }
                    }
                }
            }
        }
示例#4
0
        void CreateProcess()
        {
            bool spawnNew = !string.IsNullOrEmpty(_options.DumpFolderForNewlyStartedProcess);

            _processName = null;

            int pid;

            if (int.TryParse(_options.ProcessInfo, out pid))
            {
                _pid = pid;
            }
            else
            {
                // not numeric - let's try to find it by name
                var procs = Process.GetProcesses();
                foreach (var proc in procs)
                {
                    try {
                        if (_options.ProcessInfo.Equals(proc.MainModule.ModuleName, StringComparison.OrdinalIgnoreCase))
                        {
                            _pid = proc.Id;
                            break;
                        }
                    } catch {
                        // just ignore it
                    }
                }
            }
            if (_pid > 0)
            {
                // process found - let's attach to it
                if (!DebuggingNativeMethods.DebugActiveProcess(_pid))
                {
                    Marshal.ThrowExceptionForHR(Marshal.GetHRForLastWin32Error());
                }
                _processName = GetProcessName(_pid);
                return;
            }
            if (spawnNew)
            {
                // final try - let's try creating it (but only if -x option is set)
                var commandLine = _options.ProcessInfo + " " + string.Join(" ", _options.Args ?? new string[0]);

                var startupInfo          = new STARTUPINFO();
                var processInformation   = new PROCESS_INFORMATION();
                var processCreationFlags = ProcessCreationFlags.DEBUG_ONLY_THIS_PROCESS;
                if (_options.StartProcessInNewConsoleWindow)
                {
                    processCreationFlags |= ProcessCreationFlags.CREATE_NEW_CONSOLE;
                }
                bool res = ProcessNativeMethods.CreateProcess(null, new StringBuilder(commandLine),
                                                              null, null, false, processCreationFlags, IntPtr.Zero, null,
                                                              startupInfo, processInformation);
                if (!res)
                {
                    Marshal.ThrowExceptionForHR(Marshal.GetHRForLastWin32Error());
                }

                if (!DebuggingNativeMethods.DebugSetProcessKillOnExit(false))
                {
                    Marshal.ThrowExceptionForHR(Marshal.GetHRForLastWin32Error());
                }
                _pid         = processInformation.dwProcessId;
                _processName = GetProcessName(_pid);
                return;
            }
            throw new ArgumentException("Something is wrong with the arguments - couldn't find or create a requested process.");
        }