Index: packages/Python/lldbsuite/test/tools/lldb-mi/breakpoint/TestMiBreak.py =================================================================== --- packages/Python/lldbsuite/test/tools/lldb-mi/breakpoint/TestMiBreak.py +++ packages/Python/lldbsuite/test/tools/lldb-mi/breakpoint/TestMiBreak.py @@ -44,6 +44,69 @@ "=breakpoint-modified,bkpt={number=\"1\",type=\"breakpoint\",disp=\"keep\",enabled=\"y\",addr=\"(?!0xffffffffffffffff)0x[0-9a-f]+\",func=\".+?\",file=\".+?\",fullname=\".+?\",line=\"(-1|\d+)\",pending=\[\"printf\"\],times=\"0\",original-location=\"printf\"}") self.expect("\*stopped,reason=\"breakpoint-hit\"") + @skipIfWindows # llvm.org/pr24452: Get lldb-mi tests working on Windows + @skipIfFreeBSD # llvm.org/pr22411: Failure presumably due to known thread races + @expectedFlakeyLinux("llvm.org/pr24717") + @skipIfRemote # We do not currently support remote debugging via the MI. + def test_lldbmi_break_insert_enable_pending(self): + """Test that 'lldb-mi --interpreter' works for enabling pending breakpoints globally.""" + + self.spawnLldbMi(args=None) + + self.runCmd("-file-exec-and-symbols %s" % self.myexe) + self.expect("\^done") + + self.runCmd("-break-insert printf") + self.expect( + "\^error,msg=\"Command 'break-insert'. Breakpoint location 'printf' not found\"") + self.runCmd("-gdb-set breakpoint pending on") + self.expect("\^done") + self.runCmd("-gdb-show breakpoint pending") + self.expect("\^done,value=\"on\"") + self.runCmd("-break-insert printf") + self.expect( + "\^done,bkpt={number=\"2\",type=\"breakpoint\",disp=\"keep\",enabled=\"y\",addr=\"0xffffffffffffffff\",func=\"\?\?\",file=\"\?\?\",fullname=\"\?\?/\?\?\",line=\"0\",pending=\[\"printf\"\],times=\"0\",original-location=\"printf\"}") + self.expect( + "=breakpoint-modified,bkpt={number=\"2\",type=\"breakpoint\",disp=\"keep\",enabled=\"y\",addr=\"0xffffffffffffffff\",func=\"\?\?\",file=\"\?\?\",fullname=\"\?\?/\?\?\",line=\"0\",pending=\[\"printf\"\],times=\"0\",original-location=\"printf\"}") + + self.runCmd("-exec-run") + self.expect("\^running") + self.expect( + "=breakpoint-modified,bkpt={number=\"2\",type=\"breakpoint\",disp=\"keep\",enabled=\"y\",addr=\"(?!0xffffffffffffffff)0x[0-9a-f]+\",func=\".+?\",file=\".+?\",fullname=\".+?\",line=\"(-1|\d+)\",pending=\[\"printf\"\],times=\"0\",original-location=\"printf\"}") + self.expect("\*stopped,reason=\"breakpoint-hit\"") + self.runCmd("-break-disable 2") + self.expect("\^done") + self.expect( + "=breakpoint-modified,bkpt={number=\"2\",type=\"breakpoint\",disp=\"keep\",enabled=\"n\",addr=\"(?!0xffffffffffffffff)0x[0-9a-f]+\",func=\".+?\",file=\".+?\",fullname=\".+?\",line=\"(-1|\d+)\",pending=\[\"printf\"\],times=\"1\",original-location=\"printf\"}") + self.runCmd("-exec-continue") + self.expect("\^running") + self.expect("\*stopped,reason=\"exited-normally\"") + + # Test that it can be turned back off + self.runCmd("-file-exec-and-symbols %s" % self.myexe) + self.expect("\^done") + self.runCmd("-gdb-show breakpoint pending") + self.expect("\^done,value=\"on\"") + self.runCmd("-gdb-set breakpoint pending off") + self.expect("\^done") + self.runCmd("-gdb-show breakpoint pending") + self.expect("\^done,value=\"off\"") + self.runCmd("-break-insert printf") + self.expect( + "\^error,msg=\"Command 'break-insert'. Breakpoint location 'printf' not found\"") + # Check that enable/disable with 1 and 0 works + self.runCmd("-gdb-set breakpoint pending 1") + self.expect("\^done") + self.runCmd("-gdb-show breakpoint pending") + self.expect("\^done,value=\"on\"") + self.runCmd("-gdb-set breakpoint pending 0") + self.expect("\^done") + self.runCmd("-gdb-show breakpoint pending") + self.expect("\^done,value=\"off\"") + self.runCmd("-gdb-set breakpoint pending garbage") + self.expect("\^done") + + @skipIfWindows # llvm.org/pr24452: Get lldb-mi tests working on Windows @skipIfFreeBSD # llvm.org/pr22411: Failure presumably due to known thread races @skipIfRemote # We do not currently support remote debugging via the MI. Index: tools/lldb-mi/MICmdCmdBreak.cpp =================================================================== --- tools/lldb-mi/MICmdCmdBreak.cpp +++ tools/lldb-mi/MICmdCmdBreak.cpp @@ -165,8 +165,15 @@ if (sbTarget == rSessionInfo.GetDebugger().GetDummyTarget()) m_bBrkPtIsPending = true; - else + else { m_bBrkPtIsPending = pArgPendingBrkPt->GetFound(); + if (!m_bBrkPtIsPending) { + CMIUtilString pending; + if (m_rLLDBDebugSessionInfo.SharedDataRetrieve("breakpoint.pending", pending)) { + m_bBrkPtIsPending = pending == "on"; + } + } + } if (pArgLocation->GetFound()) m_brkName = pArgLocation->GetValue(); Index: tools/lldb-mi/MICmdCmdGdbSet.h =================================================================== --- tools/lldb-mi/MICmdCmdGdbSet.h +++ tools/lldb-mi/MICmdCmdGdbSet.h @@ -80,6 +80,7 @@ bool OptionFnSolibSearchPath(const CMIUtilString::VecString_t &vrWords); bool OptionFnOutputRadix(const CMIUtilString::VecString_t &vrWords); bool OptionFnDisassemblyFlavor(const CMIUtilString::VecString_t &vrWords); + bool OptionFnBreakpoint(const CMIUtilString::VecString_t &vrWords); bool OptionFnFallback(const CMIUtilString::VecString_t &vrWords); // Attributes: Index: tools/lldb-mi/MICmdCmdGdbSet.cpp =================================================================== --- tools/lldb-mi/MICmdCmdGdbSet.cpp +++ tools/lldb-mi/MICmdCmdGdbSet.cpp @@ -28,7 +28,8 @@ {"output-radix", &CMICmdCmdGdbSet::OptionFnOutputRadix}, {"solib-search-path", &CMICmdCmdGdbSet::OptionFnSolibSearchPath}, {"disassembly-flavor", &CMICmdCmdGdbSet::OptionFnDisassemblyFlavor}, - {"fallback", &CMICmdCmdGdbSet::OptionFnFallback}}; + {"fallback", &CMICmdCmdGdbSet::OptionFnFallback}, + {"breakpoint", &CMICmdCmdGdbSet::OptionFnBreakpoint}}; //++ //------------------------------------------------------------------------------------ @@ -431,6 +432,53 @@ return MIstatus::success; } +//++ +//------------------------------------------------------------------------------------ +// Details: Carry out work to complete the GDB set option 'breakpoint' to +// prepare +// and send back information asked for. +// Type: Method. +// Args: vrWords - (R) List of additional parameters used by this option. +// Return: MIstatus::success - Function succeeded. +// MIstatus::failure - Function failed. +// Throws: None. +//-- +bool CMICmdCmdGdbSet::OptionFnBreakpoint( + const CMIUtilString::VecString_t &vrWords) { + bool bPending = false; + bool bOk = true; + + if (vrWords.size() != 2) + // Wrong number of arguments. + bOk = false; + else if (CMIUtilString::Compare(vrWords[0], "pending") && (CMIUtilString::Compare(vrWords[1], "on") || CMIUtilString::Compare(vrWords[1], "1"))) + bPending = true; + else if (CMIUtilString::Compare(vrWords[0], "pending") && (CMIUtilString::Compare(vrWords[1], "off") || CMIUtilString::Compare(vrWords[1], "0"))) + bPending = false; + else + // Unrecognized argument(s). + bOk = false; + + if (!bOk) { + // Report error. + m_bGbbOptionFnHasError = false; + SetError(MIRSRC(IDS_CMD_ERR_GDBSET_OPT_BREAKPOINT)); + return MIstatus::failure; + } + + CMIUtilString sPendingVal = bPending ? "on" : "off"; + CMIUtilString sKey = "breakpoint.pending"; + if (!m_rLLDBDebugSessionInfo.SharedDataAdd(sKey, sPendingVal)) { + m_bGbbOptionFnHasError = false; + SetError(CMIUtilString::Format(MIRSRC(IDS_DBGSESSION_ERR_SHARED_DATA_ADD), + m_cmdData.strMiCmd.c_str(), + sKey.c_str())); + return MIstatus::failure; + } + + return MIstatus::success; +} + //++ //------------------------------------------------------------------------------------ // Details: Carry out work to complete the GDB set option to prepare and send Index: tools/lldb-mi/MICmdCmdGdbShow.h =================================================================== --- tools/lldb-mi/MICmdCmdGdbShow.h +++ tools/lldb-mi/MICmdCmdGdbShow.h @@ -80,6 +80,7 @@ bool OptionFnLanguage(const CMIUtilString::VecString_t &vrWords); bool OptionFnDisassemblyFlavor(const CMIUtilString::VecString_t &vrWords); bool OptionFnFallback(const CMIUtilString::VecString_t &vrWords); + bool OptionFnBreakpoint(const CMIUtilString::VecString_t &vrWords); // Attributes: private: Index: tools/lldb-mi/MICmdCmdGdbShow.cpp =================================================================== --- tools/lldb-mi/MICmdCmdGdbShow.cpp +++ tools/lldb-mi/MICmdCmdGdbShow.cpp @@ -32,7 +32,8 @@ {"print", &CMICmdCmdGdbShow::OptionFnPrint}, {"language", &CMICmdCmdGdbShow::OptionFnLanguage}, {"disassembly-flavor", &CMICmdCmdGdbShow::OptionFnDisassemblyFlavor}, - {"fallback", &CMICmdCmdGdbShow::OptionFnFallback}}; + {"fallback", &CMICmdCmdGdbShow::OptionFnFallback}, + {"breakpoint", &CMICmdCmdGdbShow::OptionFnBreakpoint}}; //++ //------------------------------------------------------------------------------------ @@ -347,6 +348,40 @@ return MIstatus::success; } +//++ +//------------------------------------------------------------------------------------ +// Details: Carry out work to complete the GDB show option 'breakpoint' to prepare +// and send back the requested information. +// Type: Method. +// Args: vrWords - (R) List of additional parameters used by this option. +// Return: MIstatus::success - Function succeeded. +// MIstatus::failure - Function failed. +// Throws: None. +//-- +bool CMICmdCmdGdbShow::OptionFnBreakpoint(const CMIUtilString::VecString_t &vrWords) { + if (vrWords.size() != 1) { + m_bGbbOptionFnHasError = true; + m_strGdbOptionFnError = MIRSRC(IDS_CMD_ERR_GDBSHOW_OPT_BREAKPOINT_BAD_ARGS); + return MIstatus::failure; + } + + const CMIUtilString strOption(vrWords[0]); + if (CMIUtilString::Compare(strOption, "pending")) { + if (!m_rLLDBDebugSessionInfo.SharedDataRetrieve("breakpoint.pending", m_strValue)) { + if (m_strValue.empty()) + m_strValue = "off"; + } + } else { + m_bGbbOptionFnHasError = true; + m_strGdbOptionFnError = CMIUtilString::Format( + MIRSRC(IDS_CMD_ERR_GDBSHOW_OPT_BREAKPOINT_UNKNOWN_OPTION), + strOption.c_str()); + return MIstatus::failure; + } + + return MIstatus::success; +} + //++ //------------------------------------------------------------------------------------ // Details: Carry out work to complete the GDB show option to prepare and send Index: tools/lldb-mi/MICmnResources.h =================================================================== --- tools/lldb-mi/MICmnResources.h +++ tools/lldb-mi/MICmnResources.h @@ -264,11 +264,14 @@ IDS_CMD_ERR_INFO_PRINTFN_NOT_FOUND, IDS_CMD_ERR_INFO_PRINTFN_FAILED, IDS_CMD_ERR_GDBSET_OPT_TARGETASYNC, + IDS_CMD_ERR_GDBSET_OPT_BREAKPOINT, IDS_CMD_ERR_GDBSET_OPT_SOLIBSEARCHPATH, IDS_CMD_ERR_GDBSET_OPT_PRINT_BAD_ARGS, IDS_CMD_ERR_GDBSET_OPT_PRINT_UNKNOWN_OPTION, IDS_CMD_ERR_GDBSHOW_OPT_PRINT_BAD_ARGS, IDS_CMD_ERR_GDBSHOW_OPT_PRINT_UNKNOWN_OPTION, + IDS_CMD_ERR_GDBSHOW_OPT_BREAKPOINT_BAD_ARGS, + IDS_CMD_ERR_GDBSHOW_OPT_BREAKPOINT_UNKNOWN_OPTION, IDS_CMD_ERR_EXPR_INVALID, IDS_CMD_ERR_ATTACH_FAILED, IDS_CMD_ERR_ATTACH_BAD_ARGS Index: tools/lldb-mi/MICmnResources.cpp =================================================================== --- tools/lldb-mi/MICmnResources.cpp +++ tools/lldb-mi/MICmnResources.cpp @@ -439,6 +439,8 @@ {IDS_CMD_ERR_INFO_PRINTFN_FAILED, "The request '%s' failed."}, {IDS_CMD_ERR_GDBSET_OPT_TARGETASYNC, "'target-async' expects \"on\" or \"off\""}, + {IDS_CMD_ERR_GDBSET_OPT_BREAKPOINT, + "'breakpoint' expects \"pending on\" or \"pending off\""}, {IDS_CMD_ERR_GDBSET_OPT_SOLIBSEARCHPATH, "'solib-search-path' requires at least one argument"}, {IDS_CMD_ERR_GDBSET_OPT_PRINT_BAD_ARGS, @@ -449,6 +451,10 @@ "'print' expects option-name and \"on\" or \"off\""}, {IDS_CMD_ERR_GDBSHOW_OPT_PRINT_UNKNOWN_OPTION, "'print' error. The option '%s' not found"}, + {IDS_CMD_ERR_GDBSHOW_OPT_BREAKPOINT_BAD_ARGS, + "'breakpoint' expects option-name"}, + {IDS_CMD_ERR_GDBSHOW_OPT_BREAKPOINT_UNKNOWN_OPTION, + "'breakpoint' error. The option '%s' not found"}, {IDS_CMD_ERR_EXPR_INVALID, "Failed to evaluate expression: %s"}, {IDS_CMD_ERR_ATTACH_FAILED, "Command '%s'. Attach to process failed: %s"},