// Wait for the "guest mode" event to be signaled. private void _RegisterWaitForGuestModeEvent(ExceptionGuard disposer) { LogManager.Trace("Registering wait for GuestMode event."); ThreadPool.RegisterWaitForSingleObject(DbgProvider.GuestModeEvent, (x, y) => { disposer.Dispose(); SignalDone(); }, null, // state -1, // INFINITE true); // executeOnlyOnce } // end _RegisterWaitForGuestModeEvent()
} // end BeginProcessing() protected override void ProcessRecord() { var inputCallbacks = Debugger.GetInputCallbacks() as DebugInputCallbacks; if (null != inputCallbacks) { inputCallbacks.UpdateCmdlet(this); } //var outputCallbacks = Debugger.GetOutputCallbacks() as DebugOutputCallbacks; //if( null != outputCallbacks ) // outputCallbacks.UpdateCmdlet( this ); using (var disposer = new ExceptionGuard()) { disposer.Protect(Debugger.SetCurrentCmdlet(this)); disposer.Protect(InterceptCtrlC()); MsgLoop.Prepare(); string actualCommand = string.Join(" ", Command); Task t = Debugger.InvokeDbgEngCommandAsync(actualCommand, OutputPrefix, _ConsumeLine); Task t2 = t.ContinueWith(async(x) => { DEBUG_STATUS execStatus = Debugger.GetExecutionStatus(); if (_StatusRequiresWait(execStatus)) { LogManager.Trace("InvokeDbgExtensionCommand: Current execution status ({0}) indicates that we should enter a wait.", execStatus); await WaitForBreakAsync(); } disposer.Dispose(); SignalDone(); }).Unwrap(); MsgLoop.Run(); Host.UI.WriteLine(); Util.Await(t); // in case it threw Util.Await(t2); // in case it threw } // end using( disposer ) } // end ProcessRecord()
protected override void ProcessRecord() { base.ProcessRecord(); using (var disposer = new ExceptionGuard(Debugger.HandleDbgEngOutput(_ConsumeLine))) { // Failure to load an extension should be a terminating error. // // Because the only reason to load an extension is so that you can call // commands in it. And if you didn't load it, then none of those commands // will work. string providerPath = PathOrName; if (providerPath.IndexOfAny(sm_dirSeparators) >= 0) { // We support PS paths. // // (we don't want to call GetUnresolvedProviderPathFromPSPath if it's // just a bare name, else PS will interpret that as a relative path, // which would be wrong) providerPath = GetUnresolvedProviderPathFromPSPath(PathOrName); } MsgLoop.Prepare(); var t = Debugger.AddExtensionAsync(providerPath); t.ContinueWith((x) => { disposer.Dispose(); SignalDone(); }); MsgLoop.Run(); var elr = Util.Await(t); // in case it threw if (!string.IsNullOrEmpty(elr.LoadOutput)) { SafeWriteObject(elr.LoadOutput); } SafeWriteVerbose("Loaded extension: {0}", PathOrName); } // end using( disposer ) } // end ProcessRecord()
// I think this should be for kernel-mode only. // [Parameter( Mandatory = false )] // public SwitchParameter IgnoreInaccessibleMemory { get; set; } protected override void ProcessRecord() { // Support relative paths in PS. string dumpFileResolved = SessionState.Path.GetUnresolvedProviderPathFromPSPath(DumpFile); DEBUG_FORMAT flags = DEBUG_FORMAT.DEFAULT; flags |= DEBUG_FORMAT.USER_SMALL_FULL_MEMORY | DEBUG_FORMAT.USER_SMALL_HANDLE_DATA | DEBUG_FORMAT.USER_SMALL_UNLOADED_MODULES | DEBUG_FORMAT.USER_SMALL_INDIRECT_MEMORY | DEBUG_FORMAT.USER_SMALL_DATA_SEGMENTS | DEBUG_FORMAT.USER_SMALL_PROCESS_THREAD_DATA | DEBUG_FORMAT.USER_SMALL_PRIVATE_READ_WRITE_MEMORY | DEBUG_FORMAT.USER_SMALL_FULL_MEMORY_INFO | DEBUG_FORMAT.USER_SMALL_THREAD_INFO | DEBUG_FORMAT.USER_SMALL_CODE_SEGMENTS | DEBUG_FORMAT.USER_SMALL_FULL_AUXILIARY_STATE; // TODO: Need to learn what this means // I think this should be for kernel-mode only. // if( IgnoreInaccessibleMemory ) // { // flags |= DEBUG_FORMAT.USER_SMALL_IGNORE_INACCESSIBLE_MEM; // } // TODO: Figure out these things, and see if there are new ones I don't know about: // DEBUG_FORMAT.USER_SMALL_FILTER_MEMORY | // DEBUG_FORMAT.USER_SMALL_FILTER_PATHS | // DEBUG_FORMAT.USER_SMALL_NO_OPTIONAL_DATA | // DEBUG_FORMAT.USER_SMALL_NO_AUXILIARY_STATE | if (!AllowClobber) { flags |= DEBUG_FORMAT.NO_OVERWRITE; } if (Compress) { flags |= DEBUG_FORMAT.WRITE_CAB; } if (CompressWithSymbols) { flags |= DEBUG_FORMAT.WRITE_CAB; flags |= DEBUG_FORMAT.CAB_SECONDARY_FILES; // TODO: What is CAB_SECONDARY_ALL_IMAGES for? DbgEng.h says // // "When creating a CAB with secondary images do searches // for all image files, regardless of whether they're // needed for the current session or not." // // but I don't know what it means for an image file to be "needed" for the // current session versus not. } if ((Compress || CompressWithSymbols) && !DumpFile.EndsWith(".cab", StringComparison.OrdinalIgnoreCase)) { WriteWarning("Output will be compressed, but output file name does not end in '.cab'."); WriteWarning("You will need to rename the resulting file to end with '.cab' if you want to be able to mount the dump file with Mount-DbgDumpFile."); } // TODO: Just let the API fail instead of doing this pre-check? if (File.Exists(dumpFileResolved)) { if (!AllowClobber) { // is there a better "already exists" exception? WriteError(new InvalidOperationException(Util.Sprintf("The file '{0}' already exists. Use -AllowClobber to overwrite it.", DumpFile)), "DumpFileAlreadyExists", ErrorCategory.ResourceExists, DumpFile); return; } } using (var disposer = new ExceptionGuard()) { disposer.Protect(Debugger.HandleDbgEngOutput((x) => SafeWriteVerbose(x.TrimEnd()))); disposer.Protect(new CtrlCInterceptor(_CtrlCHandler)); try { MsgLoop.Prepare(); var task = Debugger.WriteDumpAsync(DumpFile, flags, Comment, CancelTS.Token); task.ContinueWith((_t) => { disposer.Dispose(); SignalDone(); }); MsgLoop.Run(); Util.Await(task); // in case it threw } catch (DbgProviderException dpe) { if ((dpe.HResult == DebuggerObject.E_UNEXPECTED) && CancelTS.IsCancellationRequested) { WriteWarning("Dump file creation canceled."); } else { WriteError(dpe); } } } // end using( dbgeng output, CTRL-C ) } // end ProcessRecord()