Index: test/tools/lldb-mi/control/TestMiExec.py =================================================================== --- test/tools/lldb-mi/control/TestMiExec.py +++ test/tools/lldb-mi/control/TestMiExec.py @@ -12,6 +12,25 @@ @lldbmi_test @skipIfWindows #llvm.org/pr24452: Get lldb-mi tests working on Windows + @skipIfFreeBSD # Failure presumably due to StopAtEntry most likely not implemented + def test_lldbmi_exec_run(self): + """Test that 'lldb-mi --interpreter' can stop at entry.""" + + self.spawnLldbMi(args = None) + + # Load executable + self.runCmd("-file-exec-and-symbols %s" % self.myexe) + self.expect("\^done") + + # Test that program is stopped at entry + self.runCmd("-exec-run --start") + self.expect("\^running") + self.expect("\*stopped,reason=\"signal-received\",signal-name=\"SIGSTOP\",signal-meaning=\"Stop\",.*?thread-id=\"1\",stopped-threads=\"all\"") + # Test that lldb-mi is ready to execute next commands + self.expect(self.child_prompt, exactly = True) + + @lldbmi_test + @skipIfWindows #llvm.org/pr24452: Get lldb-mi tests working on Windows @skipIfFreeBSD # llvm.org/pr22411: Failure presumably due to known thread races @expectedFailureAll("llvm.org/pr23139", oslist=["linux"], compiler="gcc", compiler_version=[">=","4.9"], archs=["i386"]) def test_lldbmi_exec_abort(self): Index: tools/lldb-mi/MICmdCmdExec.h =================================================================== --- tools/lldb-mi/MICmdCmdExec.h +++ tools/lldb-mi/MICmdCmdExec.h @@ -55,6 +55,7 @@ // From CMICmdInvoker::ICmd bool Execute() override; bool Acknowledge() override; + bool ParseArgs() override; // From CMICmnBase /* dtor */ ~CMICmdCmdExecRun() override; @@ -61,6 +62,7 @@ // Attributes: private: lldb::SBCommandReturnObject m_lldbResult; + const CMIUtilString m_constStrArgStart; // StopAtEntry - run to first instruction or main(), just run process if not specified }; //++ ============================================================================ Index: tools/lldb-mi/MICmdCmdExec.cpp =================================================================== --- tools/lldb-mi/MICmdCmdExec.cpp +++ tools/lldb-mi/MICmdCmdExec.cpp @@ -48,6 +48,7 @@ // Throws: None. //-- CMICmdCmdExecRun::CMICmdCmdExecRun() + : m_constStrArgStart("start") { // Command factory matches this name with that received from the stdin stream m_strMiCmd = "exec-run"; @@ -68,6 +69,23 @@ } //++ ------------------------------------------------------------------------------------ +// Details: The invoker requires this function. The parses the command line options +// arguments to extract values for each of those arguments. +// Type: Overridden. +// Args: None. +// Return: MIstatus::success - Functional succeeded. +// MIstatus::failure - Functional failed. +// Throws: None. +//-- +bool +CMICmdCmdExecRun::ParseArgs() +{ + m_setCmdArgs.Add( + new CMICmdArgValOptionLong(m_constStrArgStart, false, true, CMICmdArgValListBase::eArgValType_OptionLong, 0)); + return ParseValidateCmdOptions(); +} + +//++ ------------------------------------------------------------------------------------ // Details: The invoker requires this function. The command does work in this function. // The command is likely to communicate with the LLDB SBDebugger in here. // Type: Overridden. @@ -84,6 +102,15 @@ lldb::SBStream errMsg; lldb::SBLaunchInfo launchInfo = rSessionInfo.GetTarget().GetLaunchInfo(); launchInfo.SetListener(rSessionInfo.GetListener()); + + CMICMDBASE_GETOPTION(pArgStart, OptionLong, m_constStrArgStart); + + // Run to first instruction or main() requested ? + if (pArgStart->GetFound()) + { + launchInfo.SetLaunchFlags(launchInfo.GetLaunchFlags() | lldb::eLaunchFlagStopAtEntry); + } + lldb::SBProcess process = rSessionInfo.GetTarget().Launch(launchInfo, error); if ((!process.IsValid()) || (error.Fail())) { Index: tools/lldb-mi/MICmdCmdSupportList.cpp =================================================================== --- tools/lldb-mi/MICmdCmdSupportList.cpp +++ tools/lldb-mi/MICmdCmdSupportList.cpp @@ -71,8 +71,13 @@ bool CMICmdCmdSupportListFeatures::Acknowledge() { - const CMICmnMIValueConst miValueConst("data-read-memory-bytes"); - const CMICmnMIValueList miValueList(miValueConst); + // Declare supported features here + const CMICmnMIValueConst miValueConst1("data-read-memory-bytes"); + const CMICmnMIValueConst miValueConst2("exec-run-start-option"); + CMICmnMIValueList miValueList(true); + // Some features may depend on host or/and target, decide what to add below + miValueList.Add(miValueConst1); + miValueList.Add(miValueConst2); const CMICmnMIValueResult miValueResult("features", miValueList); const CMICmnMIResultRecord miRecordResult(m_cmdData.strMiCmdToken, CMICmnMIResultRecord::eResultClass_Done, miValueResult); m_miResultRecord = miRecordResult;