/// <summary> /// Code to set the breakpoint in GDB and then confirm and set in Visual Studio /// </summary> /// <param name="command">Initial command to set the breakpoint in GDB</param> /// <param name="GDB_ID">Breakpoint ID in GDB</param> /// <param name="GDB_line">Breakpoint Line Number</param> /// <param name="GDB_filename">Breakpoint File Name</param> /// <param name="GDB_address">Breakpoint Address</param> /// <returns>true if successful.</returns> private bool setBreakpointImpl(string command1, string command2, out uint GDB_ID, out uint GDB_line, out string GDB_filename, out string GDB_address) { string response; string bpointAddress; string bpointStopPoint; GDB_ID = 0; GDB_filename = ""; GDB_address = ""; GDB_line = 0; if (VSNDK.AddIn.VSNDKAddIn.isDebugEngineRunning == true) { prepareToModifyBreakpoint(); response = GDBParser.parseCommand(command1, 6); if ((response.Contains("<PENDING>")) && (command2 != "")) response = GDBParser.parseCommand(command2, 6); if ((response.Length < 2) && (VSNDK.AddIn.VSNDKAddIn.isDebugEngineRunning == false)) { return false; } HandleBreakpoints hBreakpoints = new HandleBreakpoints(this); hBreakpoints.handle(response); GDB_ID = (uint)hBreakpoints.number; GDB_filename = hBreakpoints.FileName; GDB_address = hBreakpoints.Address; if ((GDB_address != "<PENDING>") && (GDB_address != "")) { //** Run Code to verify breakpoint stop point. bpointAddress = GDBParser.parseCommand("info b " + GDB_ID.ToString(), 18); bpointStopPoint = GDBParser.parseCommand("info line *" + bpointAddress, 18); GDB_line = (uint)Convert.ToInt64(bpointStopPoint.Trim()); } else { GDB_address = "0x0"; GDB_line = (uint)hBreakpoints.linePos; } resumeFromInterrupt(); return true; } else return false; }
public void processingGDBOutput() { // string verify = ""; while (_running) { string response = ""; while ((response = GDBParser.removeGDBResponse()) == "" && _running) { }; response = response.Replace("\r\n", "@"); // creating a char delimiter that will be used to split the response in more than one event string[] events = response.Split('@'); foreach (string ev in events) { // verify += ev; if (ev.Length > 1) // only to avoid empty events, in case there are two delimiters together. { if (m_eventDispatcher.countSIGINT > 0) if ((ev.Substring(0, 2) != "50") && (ev.Substring(0, 2) != "80")) m_eventDispatcher.countSIGINT = 0; switch (ev[0]) { case '0': // events related to starting GDB break; case '1': // not used. break; case '2': // events related to breakpoints (including breakpoint hits) m_hBreakpoints = new HandleBreakpoints(m_eventDispatcher); m_hBreakpoints.handle(ev); break; case '3': // not used. break; case '4': // events related to execution control (processes, threads, programs) 1 m_hProcExe = new HandleProcessExecution(m_eventDispatcher); m_hProcExe.handle(ev); break; case '5': // events related to execution control (processes, threads, programs and GDB Bugs) 2 m_hProcExe = new HandleProcessExecution(m_eventDispatcher); m_hProcExe.handle(ev); break; case '6': // events related to evaluating expressions break; case '7': // events related to stack frames. break; case '8': // events related to output m_hOutputs = new HandleOutputs(m_eventDispatcher); m_hOutputs.handle(ev); break; case '9': // not used. break; default: // event not parsed correctly, or not implemented completely. break; } } } } }
// Ignore "ignore" hit counts public bool ignoreHitCount(uint GDB_ID, int ignore) { ignore -= 1; if (ignore < 0) { ignore = int.MaxValue; // had to ignore the biggest number of times to keep the breakpoint enabled and to avoid stopping on it. } string cmd = @"-break-after " + GDB_ID + " " + ignore; string response = GDBParser.parseCommand(cmd, 18); if (response == "") return false; HandleBreakpoints hBreakpoints = new HandleBreakpoints(this); hBreakpoints.handle(response); return true; }
/* // Break only when hit count is equal to "count" public bool setBreakWhenHitCountEqual(ref uint GDB_ID, uint counts, string filename, uint line) { // remove breakpoint GDB_ID and insert a temporary new one. deleteBreakpoint(GDB_ID); string cmd = @"-break-insert --thread-group i1 -t -f " + filename + ":" + line; string response = GDBParser.parseCommand(cmd, 20); if (response == "") return false; HandleBreakpoints hBreakpoints = new HandleBreakpoints(this); hBreakpoints.handle(response); GDB_ID = (uint)hBreakpoints.number; ignoreHitCount(GDB_ID, counts); return true; }*/ // Set breakpoint condition public bool setBreakpointCondition(uint GDB_ID, string condition) { string cmd; if (condition != "") cmd = @"-break-condition " + GDB_ID + " " + condition; else cmd = @"-break-condition " + GDB_ID; string response = GDBParser.parseCommand(cmd, 19); if (response == "") return false; HandleBreakpoints hBreakpoints = new HandleBreakpoints(this); hBreakpoints.handle(response); return true; }
/* // Set watchpoint condition, i.e., stops when condition changes public bool setWatchpointCondition(ref uint GDB_ID, string condition) { if (condition != "") { // remove breakpoint GDB_ID and insert this new one... See the steps for creating a breakpoint. deleteBreakpoint(GDB_ID); string cmd = @"-break-watch " + condition; string response = GDBParser.parseCommand(cmd, 21); if (response == "") return false; HandleBreakpoints hBreakpoints = new HandleBreakpoints(this); hBreakpoints.handle(response); } return true; } */ public bool deleteBreakpoint(uint GDB_ID) { if (m_gdbOutput._running) { prepareToModifyBreakpoint(); string response = GDBParser.parseCommand(@"-break-delete " + GDB_ID, 7); if (response == null || response == "") { resumeFromInterrupt(); return false; } HandleBreakpoints hBreakpoints = new HandleBreakpoints(this); hBreakpoints.handle(response); uint retID = (uint)hBreakpoints.number; if (GDB_ID != retID) { resumeFromInterrupt(); return false; } resumeFromInterrupt(); } return true; }
// Enable or disable a breakpoint public bool enableBreakpoint(uint GDB_ID, bool fEnable) { prepareToModifyBreakpoint(); string inputCommand; string sEnable = "enable"; if (!fEnable) { sEnable = "disable"; } inputCommand = @"-break-" + sEnable + " " + GDB_ID; string response = GDBParser.parseCommand(inputCommand, 8); HandleBreakpoints hBreakpoints = new HandleBreakpoints(this); hBreakpoints.handle(response); uint retID = (uint)hBreakpoints.number; if (GDB_ID != retID) { resumeFromInterrupt(); return false; } resumeFromInterrupt(); return true; }
/// <summary> /// Code to set the breakpoint in GDB and then confirm and set in Visual Studio /// </summary> /// <param name="command"> Initial command to set the breakpoint in GDB, with the entire path when setting /// a breakpoint in a given line number. </param> /// <param name="command2"> Initial command to set the breakpoint in GDB, with only the file name when setting /// a breakpoint in a given line number, or "" when setting a breakpoint in a function. </param> /// <param name="GDB_ID"> Returns the breakpoint ID in GDB. </param> /// <param name="GDB_line"> Returns the breakpoint Line Number. </param> /// <param name="GDB_filename"> Returns the breakpoint File Name. </param> /// <param name="GDB_address"> Returns the Breakpoint Address. </param> /// <returns> If successful, returns true; otherwise, returns false. </returns> private bool setBreakpointImpl(string command, string command2, out uint GDB_ID, out uint GDB_line, out string GDB_filename, out string GDB_address) { string response; string bpointAddress; string bpointStopPoint; GDB_ID = 0; GDB_filename = ""; GDB_address = ""; GDB_line = 0; if (VSNDK.Package.ControlDebugEngine.isDebugEngineRunning == true) { prepareToModifyBreakpoint(); // Gets the parsed response for the GDB/MI command that inserts breakpoint in a given line or a given function. // (http://sourceware.org/gdb/onlinedocs/gdb/GDB_002fMI-Breakpoint-Commands.html) response = GDBParser.parseCommand(command, 6); if ((command2 != "") && ((response.Contains("<PENDING>")))) { response = GDBParser.parseCommand(command2, 6); } if (((response.Length < 2) && (VSNDK.Package.ControlDebugEngine.isDebugEngineRunning == false)) || (response == "Function not found!")) { resumeFromInterrupt(); return false; } HandleBreakpoints hBreakpoints = new HandleBreakpoints(this); hBreakpoints.handle(response); GDB_ID = (uint)hBreakpoints.number; GDB_filename = hBreakpoints.FileName; GDB_address = hBreakpoints.Address; if ((GDB_address != "<PENDING>") && (GDB_address != "")) { //** Run Code to verify breakpoint stop point. // Gets the parsed response for the GDB command that print information about the specified breakpoint, in this // case, only its address. (http://sourceware.org/gdb/onlinedocs/gdb/Set-Breaks.html) bpointAddress = GDBParser.parseCommand("info b " + GDB_ID.ToString(), 18); // Gets the parsed response for the GDB command that inquire what source line covers a particular address. // (http://sourceware.org/gdb/onlinedocs/gdb/Machine-Code.html) bpointStopPoint = GDBParser.parseCommand("info line *" + bpointAddress, 18); GDB_line = (uint)Convert.ToInt64(bpointStopPoint.Trim()); } else { GDB_address = "0x0"; GDB_line = (uint)hBreakpoints.linePos; } resumeFromInterrupt(); return true; } else return false; }
/// <summary> /// Set breakpoint condition in GDB. /// </summary> /// <param name="GDB_ID"> Breakpoint ID in GDB. </param> /// <param name="condition"> Condition to be set. When empty (""), means to remove any previous condition. </param> /// <returns> If successful, returns true; otherwise, returns false. </returns> public bool setBreakpointCondition(uint GDB_ID, string condition) { string cmd; // Gets the parsed response for the GDB/MI command that sets a condition to the breakpoint "GDB_ID". If there is no // condition, any previous one associated to this breakpoint will be removed. // (http://sourceware.org/gdb/onlinedocs/gdb/GDB_002fMI-Breakpoint-Commands.html) if (condition != "") cmd = @"-break-condition " + GDB_ID + " " + condition; else cmd = @"-break-condition " + GDB_ID; string response = GDBParser.parseCommand(cmd, 19); if (response == "") return false; HandleBreakpoints hBreakpoints = new HandleBreakpoints(this); hBreakpoints.handle(response); return true; }
/// <summary> /// Ignore a given number of hit counts in GDB. /// </summary> /// <param name="GDB_ID"> Breakpoint ID in GDB. </param> /// <param name="ignore"> Number of hit counts to ignore. </param> /// <returns> If successful, returns true; otherwise, returns false. </returns> public bool ignoreHitCount(uint GDB_ID, int ignore) { ignore -= 1; // The given number is decreased by one, because the VS command means to break when hit count is equal or greater // than X hits. So, the equivalent GDB command is to break after (X - 1) hit counts. if (ignore < 0) { // Had to ignore the biggest number of times to keep the breakpoint enabled and to avoid stopping on it. ignore = int.MaxValue; } // Gets the parsed response for the GDB/MI command that makes the breakpoint "GDB_ID" ignore "ignore" hit counts. // (http://sourceware.org/gdb/onlinedocs/gdb/GDB_002fMI-Breakpoint-Commands.html) string cmd = @"-break-after " + GDB_ID + " " + ignore; string response = GDBParser.parseCommand(cmd, 18); if (response == "") return false; HandleBreakpoints hBreakpoints = new HandleBreakpoints(this); hBreakpoints.handle(response); return true; }
/// <summary> /// Enable or disable a breakpoint. /// </summary> /// <param name="GDB_ID"> Breakpoint ID in GDB. </param> /// <param name="fEnable"> If true, enable the breakpoint. If false, disable it. </param> /// <returns> If successful, returns true; otherwise, returns false. </returns> public bool enableBreakpoint(uint GDB_ID, bool fEnable) { prepareToModifyBreakpoint(); string inputCommand; string sEnable = "enable"; if (!fEnable) { sEnable = "disable"; } // Gets the parsed response for the GDB/MI command that enables or disables the breakpoint "GDB_ID". // (http://sourceware.org/gdb/onlinedocs/gdb/GDB_002fMI-Breakpoint-Commands.html) inputCommand = @"-break-" + sEnable + " " + GDB_ID; string response = GDBParser.parseCommand(inputCommand, 8); HandleBreakpoints hBreakpoints = new HandleBreakpoints(this); hBreakpoints.handle(response); uint retID = (uint)hBreakpoints.number; resumeFromInterrupt(); if (GDB_ID != retID) { return false; } return true; }
/// <summary> /// Delete a breakpoint in GDB. /// </summary> /// <param name="GDB_ID"> Breakpoint ID in GDB. </param> /// <returns> If successful, returns true; otherwise, returns false. </returns> public bool deleteBreakpoint(uint GDB_ID) { if (m_gdbOutput._running) { prepareToModifyBreakpoint(); // Gets the parsed response for the GDB/MI command that deletes the breakpoint "GDB_ID". // (http://sourceware.org/gdb/onlinedocs/gdb/GDB_002fMI-Breakpoint-Commands.html) string response = GDBParser.parseCommand(@"-break-delete " + GDB_ID, 7); if (response == null || response == "") { resumeFromInterrupt(); return false; } HandleBreakpoints hBreakpoints = new HandleBreakpoints(this); hBreakpoints.handle(response); uint retID = (uint)hBreakpoints.number; resumeFromInterrupt(); if (GDB_ID != retID) { return false; } } return true; }