public void OnOutputMessage(OutputMessage outputMessage) { try { if (outputMessage.ErrorCode == 0) { var eventObject = new AD7MessageEvent(outputMessage, isAsync: true); Send(eventObject, AD7MessageEvent.IID, null); } else { var eventObject = new AD7ErrorEvent(outputMessage, isAsync: true); Send(eventObject, AD7ErrorEvent.IID, null); } } catch { // Since we are often trying to report an exception, if something goes wrong we don't want to take down the process, // so ignore the failure. } }
public AD7ErrorEvent(OutputMessage outputMessage, bool isAsync) { _outputMessage = outputMessage; _isAsync = isAsync; }
public AD7ErrorEvent(OutputMessage outputMessage, bool isAsync) { _outputMessage = outputMessage; _isAsync = isAsync; }
internal static int ConvertMessageToAD7(OutputMessage outputMessage, enum_MESSAGETYPE[] pMessageType, out string pbstrMessage, out uint pdwType, out string pbstrHelpFileName, out uint pdwHelpId) { const uint MB_ICONERROR = 0x00000010; const uint MB_ICONWARNING = 0x00000030; pMessageType[0] = outputMessage.MessageType; pbstrMessage = outputMessage.Message; pdwType = 0; if ((outputMessage.MessageType & enum_MESSAGETYPE.MT_TYPE_MASK) == enum_MESSAGETYPE.MT_MESSAGEBOX) { switch (outputMessage.SeverityValue) { case OutputMessage.Severity.Error: pdwType |= MB_ICONERROR; break; case OutputMessage.Severity.Warning: pdwType |= MB_ICONWARNING; break; } } pbstrHelpFileName = null; pdwHelpId = 0; return Constants.S_OK; }
private void SendMessage(string message, OutputMessage.Severity severity, bool isAsync) { try { // IDebugErrorEvent2 is used to report error messages to the user when something goes wrong in the debug engine. // The sample engine doesn't take advantage of this. AD7MessageEvent eventObject = new AD7MessageEvent(new OutputMessage(message, enum_MESSAGETYPE.MT_MESSAGEBOX, severity), isAsync); Send(eventObject, AD7MessageEvent.IID, null); } catch { // Since we are often trying to report an exception, if something goes wrong we don't want to take down the process, // so ignore the failure. } }
public void OnOutputMessage(OutputMessage outputMessage) { try { if (outputMessage.ErrorCode == 0) { var eventObject = new AD7MessageEvent(outputMessage, isAsync: true); Send(eventObject, AD7MessageEvent.IID, null); } else { var eventObject = new AD7ErrorEvent(outputMessage, isAsync: true); Send(eventObject, AD7ErrorEvent.IID, null); } } catch { // Since we are often trying to report an exception, if something goes wrong we don't want to take down the process, // so ignore the failure. } }
public DebuggedProcess(bool bLaunched, LaunchOptions launchOptions, ISampleEngineCallback callback, WorkerThread worker, BreakpointManager bpman, AD7Engine engine, string registryRoot) { uint processExitCode = 0; g_Process = this; _pendingMessages = new StringBuilder(400); _worker = worker; _launchOptions = launchOptions; _breakpointManager = bpman; Engine = engine; _libraryLoaded = new List <string>(); _loadOrder = 0; MICommandFactory = MICommandFactory.GetInstance(launchOptions.DebuggerMIMode, this); _waitDialog = MICommandFactory.SupportsStopOnDynamicLibLoad() ? new WaitDialog(ResourceStrings.LoadingSymbolMessage, ResourceStrings.LoadingSymbolCaption) : null; Natvis = new Natvis.Natvis(this); // we do NOT have real Win32 process IDs, so we use a guid AD_PROCESS_ID pid = new AD_PROCESS_ID(); pid.ProcessIdType = (int)enum_AD_PROCESS_ID.AD_PROCESS_ID_GUID; pid.guidProcessId = Guid.NewGuid(); this.Id = pid; SourceLineCache = new SourceLineCache(this); _callback = callback; _moduleList = new List <DebuggedModule>(); ThreadCache = new ThreadCache(callback, this); Disassembly = new Disassembly(this); ExceptionManager = new ExceptionManager(MICommandFactory, _worker, _callback, registryRoot); VariablesToDelete = new List <string>(); OutputStringEvent += delegate(object o, string message) { // We can get messages before we have started the process // but we can't send them on until it is if (_connected) { _callback.OnOutputString(message); } else { _pendingMessages.Append(message); } }; LibraryLoadEvent += delegate(object o, EventArgs args) { ResultEventArgs results = args as MICore.Debugger.ResultEventArgs; string file = results.Results.TryFindString("host-name"); if (!string.IsNullOrEmpty(file) && MICommandFactory.SupportsStopOnDynamicLibLoad()) { _libraryLoaded.Add(file); if (_waitDialog != null) { _waitDialog.ShowWaitDialog(file); } } else if (this.MICommandFactory.Mode == MIMode.Clrdbg) { string id = results.Results.FindString("id"); ulong baseAddr = results.Results.FindAddr("base-address"); uint size = results.Results.FindUint("size"); bool symbolsLoaded = results.Results.FindInt("symbols-loaded") != 0; var module = new DebuggedModule(id, file, baseAddr, size, symbolsLoaded, string.Empty, _loadOrder++); lock (_moduleList) { _moduleList.Add(module); } _callback.OnModuleLoad(module); } else if (!string.IsNullOrEmpty(file)) { string addr = results.Results.TryFindString("loaded_addr"); if (string.IsNullOrEmpty(addr) || addr == "-") { return; // identifies the exe, not a real load } // generate module string id = results.Results.TryFindString("name"); bool symsLoaded = true; string symPath = null; if (results.Results.Contains("symbols-path")) { symPath = results.Results.FindString("symbols-path"); if (string.IsNullOrEmpty(symPath)) { symsLoaded = false; } } else { symPath = file; } ulong loadAddr = results.Results.FindAddr("loaded_addr"); uint size = results.Results.FindUint("size"); if (String.IsNullOrEmpty(id)) { id = file; } var module = FindModule(id); if (module == null) { module = new DebuggedModule(id, file, loadAddr, size, symsLoaded, symPath, _loadOrder++); lock (_moduleList) { _moduleList.Add(module); } _callback.OnModuleLoad(module); } } }; if (_launchOptions is LocalLaunchOptions) { this.Init(new MICore.LocalTransport(), _launchOptions); } else if (_launchOptions is PipeLaunchOptions) { this.Init(new MICore.PipeTransport(), _launchOptions); } else if (_launchOptions is TcpLaunchOptions) { this.Init(new MICore.TcpTransport(), _launchOptions); } else if (_launchOptions is SerialLaunchOptions) { string port = ((SerialLaunchOptions)_launchOptions).Port; this.Init(new MICore.SerialTransport(port), _launchOptions); } else { throw new ArgumentOutOfRangeException("LaunchInfo.options"); } MIDebugCommandDispatcher.AddProcess(this); // When the debuggee exits, we need to exit the debugger ProcessExitEvent += delegate(object o, EventArgs args) { // NOTE: Exceptions leaked from this method may cause VS to crash, be careful ResultEventArgs results = args as MICore.Debugger.ResultEventArgs; if (results.Results.Contains("exit-code")) { // GDB sometimes returns exit codes, which don't fit into uint, like "030000000472". // And we can't throw from here, because it crashes VS. // Full exit code will still usually be reported in the Output window, // but here let's return "uint.MaxValue" just to indicate that something went wrong. if (!uint.TryParse(results.Results.FindString("exit-code"), out processExitCode)) { processExitCode = uint.MaxValue; } } // quit MI Debugger _worker.PostOperation(CmdExitAsync); if (_waitDialog != null) { _waitDialog.EndWaitDialog(); } }; // When the debugger exits, we tell AD7 we are done DebuggerExitEvent += delegate(object o, EventArgs args) { // NOTE: Exceptions leaked from this method may cause VS to crash, be careful // this is the last AD7 Event we can ever send // Also the transport is closed when this returns _callback.OnProcessExit(processExitCode); Dispose(); }; DebuggerAbortedEvent += delegate(object o, EventArgs args) { // NOTE: Exceptions leaked from this method may cause VS to crash, be careful // The MI debugger process unexpectedly exited. _worker.PostOperation(() => { // If the MI Debugger exits before we get a resume call, we have no way of sending program destroy. So just let start debugging fail. if (!_connected) { return; } _callback.OnError(MICoreResources.Error_MIDebuggerExited); _callback.OnProcessExit(uint.MaxValue); Dispose(); }); }; ModuleLoadEvent += async delegate(object o, EventArgs args) { // NOTE: This is an async void method, so make sure exceptions are caught and somehow reported if (_libraryLoaded.Count != 0) { string moduleNames = string.Join(", ", _libraryLoaded); try { _libraryLoaded.Clear(); SourceLineCache.OnLibraryLoad(); await _breakpointManager.BindAsync(); await CheckModules(); _bLastModuleLoadFailed = false; } catch (Exception e) { if (this.ProcessState == MICore.ProcessState.Exited) { return; // ignore exceptions after the process has exited } string exceptionDescription = EngineUtils.GetExceptionDescription(e); string message = string.Format(CultureInfo.CurrentCulture, MICoreResources.Error_ExceptionProcessingModules, moduleNames, exceptionDescription); // to avoid spamming the user, if the last module failed, we send the next failure to the output windiw instead of a message box if (!_bLastModuleLoadFailed) { _callback.OnError(message); _bLastModuleLoadFailed = true; } else { _callback.OnOutputMessage(new OutputMessage(message, enum_MESSAGETYPE.MT_OUTPUTSTRING, OutputMessage.Severity.Warning)); } } } if (_waitDialog != null) { _waitDialog.EndWaitDialog(); } if (MICommandFactory.SupportsStopOnDynamicLibLoad()) { CmdContinueAsync(); } }; // When we break we need to gather information BreakModeEvent += async delegate(object o, EventArgs args) { // NOTE: This is an async void method, so make sure exceptions are caught and somehow reported ResultEventArgs results = args as MICore.Debugger.ResultEventArgs; if (_waitDialog != null) { _waitDialog.EndWaitDialog(); } if (!this._connected) { _initialBreakArgs = results; return; } try { await HandleBreakModeEvent(results); } catch (Exception e) { if (this.ProcessState == MICore.ProcessState.Exited) { return; // ignore exceptions after the process has exited } string exceptionDescription = EngineUtils.GetExceptionDescription(e); string message = string.Format(CultureInfo.CurrentCulture, MICoreResources.Error_FailedToEnterBreakState, exceptionDescription); _callback.OnError(message); Terminate(); } }; ErrorEvent += delegate(object o, EventArgs args) { // NOTE: Exceptions leaked from this method may cause VS to crash, be careful ResultEventArgs result = (ResultEventArgs)args; _callback.OnError(result.Results.FindString("msg")); }; ThreadCreatedEvent += delegate(object o, EventArgs args) { ResultEventArgs result = (ResultEventArgs)args; ThreadCache.ThreadEvent(result.Results.FindInt("id"), /*deleted */ false); }; ThreadExitedEvent += delegate(object o, EventArgs args) { ResultEventArgs result = (ResultEventArgs)args; ThreadCache.ThreadEvent(result.Results.FindInt("id"), /*deleted*/ true); }; MessageEvent += (object o, ResultEventArgs args) => { OutputMessage outputMessage = DecodeOutputEvent(args.Results); if (outputMessage != null) { _callback.OnOutputMessage(outputMessage); } }; BreakChangeEvent += _breakpointManager.BreakpointModified; }