public int Attach(IDebugSession2 pSession) { attachedSession = pSession; ctx = new SquirrelDebugContext(DebugContextHandler, FileContexts); thread.SetContext(ctx); // temporary hack: if you try to connect when there's nothing to connect to, // it can put Visual Studio in an unstable state. This is because here, the DebugProcess, // is too late to attempt (and fail) to connect to the remote debugging port. // That should really have been done earlier, in the engine or program launch. // VS isn't capable of dealing with a failure in this function. bool bRetryConnect = false; do { bRetryConnect = false; engineCallback.OnOutputString("Connecting to" + IpAddress + ":" + IpPort); if (!ctx.Connect(IpAddress, IpPort)) { engineCallback.OnOutputString("ERROR: Cannot Connect to " + IpAddress + ":" + IpPort); engineCallback.OnError(null, "Cannot Connect to debugee"); switch (MessageBox.Show("Could not find a Squirrel VM to connect the debugger to.\n" + "You can either launch the game, run script_debug, and hit 'retry',\n" + "or cancel, 'stop debugging' and try again later.", "Temporary Failsafe", MessageBoxButtons.RetryCancel, MessageBoxIcon.Hand)) { case DialogResult.Retry: bRetryConnect = true; break; /* // This code path, although apparently correct, will actually cause Visual Studio to fail with a "could not detach from process" error. * // It's some cryptic COM error to do with the invoked process object having disconnected from its clients. * case DialogResult.Abort: * port.SendProcessCreateEvent(); * return Microsoft.VisualStudio.VSConstants.E_FAIL; */ case DialogResult.Ignore: case DialogResult.Cancel: default: break; } /* * ctx = null; * // attachedSession = null; * return Microsoft.VisualStudio.VSConstants.E_FAIL; */ } } while (bRetryConnect); port.SendProcessCreateEvent(); return(Microsoft.VisualStudio.VSConstants.S_OK); }
// Initiate an x86 stack walk on this thread. /* public void DoStackWalk(DebuggedThread thread) * { * //throw new NotImplementedException(); * } * * public void WaitForAndDispatchDebugEvent(ResumeEventPumpFlags flags) * { * throw new NotImplementedException(); * }*/ /* public int PollThreadId * { * get { return 1; } * } * * public bool IsStopped * { * get * { * return false; * } * } * * public bool IsPumpingDebugEvents * { * get * { * return true; * } * }*/ #endregion void DebugContextHandler(SquirrelDebugContext ctx, DebuggerEventDesc ed) { switch (ed.EventType) { case "error": case "breakpoint": case "step": if (ed.EventType != "step") { engineCallback.OnOutputString("DEBUGGER EVENT : " + ed.EventType + "\n"); } if (thread.Id != ed.ThreadId) { DebuggedThread oldthread = thread; thread = new DebuggedThread(engine, ed.ThreadId); thread.SetContext(ctx); engineCallback.OnThreadExit(oldthread, 0); } thread.SetStackFrames(ctx.StackFrames); processState = (uint)enum_PROCESS_INFO_FLAGS.PIFLAG_PROCESS_STOPPED | (uint)enum_PROCESS_INFO_FLAGS.PIFLAG_DEBUGGER_ATTACHED; switch (ed.EventType) { case "error": //engineCallback.OnError(thread,"Unhandled exception [{0}] line = {1} source = {2} ThreadId = {3}", ed.Error, ed.Line, ed.Source, ed.ThreadId); engineCallback.OnException(thread, ed.Error, ed.Line, ed.Source); break; case "breakpoint": { BreakPointAddress bpa = FindBreakpoint((uint)ed.Line, ed.Source); if (bpa != null) { engineCallback.OnOutputString("BP " + ed.Line + " : " + ed.Source + "\n"); engineCallback.OnBreakpoint(thread, bpa.boundbp, bpa.id); } else { engineCallback.OnOutputString("DEBUGGER ERROR : Could not find breakpoint " + ed.Line + " : " + ed.Source + "\n"); Continue(thread); } } break; case "step": engineCallback.OnStepComplete(thread); break; } break; case "resumed": engineCallback.OnOutputString("DEBUGGER EVENT : resumed\n"); processState = (uint)enum_PROCESS_INFO_FLAGS.PIFLAG_PROCESS_RUNNING | (uint)enum_PROCESS_INFO_FLAGS.PIFLAG_DEBUGGER_ATTACHED; break; case "suspended": engineCallback.OnOutputString("DEBUGGER EVENT : suspended\n"); engineCallback.OnAsyncBreakComplete(thread); processState = (uint)enum_PROCESS_INFO_FLAGS.PIFLAG_PROCESS_STOPPED | (uint)enum_PROCESS_INFO_FLAGS.PIFLAG_DEBUGGER_ATTACHED; break; case "disconnected": engineCallback.OnOutputString("DEBUGGER EVENT : disconnected\n"); Terminate(); processState = (uint)enum_PROCESS_INFO_FLAGS.PIFLAG_PROCESS_STOPPED; break; case "addbreakpoint": engineCallback.OnOutputString(String.Format("DEBUGGER EVENT : {0}\n", ed.EventType)); break; default: engineCallback.OnOutputString("DEBUGGER EVENT : " + ed.EventType + "<UNHANDLED>\n"); break; } //Console.WriteLine("do things here"); }