/// <summary> /// Engines notify the debugger about the results of a symbol search by sending an instance of IDebugSymbolSearchEvent2. /// Not used. /// </summary> /// <param name="module"></param> /// <param name="status"></param> /// <param name="dwStatusFlags"></param> public void OnSymbolSearch(AD7Module module, string status, uint dwStatusFlags) { string statusString = (dwStatusFlags == 1 ? "Symbols Loaded - " : "No symbols loaded") + status; AD7SymbolSearchEvent eventObject = new AD7SymbolSearchEvent(module, statusString, dwStatusFlags); Send(eventObject, AD7SymbolSearchEvent.IID, null); }
/// <summary> /// The VSNDK debug engine does not support binding breakpoints as modules load since the primary exe is the only module /// symbols are loaded for. A production debugger will need to bind breakpoints when a new module is loaded. /// </summary> /// <param name="debuggedModule"> A module loaded in the debugged process. </param> public void OnModuleLoad(AD7Module debuggedModule) { // AD7Module ad7Module = new AD7Module(debuggedModule); AD7ModuleLoadEvent eventObject = new AD7ModuleLoadEvent(debuggedModule, true /* this is a module load */); // debuggedModule.Client = ad7Module; Send(eventObject, AD7ModuleLoadEvent.IID, null); }
/// <summary> /// Constructor. /// </summary> /// <param name="module"> The AD7Module object representing the module for which the symbols were loaded. </param> /// <param name="searchInfo"> The string containing any error messages from the module. </param> /// <param name="symbolFlags"> A combination of flags from the MODULE_INFO_FLAGS enumeration indicating whether any /// symbols were loaded. </param> public AD7SymbolSearchEvent(AD7Module module, string searchInfo, uint symbolFlags) { m_module = module; m_searchInfo = searchInfo; m_symbolFlags = symbolFlags; }
/// <summary> /// Constructor. /// </summary> /// <param name="module"> The IDebugModule2 object that represents the module which is loading or unloading. </param> /// <param name="fLoad"> onzero (TRUE) if the module is loading and zero (FALSE) if the module is unloading. </param> public AD7ModuleLoadEvent(AD7Module module, bool fLoad) { m_module = module; m_fLoad = fLoad; }
/// <summary> /// Sends the event. /// </summary> /// <param name="engine"> The AD7Engine object that represents the DE. </param> /// <param name="aModule"> The IDebugModule2 object that represents the module which is loading or unloading. </param> /// <param name="fLoad"> onzero (TRUE) if the module is loading and zero (FALSE) if the module is unloading. </param> internal static void Send(AD7Engine engine, AD7Module aModule, bool fLoad) { var eventObject = new AD7ModuleLoadEvent(aModule, fLoad); engine.Callback.Send(eventObject, IID, null); }
/// <summary> /// Attach the debug engine to a program. (http://msdn.microsoft.com/en-us/library/bb145136.aspx) /// </summary> /// <param name="rgpPrograms"> Represent programs to be attached to. These are port programs. </param> /// <param name="rgpProgramNodes"> Represent program nodes, one for each program. The program nodes in this array represent /// the same programs as in pProgram. The program nodes are given so that the DE can identify the programs to attach to. </param> /// <param name="aCeltPrograms"> Number of programs and/or program nodes in the pProgram and rgpProgramNodes arrays. </param> /// <param name="ad7Callback"> The IDebugEventCallback2 object to be used to send debug events to the SDM. </param> /// <param name="dwReason"> A value from the ATTACH_REASON enumeration that specifies the reason for attaching these programs. </param> /// <returns> If successful, returns S_OK; otherwise, returns an error code. </returns> int IDebugEngine2.Attach(IDebugProgram2[] rgpPrograms, IDebugProgramNode2[] rgpProgramNodes, uint aCeltPrograms, IDebugEventCallback2 ad7Callback, enum_ATTACH_REASON dwReason) { if (aCeltPrograms != 1) { System.Diagnostics.Debug.Fail("VSNDK Debugger only supports one debug target at a time."); throw new ArgumentException(); } try { EngineUtils.RequireOk(rgpPrograms[0].GetProgramId(out m_programGUID)); m_program = rgpPrograms[0]; // It is NULL when the user attached the debugger to a running process (by using Attach to Process UI). When that // happens, some objects must be instantiated, as well as GDB must be launched. Those ones are instantiated/launched // by LaunchSuspended and ResumeProcess methods when debugging an open project. if (this.m_engineCallback == null) { VSNDK.Package.ControlDebugEngine.isDebugEngineRunning = true; m_engineCallback = new EngineCallback(this, ad7Callback); AD7ProgramNodeAttach pnt = (AD7ProgramNodeAttach)m_program; m_process = pnt.m_process; AD7Port port = pnt.m_process._portAttach; string publicKeyPath = Environment.GetEnvironmentVariable("AppData") + @"\BlackBerry\bbt_id_rsa.pub"; string progName = pnt.m_programName.Substring(pnt.m_programName.LastIndexOf('/') + 1); string exePath = ""; string processesPaths = ""; System.IO.StreamReader readProcessesPathsFile = null; // Read the file ProcessesPath.txt to try to get the file location of the executable file. try { readProcessesPathsFile = new System.IO.StreamReader(System.Environment.GetFolderPath(Environment.SpecialFolder.LocalApplicationData) + @"\Research In Motion\ProcessesPath.txt"); processesPaths = readProcessesPathsFile.ReadToEnd(); readProcessesPathsFile.Close(); } catch (Exception e) { processesPaths = ""; } string searchProgName = progName + "_" + port.m_isSimulator; int begin = processesPaths.IndexOf(searchProgName + ":>"); if (begin != -1) { begin += searchProgName.Length + 2; int end = processesPaths.IndexOf("\r\n", begin); exePath = processesPaths.Substring(begin, end - begin) + progName; } else { exePath = "CannotAttachToRunningProcess"; } exePath = exePath.Replace("\\", "\\\\\\\\"); if (GDBParser.LaunchProcess(pnt.m_programID, exePath, port.m_IP, port.m_isSimulator, port.m_toolsPath, publicKeyPath, port.m_password)) { if (exePath == "CannotAttachToRunningProcess") { MessageBox.Show(progName + " is attached to the debugger. However, to be able to debug your application, you must build and deploy it from this computer first.", "No executable file with symbols found.", MessageBoxButtons.OK, MessageBoxIcon.Warning); } m_eventDispatcher = new EventDispatcher(this); m_module = new AD7Module(); m_progNode = new AD7ProgramNode(m_process._processGUID, m_process._processID, exePath, new Guid(AD7Engine.Id)); AddThreadsToProgram(); } else { GDBParser.exitGDB(); VSNDK.Package.ControlDebugEngine.isDebugEngineRunning = false; return VSConstants.E_FAIL; } } AD7EngineCreateEvent.Send(this); AD7ProgramCreateEvent.Send(this); AD7ModuleLoadEvent.Send(this, m_module, true); AD7LoadCompleteEvent.Send(this, currentThread()); // If the reason for attaching is ATTACH_REASON_LAUNCH, the DE needs to send the IDebugEntryPointEvent2 event. // See http://msdn.microsoft.com/en-us/library/bb145136%28v=vs.100%29.aspx if (dwReason == enum_ATTACH_REASON.ATTACH_REASON_LAUNCH) { AD7EntryPointEvent ad7Event = new AD7EntryPointEvent(); Guid riidEvent = new Guid(AD7EntryPointEvent.IID); uint attributes = (uint)enum_EVENTATTRIBUTES.EVENT_STOPPING | (uint)enum_EVENTATTRIBUTES.EVENT_SYNCHRONOUS; int rc = ad7Callback.Event(this, null, m_program, currentThread(), ad7Event, ref riidEvent, attributes); Debug.Assert(rc == VSConstants.S_OK); } } catch (Exception e) { return EngineUtils.UnexpectedException(e); } return VSConstants.S_OK; }
/// <summary> /// 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 the VSNDK Debug Engine sends in this fashion is Program Destroy. /// It responds to that event by shutting down the engine. (http://msdn.microsoft.com/en-us/library/bb160915.aspx) /// </summary> /// <param name="eventObject"> Represents the previously sent synchronous event from which the debugger should now continue. </param> /// <returns> If successful, returns S_OK; otherwise, returns an error code. </returns> int IDebugEngine2.ContinueFromSynchronousEvent(IDebugEvent2 eventObject) { try { if (eventObject is AD7ProgramDestroyEvent) { resetStackFrames(); m_process.Detach(); m_process = null; m_program.Detach(); m_program = null; m_engineCallback = null; m_breakpointManager = null; m_docContext = null; m_eventDispatcher = null; m_module = null; m_progNode = null; m_programGUID = Guid.Empty; m_threads = null; GC.Collect(); } else { Debug.Fail("Unknown synchronous event"); } } catch (Exception e) { return EngineUtils.UnexpectedException(e); } if (m_eventDispatcher != null) m_eventDispatcher.continueExecution(); return VSConstants.S_OK; }
public AD7SymbolSearchEvent(AD7Module module, string searchInfo, uint symbolFlags) { m_module = module; m_searchInfo = searchInfo; m_symbolFlags = symbolFlags; }
/// <summary> /// Launches a process by means of the debug engine. (http://msdn.microsoft.com/en-us/library/bb146223.aspx) /// </summary> /// <param name="pszServer"> The name of the machine in which to launch the process. Use a null value to specify the local /// machine. Or it should be the name of the server? </param> /// <param name="port"> The IDebugPort2 interface representing the port that the program will run in. </param> /// <param name="exe"> The name of the executable to be launched. </param> /// <param name="args"> The arguments to pass to the executable. May be a null value if there are no arguments. </param> /// <param name="dir"> The name of the working directory used by the executable. May be a null value if no working directory is /// required. </param> /// <param name="env"> Environment block of NULL-terminated strings, followed by an additional NULL terminator. </param> /// <param name="options"> The options for the executable. </param> /// <param name="launchFlags"> Specifies the LAUNCH_FLAGS for a session. </param> /// <param name="hStdInput"> Handle to an alternate input stream. May be 0 if redirection is not required. </param> /// <param name="hStdOutput"> Handle to an alternate output stream. May be 0 if redirection is not required. </param> /// <param name="hStdError"> Handle to an alternate error output stream. May be 0 if redirection is not required. </param> /// <param name="ad7Callback"> The IDebugEventCallback2 object that receives debugger events. </param> /// <param name="process"> Returns the resulting IDebugProcess2 object that represents the launched process. </param> /// <returns> If successful, returns S_OK; otherwise, returns an error code. </returns> 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.Assert(m_programGUID == Guid.Empty); process = null; try { VSNDK.Package.ControlDebugEngine.isDebugEngineRunning = true; m_engineCallback = new EngineCallback(this, ad7Callback); // Read arguments back from the args string var nvc = new NameValueCollection(); NameValueCollectionHelper.LoadFromString(nvc, args); string pid = nvc.GetValues("pid")[0]; string exePath = exe; string targetIP = nvc.GetValues("targetIP")[0]; bool isSimulator = Convert.ToBoolean(nvc.GetValues("isSimulator")[0]); string toolsPath = nvc.GetValues("ToolsPath")[0]; string publicKeyPath = nvc.GetValues("PublicKeyPath")[0]; string password = null; string[] passwordArray = nvc.GetValues("Password"); if (passwordArray != null) password = passwordArray[0]; if (GDBParser.LaunchProcess(pid, exePath, targetIP, isSimulator, toolsPath, publicKeyPath, password)) { process = m_process = new AD7Process(this, port); m_eventDispatcher = new EventDispatcher(this); m_programGUID = m_process._processGUID; m_module = new AD7Module(); // m_progNode = new AD7ProgramNode(m_process.PhysID, pid, exePath, new Guid(AD7Engine.Id)); m_progNode = new AD7ProgramNode(m_process._processGUID, pid, exePath, new Guid(AD7Engine.Id)); AddThreadsToProgram(); AD7EngineCreateEvent.Send(this); return VSConstants.S_OK; } else { GDBParser.exitGDB(); VSNDK.Package.ControlDebugEngine.isDebugEngineRunning = false; return VSConstants.E_FAIL; } } catch (Exception e) { return EngineUtils.UnexpectedException(e); } }
internal static void Send(AD7Engine engine, AD7Module aModule, bool fLoad) { var eventObject = new AD7ModuleLoadEvent(aModule, fLoad); engine.Callback.Send(eventObject, IID, null); }
public AD7ModuleLoadEvent(AD7Module module, bool fLoad) { m_module = module; m_fLoad = fLoad; }
/// <summary> /// Engines notify the debugger about the results of a symbol search by sending an instance of IDebugSymbolSearchEvent2. /// Not used. /// </summary> /// <param name="module"></param> /// <param name="status"></param> /// <param name="dwStatusFlags"></param> public void OnSymbolSearch(AD7Module module, string status, uint dwStatusFlags) { string statusString = (dwStatusFlags == 1 ? "Symbols Loaded - " : "No symbols loaded") + status; AD7SymbolSearchEvent eventObject = new AD7SymbolSearchEvent(module, statusString, dwStatusFlags); Send(eventObject, AD7SymbolSearchEvent.IID, null); }
/// <summary> /// The VSNDK debug engine does not support binding breakpoints as modules load since the primary exe is the only module /// symbols are loaded for. A production debugger will need to bind breakpoints when a new module is loaded. /// </summary> /// <param name="debuggedModule"> A module loaded in the debugged process. </param> public void OnModuleLoad(AD7Module debuggedModule) { // AD7Module ad7Module = new AD7Module(debuggedModule); AD7ModuleLoadEvent eventObject = new AD7ModuleLoadEvent(debuggedModule, true /* this is a module load */); // debuggedModule.Client = ad7Module; Send(eventObject, AD7ModuleLoadEvent.IID, null); }
//public void OnModuleLoad(DebuggedModule debuggedModule) public void OnModuleLoad(AD7Module debuggedModule) { // This will get called when the entrypoint breakpoint is fired because the engine sends a mod-load event // for the exe. // if (m_engine.DebuggedProcess != null) // { // Debug.Assert(GDBParser.CurrentThreadId == m_engine.DebuggedProcess.PollThreadId); // } // AD7Module ad7Module = new AD7Module(debuggedModule); AD7ModuleLoadEvent eventObject = new AD7ModuleLoadEvent(debuggedModule, true /* this is a module load */); // debuggedModule.Client = ad7Module; // The sample engine does not support binding breakpoints as modules load since the primary exe is the only module // symbols are loaded for. A production debugger will need to bind breakpoints when a new module is loaded. Send(eventObject, AD7ModuleLoadEvent.IID, null); }