protected override void ProcessRecord() { // Support relative paths in PS. string dumpFileResolved = SessionState.Path.GetUnresolvedProviderPathFromPSPath(DumpFile); // TODO: don't check this here... catch and write instead if (!File.Exists(dumpFileResolved)) { // It could be wildcarded... unfortunately attaching to multiple dumps // doesn't seem to work. But if it only resolves to one file... let's // allow it. ProviderInfo dontCare; var multi = SessionState.Path.GetResolvedProviderPathFromPSPath(DumpFile, out dontCare); if ((null == multi) || (0 == multi.Count)) { ThrowTerminatingError(new FileNotFoundException(), "NoSuchDumpFile", ErrorCategory.ObjectNotFound, DumpFile); return; } else if (multi.Count > 1) { ThrowTerminatingError(new NotSupportedException("Attaching to multiple dump files does not really work."), "AttachToMultipleDumpsNotsupported", ErrorCategory.OpenError, DumpFile); return; } else { dumpFileResolved = multi[0]; } } if (String.IsNullOrEmpty(TargetName)) { TargetName = Path.GetFileNameWithoutExtension(dumpFileResolved); } if (DbgProvider.IsTargetNameInUse(TargetName)) { ThrowTerminatingError(new ArgumentException(Util.Sprintf("The target name '{0}' is already in use. Please use -TargetName to specify a different target name.", TargetName), "TargetName"), "TargetNameInUse", ErrorCategory.ResourceExists, TargetName); } Debugger = DbgEngDebugger.NewDebugger(); using (Debugger.SetCurrentCmdlet(this)) { Debugger.LoadCrashDump(dumpFileResolved, TargetName); base.ProcessRecord(true); } // end using( psPipe ) } // end ProcessRecord()
protected override void ProcessRecord() { if (String.IsNullOrEmpty(TargetName)) { TargetName = Util.Sprintf("{0} ({1})", Path.GetFileNameWithoutExtension(FilePath), processId); } if (DbgProvider.IsTargetNameInUse(TargetName)) { ThrowTerminatingError(new ArgumentException(Util.Sprintf("The target name '{0}' is already in use. Please use -TargetName to specify a different target name.", TargetName), "TargetName"), "TargetNameInUse", ErrorCategory.ResourceExists, TargetName); } Debugger = DbgEngDebugger.NewDebugger(); CheckCanAddNewTargetType(DbgEngDebugger.TargetType.UmLive); using (Debugger.SetCurrentCmdlet(this)) { Debugger.ProcessCreated += DebuggerOnProcessCreated; Debugger.CreateProcessAndAttach2(_BuildCommandline(), StartDirectory, TargetName, SkipInitialBreakpoint, SkipFinalBreakpoint, NoDebugHeap, DebugChildProcesses, ConsoleOption); //Debugger.SetInputCallbacks( new DebugInputCallbacks( this ) ); //Debugger.SetOutputCallbacks( new DebugOutputCallbacks( this ) ); try { // will call Debugger.WaitForEvent() base.ProcessRecord(); } finally { Debugger.ProcessCreated -= DebuggerOnProcessCreated; } } // end using( current cmdlet ) } // end ProcessRecord()
protected override void ProcessRecord() { if (0 == Id) { // TODO: get our base cmdlet stuff WriteError(new ErrorRecord(new InvalidOperationException(), "CannotAttachToSystemProcess", ErrorCategory.InvalidOperation, Id)); return; } string existingTargetName = null; if (String.IsNullOrEmpty(TargetName)) { // Check to see if it already has a name before generating one. if (!Debugger.TryGetExistingUmTargetName((uint)Id, out existingTargetName) || DbgProvider.IsTargetNameInUse(existingTargetName)) { using (Process p = Process.GetProcessById(Id)) { TargetName = Util.Sprintf("{0} ({1})", p.ProcessName, Id); } } else { TargetName = existingTargetName; } // TODO: keep generating new target names until we succeed. } if (DbgProvider.IsTargetNameInUse(TargetName)) { ThrowTerminatingError(new ArgumentException(Util.Sprintf("The target name '{0}' is already in use. Please use -TargetName to specify a different target name.", TargetName), "TargetName"), "TargetNameInUse", ErrorCategory.ResourceExists, TargetName); } LogManager.Trace("Connecting to process 0x{0:x} ({1}).", Id, TargetName); Debugger = DbgEngDebugger.NewDebugger(); CheckCanAddNewTargetType(DbgEngDebugger.TargetType.UmLive); using (Debugger.SetCurrentCmdlet(this)) { Debugger.AttachToProcess(Id, SkipInitialBreakpoint, SkipFinalBreakpoint, ReAttach ? DEBUG_ATTACH.EXISTING : DEBUG_ATTACH.DEFAULT, TargetName); // This will call Debugger.WaitForEvent() base.ProcessRecord(true); if (ReAttach) { // Workaround for INT60c4fc41: "Reattaching to an .abandoned // process leaves thread suspend count too high" // // When abandoning a process, the debugger increments the suspend // count of all the threads. When re-attaching, the debugger // SHOULD undo that, but... it doesn't. So we'll try to fix that. foreach (var t in Debugger.EnumerateThreads()) { for (int sc = t.SuspendCount; sc > 1; sc--) { t.DecrementSuspendCount(); } } } } // end using( psPipe ) } // end ProcessRecord()