public JBreakpoint(JProcess process, string filename, int lineNo, string condition, bool breakWhenChanged, int breakpointId, bool isDjangoBreakpoint = false) { _process = process; _filename = filename; _lineNo = lineNo; _breakpointId = breakpointId; _condition = condition; _breakWhenChanged = breakWhenChanged; _isDjangoBreakpoint = isDjangoBreakpoint; }
public static ConnErrorMessages TryAttach(string hostName, ushort portNumber, string secret, bool useSsl, SslErrorHandling sslErrorHandling, out JProcess process) { process = null; Socket socket; Stream stream; ConnErrorMessages err = TryConnect(hostName, portNumber, secret, useSsl, sslErrorHandling, out socket, out stream); if (err == ConnErrorMessages.None) { bool attached = false; JLanguageVersion langVer; try { stream.Write(AttachCommandBytes); var buf = new byte[8]; int bufLen = stream.Read(buf, 0, Accepted.Length); string attachResp = Encoding.ASCII.GetString(buf, 0, bufLen); if (attachResp != Accepted) { return ConnErrorMessages.RemoteAttachRejected; } int langMajor = stream.ReadInt32(); int langMinor = stream.ReadInt32(); int langMicro = stream.ReadInt32(); langVer = (JLanguageVersion)((langMajor << 8) | langMinor); if (!Enum.IsDefined(typeof(JLanguageVersion), langVer)) { langVer = JLanguageVersion.None; } attached = true; } catch (IOException) { return ConnErrorMessages.RemoteNetworkError; } finally { if (!attached) { if (stream != null) { stream.Close(); } socket.Close(); socket = null; stream = null; } } process = new JRemoteProcess(hostName, portNumber, secret, useSsl, langVer); process.Connected(socket, stream); } return err; }
// Called by the SDM to indicate that a synchronous debug event, previously sent by the DE to the SDM, // was received and processed. The only event we send in this fashion is Program Destroy. // It responds to that event by shutting down the engine. int IDebugEngine2.ContinueFromSynchronousEvent(IDebugEvent2 eventObject) { AssertMainThread(); if (eventObject is AD7ProgramDestroyEvent) { var debuggedProcess = _process; _events = null; _process = null; _ad7ProgramId = Guid.Empty; foreach (var thread in _threads.Values) { thread.Dispose(); } _threads.Clear(); _modules.Clear(); debuggedProcess.Close(); } else { Debug.Fail("Unknown syncronious event"); } return VSConstants.S_OK; }
// Launches a process by means of the debug engine. // Normally, Visual Studio launches a program using the IDebugPortEx2::LaunchSuspended method and then attaches the debugger // to the suspended program. However, there are circumstances in which the debug engine may need to launch a program // (for example, if the debug engine is part of an interpreter and the program being debugged is an interpreted language), // in which case Visual Studio uses the IDebugEngineLaunch2::LaunchSuspended method // The IDebugEngineLaunch2::ResumeProcess method is called to start the process after the process has been successfully launched in a suspended state. int IDebugEngineLaunch2.LaunchSuspended(string pszServer, IDebugPort2 port, string exe, string args, string dir, string env, string options, enum_LAUNCH_FLAGS launchFlags, uint hStdInput, uint hStdOutput, uint hStdError, IDebugEventCallback2 ad7Callback, out IDebugProcess2 process) { Debug.WriteLine("--------------------------------------------------------------------------------"); Debug.WriteLine("JEngine LaunchSuspended Begin " + launchFlags + " " + GetHashCode()); AssertMainThread(); Debug.Assert(_events == null); Debug.Assert(_process == null); Debug.Assert(_ad7ProgramId == Guid.Empty); process = null; _events = ad7Callback; JLanguageVersion version = DefaultVersion; JDebugOptions debugOptions = JDebugOptions.None; bool attachRunning = false; List<string[]> dirMapping = null; string interpreterOptions = null; if (options != null) { var splitOptions = SplitOptions(options); foreach (var optionSetting in splitOptions) { var setting = optionSetting.Split(new[] { '=' }, 2); if (setting.Length == 2) { switch (setting[0]) { case VersionSetting: version = GetLanguageVersion(setting[1]); break; case WaitOnAbnormalExitSetting: bool value; if (Boolean.TryParse(setting[1], out value) && value) { debugOptions |= JDebugOptions.WaitOnAbnormalExit; } break; case WaitOnNormalExitSetting: if (Boolean.TryParse(setting[1], out value) && value) { debugOptions |= JDebugOptions.WaitOnNormalExit; } break; case RedirectOutputSetting: if (Boolean.TryParse(setting[1], out value) && value) { debugOptions |= JDebugOptions.RedirectOutput; } break; case BreakSystemExitZero: if (Boolean.TryParse(setting[1], out value) && value) { debugOptions |= JDebugOptions.BreakOnSystemExitZero; } break; case DebugStdLib: if (Boolean.TryParse(setting[1], out value) && value) { debugOptions |= JDebugOptions.DebugStdLib; } break; case DirMappingSetting: string[] dirs = setting[1].Split('|'); if (dirs.Length == 2) { if (dirMapping == null) { dirMapping = new List<string[]>(); } Debug.WriteLine(String.Format("Mapping dir {0} to {1}", dirs[0], dirs[1])); dirMapping.Add(dirs); } break; case InterpreterOptions: interpreterOptions = setting[1]; break; case AttachRunning: attachRunning = Convert.ToBoolean(setting[1]); break; case EnableDjangoDebugging: if (Boolean.TryParse(setting[1], out value) && value) { debugOptions |= JDebugOptions.DjangoDebugging; } break; } } } } Guid processId; if (attachRunning && Guid.TryParse(exe, out processId)) { _process = DebugConnectionListener.GetProcess(processId); _attached = true; _pseudoAttach = true; } else { _process = new JProcess(version, exe, args, dir, env, interpreterOptions, debugOptions, dirMapping); } _programCreated = false; _loadComplete.Reset(); if (!attachRunning) { _process.Start(false); } AttachEvents(_process); AD_PROCESS_ID adProcessId = new AD_PROCESS_ID(); adProcessId.ProcessIdType = (uint)enum_AD_PROCESS_ID.AD_PROCESS_ID_SYSTEM; adProcessId.dwProcessId = (uint)_process.Id; EngineUtils.RequireOk(port.GetProcess(adProcessId, out process)); Debug.WriteLine("JEngine LaunchSuspended returning S_OK"); Debug.Assert(process != null); Debug.Assert(!_process.HasExited); return VSConstants.S_OK; }
private void AttachEvents(JProcess process) { process.ProcessLoaded += OnProcessLoaded; process.ModuleLoaded += OnModuleLoaded; process.ThreadCreated += OnThreadCreated; process.BreakpointBindFailed += OnBreakpointBindFailed; process.BreakpointBindSucceeded += OnBreakpointBindSucceeded; process.BreakpointHit += OnBreakpointHit; process.AsyncBreakComplete += OnAsyncBreakComplete; process.ExceptionRaised += OnExceptionRaised; process.ProcessExited += OnProcessExited; process.StepComplete += OnStepComplete; process.ThreadExited += OnThreadExited; process.DebuggerOutput += OnDebuggerOutput; process.StartListening(); }