/// <summary>
 /// Initializes a new instance of the <see cref="RunningProcessVm"/> class.
 /// </summary>
 public RunningProcessVm()
 {
     CanExecute              = true;
     AttachmentOption        = new AttachmentOptionVm();
     RefreshProcessesCommand = new ButtonCommand(() => Debugger.RefreshProcessList(this), true);
     AttachToProcessCommand  = new ButtonCommand(z => Debugger.AttachToProcess(z), AttachmentOption, true);
     GetRunningProcesses();
 }
Beispiel #2
0
        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()