Index: test/tools/lldb-mi/stack/TestMiStack.py =================================================================== --- test/tools/lldb-mi/stack/TestMiStack.py +++ test/tools/lldb-mi/stack/TestMiStack.py @@ -137,9 +137,9 @@ # Test -stack-list-locals: use 1 or --all-values self.runCmd("-stack-list-locals 1") - self.expect("\^done,locals=\[{name=\"var_c\",value=\"{var_a = 10,var_b = 97 'a',inner_ = { var_d = 30 }}\"}\]") + self.expect("\^done,locals=\[{name=\"var_c\",value=\"{var_a = 10, var_b = 97 'a', inner_ = {var_d = 30}}\"}\]") self.runCmd("-stack-list-locals --all-values") - self.expect("\^done,locals=\[{name=\"var_c\",value=\"{var_a = 10,var_b = 97 'a',inner_ = { var_d = 30 }}\"}\]") + self.expect("\^done,locals=\[{name=\"var_c\",value=\"{var_a = 10, var_b = 97 'a', inner_ = {var_d = 30}}\"}\]") # Test -stack-list-locals: use 2 or --simple-values self.runCmd("-stack-list-locals 2") @@ -164,9 +164,9 @@ # Test -stack-list-locals: use 1 or --all-values self.runCmd("-stack-list-locals 1") - self.expect("\^done,locals=\[{name=\"array\",value=\"{\[0\] = 100,\[1\] = 200,\[2\] = 300}\"}\]") + self.expect("\^done,locals=\[{name=\"array\",value=\"{\[0\] = 100, \[1\] = 200, \[2\] = 300}\"}\]") self.runCmd("-stack-list-locals --all-values") - self.expect("\^done,locals=\[{name=\"array\",value=\"{\[0\] = 100,\[1\] = 200,\[2\] = 300}\"}\]") + self.expect("\^done,locals=\[{name=\"array\",value=\"{\[0\] = 100, \[1\] = 200, \[2\] = 300}\"}\]") # Test -stack-list-locals: use 2 or --simple-values self.runCmd("-stack-list-locals 2") Index: test/tools/lldb-mi/variable/TestMiVar.py =================================================================== --- test/tools/lldb-mi/variable/TestMiVar.py +++ test/tools/lldb-mi/variable/TestMiVar.py @@ -112,13 +112,13 @@ self.runCmd("-data-evaluate-expression \"argv[0]\"") self.expect("\^done,value=\"0x[0-9a-f]+\"") self.runCmd("-var-create var6 * \"argv[0]\"") - self.expect("\^done,name=\"var6\",numchild=\"1\",value=\"0x[0-9a-f]+\",type=\"const char \*\",thread-id=\"1\",has_more=\"0\"") + self.expect("\^done,name=\"var6\",numchild=\"1\",value=\"0x[0-9a-f]+ \\\\\\\".*%s\\\\\\\"\",type=\"const char \*\",thread-id=\"1\",has_more=\"0\"" % self.myexe) self.runCmd("-var-evaluate-expression var6") - self.expect("\^done,value=\"0x[0-9a-f]+\"") + self.expect("\^done,value=\"0x[0-9a-f]+ \\\\\\\".*%s\\\\\\\"\"" % self.myexe) self.runCmd("-var-show-attributes var6") self.expect("\^done,status=\"editable\"") - self.runCmd("-var-list-children var6") - #self.expect("\^done,numchild=\"1\",children=\[child=\{name=\"var6\.\*\$15\",exp=\"\*\$15\",numchild=\"0\",type=\"const char\",thread-id=\"1\",has_more=\"0\"\}\]") #FIXME -var-list-children shows invalid thread-id + self.runCmd("-var-list-children --all-values var6") + self.expect("\^done,numchild=\"1\",children=\[child=\{name=\"var6\.\*\$11\",exp=\"\*\$11\",numchild=\"0\",type=\"const char\",thread-id=\"4294967295\",value=\"47 '/'\",has_more=\"0\"\}\]") #FIXME -var-list-children shows invalid thread-id @lldbmi_test @expectedFailureWindows("llvm.org/pr22274: need a pexpect replacement for windows") @@ -147,7 +147,7 @@ self.runCmd("-var-create var_complx * complx") self.expect("\^done,name=\"var_complx\",numchild=\"3\",value=\"\{\.\.\.\}\",type=\"complex_type\",thread-id=\"1\",has_more=\"0\"") self.runCmd("-var-create var_complx_array * complx_array") - self.expect("\^done,name=\"var_complx_array\",numchild=\"2\",value=\"\{\.\.\.\}\",type=\"complex_type \[2\]\",thread-id=\"1\",has_more=\"0\"") + self.expect("\^done,name=\"var_complx_array\",numchild=\"2\",value=\"\[2\]\",type=\"complex_type \[2\]\",thread-id=\"1\",has_more=\"0\"") # Go to BP_var_update_test_l line = line_number('main.cpp', '// BP_var_update_test_l') @@ -183,7 +183,7 @@ # Test that var_complex_array was updated self.runCmd("-var-update --all-values var_complx_array") - self.expect("\^done,changelist=\[\{name=\"var_complx_array\",value=\"\{\.\.\.\}\",in_scope=\"true\",type_changed=\"false\",has_more=\"0\"\}\]") + self.expect("\^done,changelist=\[\{name=\"var_complx_array\",value=\"\[2\]\",in_scope=\"true\",type_changed=\"false\",has_more=\"0\"\}\]") if __name__ == '__main__': unittest2.main() Index: tools/lldb-mi/MICmdCmdMiscellanous.cpp =================================================================== --- tools/lldb-mi/MICmdCmdMiscellanous.cpp +++ tools/lldb-mi/MICmdCmdMiscellanous.cpp @@ -239,7 +239,7 @@ if (thread.IsValid()) { CMICmnMIValueTuple miTuple; - if (!rSessionInfo.MIResponseFormThreadInfo2(m_cmdData, thread, miTuple)) + if (!rSessionInfo.MIResponseFormThreadInfo(m_cmdData, thread, CMICmnLLDBDebugSessionInfo::eThreadInfoFormat_NoFrames, miTuple)) return MIstatus::failure; m_vecMIValueTuple.push_back(miTuple); Index: tools/lldb-mi/MICmdCmdStack.cpp =================================================================== --- tools/lldb-mi/MICmdCmdStack.cpp +++ tools/lldb-mi/MICmdCmdStack.cpp @@ -213,7 +213,7 @@ lldb::SBThread sbThread = sbProcess.GetSelectedThread(); MIuint nFrameId = sbThread.GetSelectedFrame().GetFrameID(); - if (!rSessionInfo.MIResponseFormFrameInfo(sbThread, nFrameId, m_miValueTuple)) + if (!rSessionInfo.MIResponseFormFrameInfo(sbThread, nFrameId, CMICmnLLDBDebugSessionInfo::eFrameInfoFormat_NoArguments, m_miValueTuple)) return MIstatus::failure; return MIstatus::success; @@ -356,7 +356,7 @@ for (MIuint nLevel = nFrameLow; nLevel < nThreadFrames; nLevel++) { CMICmnMIValueTuple miValueTuple; - if (!rSessionInfo.MIResponseFormFrameInfo(thread, nLevel, miValueTuple)) + if (!rSessionInfo.MIResponseFormFrameInfo(thread, nLevel, CMICmnLLDBDebugSessionInfo::eFrameInfoFormat_NoArguments, miValueTuple)) return MIstatus::failure; const CMICmnMIValueResult miValueResult8("frame", miValueTuple); Index: tools/lldb-mi/MICmdCmdThread.cpp =================================================================== --- tools/lldb-mi/MICmdCmdThread.cpp +++ tools/lldb-mi/MICmdCmdThread.cpp @@ -100,7 +100,7 @@ return MIstatus::success; CMICmnMIValueTuple miTuple; - if (!rSessionInfo.MIResponseFormThreadInfo3(m_cmdData, thread, miTuple)) + if (!rSessionInfo.MIResponseFormThreadInfo(m_cmdData, thread, CMICmnLLDBDebugSessionInfo::eThreadInfoFormat_AllFrames, miTuple)) return MIstatus::failure; m_miValueTupleThread = miTuple; @@ -117,7 +117,7 @@ if (thread.IsValid()) { CMICmnMIValueTuple miTuple; - if (!rSessionInfo.MIResponseFormThreadInfo3(m_cmdData, thread, miTuple)) + if (!rSessionInfo.MIResponseFormThreadInfo(m_cmdData, thread, CMICmnLLDBDebugSessionInfo::eThreadInfoFormat_AllFrames, miTuple)) return MIstatus::failure; m_vecMIValueTuple.push_back(miTuple); Index: tools/lldb-mi/MICmnLLDBDebugSessionInfo.h =================================================================== --- tools/lldb-mi/MICmnLLDBDebugSessionInfo.h +++ tools/lldb-mi/MICmnLLDBDebugSessionInfo.h @@ -116,6 +116,25 @@ kNumVariableInfoFormats }; + //++ =================================================================== + // Details: Determine the information that should be shown by using MIResponseFormThreadInfo family functions. + //-- + enum ThreadInfoFormat_e + { + eThreadInfoFormat_NoFrames, + eThreadInfoFormat_AllFrames + }; + + //++ =================================================================== + // Details: Determine the information that should be shown by using MIResponseFormFrameInfo family functions. + //-- + enum FrameInfoFormat_e + { + eFrameInfoFormat_NoArguments, + eFrameInfoFormat_AllArguments, + eFrameInfoFormat_AllArgumentsInSimpleForm + }; + // Typedefs: public: typedef std::vector VecActiveThreadId_t; @@ -132,25 +151,15 @@ // Common command required functionality bool AccessPath(const CMIUtilString &vPath, bool &vwbYesAccessible); - bool GetFrameInfo(const lldb::SBFrame &vrFrame, lldb::addr_t &vwPc, CMIUtilString &vwFnName, CMIUtilString &vwFileName, - CMIUtilString &vwPath, MIuint &vwnLine); - bool GetThreadFrames(const SMICmdData &vCmdData, const MIuint vThreadIdx, CMIUtilString &vwrThreadFrames); - bool GetThreadFrames2(const SMICmdData &vCmdData, const MIuint vThreadIdx, CMIUtilString &vwrThreadFrames); bool ResolvePath(const SMICmdData &vCmdData, const CMIUtilString &vPath, CMIUtilString &vwrResolvedPath); bool ResolvePath(const CMIUtilString &vstrUnknown, CMIUtilString &vwrResolvedPath); - bool MIResponseFormFrameInfo(const lldb::SBThread &vrThread, const MIuint vnLevel, CMICmnMIValueTuple &vwrMiValueTuple); - bool MIResponseFormFrameInfo(const lldb::addr_t vPc, const CMIUtilString &vFnName, const CMIUtilString &vFileName, - const CMIUtilString &vPath, const MIuint vnLine, CMICmnMIValueTuple &vwrMiValueTuple); - bool MIResponseFormFrameInfo2(const lldb::addr_t vPc, const CMIUtilString &vArgInfo, const CMIUtilString &vFnName, - const CMIUtilString &vFileName, const CMIUtilString &vPath, const MIuint vnLine, - CMICmnMIValueTuple &vwrMiValueTuple); - bool MIResponseFormThreadInfo(const SMICmdData &vCmdData, const lldb::SBThread &vrThread, CMICmnMIValueTuple &vwrMIValueTuple); - bool MIResponseFormThreadInfo2(const SMICmdData &vCmdData, const lldb::SBThread &vrThread, CMICmnMIValueTuple &vwrMIValueTuple); - bool MIResponseFormThreadInfo3(const SMICmdData &vCmdData, const lldb::SBThread &vrThread, CMICmnMIValueTuple &vwrMIValueTuple); + bool MIResponseFormFrameInfo(const lldb::SBThread &vrThread, const MIuint vnLevel, + const FrameInfoFormat_e veFrameInfoFormat, CMICmnMIValueTuple &vwrMiValueTuple); + bool MIResponseFormThreadInfo(const SMICmdData &vCmdData, const lldb::SBThread &vrThread, + const ThreadInfoFormat_e veThreadInfoFormat, CMICmnMIValueTuple &vwrMIValueTuple); bool MIResponseFormVariableInfo(const lldb::SBFrame &vrFrame, const MIuint vMaskVarTypes, - const VariableInfoFormat_e veVarInfoFormat, CMICmnMIValueList &vwrMiValueList); - bool MIResponseFormVariableInfo2(const lldb::SBFrame &vrFrame, const MIuint vMaskVarTypes, - const VariableInfoFormat_e veVarInfoFormat, CMICmnMIValueList &vwrMiValueList); + const VariableInfoFormat_e veVarInfoFormat, CMICmnMIValueList &vwrMiValueList, + const MIuint vnMaxDepth = 10); bool MIResponseFormBrkPtFrameInfo(const SBrkPtInfo &vrBrkPtInfo, CMICmnMIValueTuple &vwrMiValueTuple); bool MIResponseFormBrkPtInfo(const SBrkPtInfo &vrBrkPtInfo, CMICmnMIValueTuple &vwrMiValueTuple); bool GetBrkPtInfo(const lldb::SBBreakpoint &vBrkPt, SBrkPtInfo &vrwBrkPtInfo) const; @@ -187,8 +196,11 @@ /* ctor */ CMICmnLLDBDebugSessionInfo(const CMICmnLLDBDebugSessionInfo &); void operator=(const CMICmnLLDBDebugSessionInfo &); // - bool GetVariableInfo(const MIuint vnMaxDepth, const lldb::SBValue &vrValue, const bool vbIsChildValue, - const MIuint vnDepth, CMICmnMIValueList &vwrMiValueList); + bool GetVariableInfo(const lldb::SBValue &vrValue, const bool vbInSimpleForm, CMIUtilString &vwrStrValue); + bool GetFrameInfo(const lldb::SBFrame &vrFrame, lldb::addr_t &vwPc, CMIUtilString &vwFnName, CMIUtilString &vwFileName, + CMIUtilString &vwPath, MIuint &vwnLine); + bool GetThreadFrames(const SMICmdData &vCmdData, const MIuint vThreadIdx, const FrameInfoFormat_e veFrameInfoFormat, + CMIUtilString &vwrThreadFrames); // Overridden: private: Index: tools/lldb-mi/MICmnLLDBDebugSessionInfo.cpp =================================================================== --- tools/lldb-mi/MICmnLLDBDebugSessionInfo.cpp +++ tools/lldb-mi/MICmnLLDBDebugSessionInfo.cpp @@ -211,7 +211,8 @@ // Throws: None. //-- bool -CMICmnLLDBDebugSessionInfo::GetThreadFrames(const SMICmdData &vCmdData, const MIuint vThreadIdx, CMIUtilString &vwrThreadFrames) +CMICmnLLDBDebugSessionInfo::GetThreadFrames(const SMICmdData &vCmdData, const MIuint vThreadIdx, const FrameInfoFormat_e veFrameInfoFormat, + CMIUtilString &vwrThreadFrames) { lldb::SBThread thread = GetProcess().GetThreadByIndexID(vThreadIdx); const uint32_t nFrames = thread.GetNumFrames(); @@ -230,108 +231,8 @@ CMIUtilString strListCommaSeperated; for (MIuint nLevel = 0; nLevel < nFrames; nLevel++) { - lldb::SBFrame frame = thread.GetFrameAtIndex(nLevel); - lldb::addr_t pc = 0; - CMIUtilString fnName; - CMIUtilString fileName; - CMIUtilString path; - MIuint nLine = 0; - if (!GetFrameInfo(frame, pc, fnName, fileName, path, nLine)) - return MIstatus::failure; - - // Function args - CMICmnMIValueList miValueList(true); - const MIuint maskVarTypes = eVariableType_Arguments; - if (!MIResponseFormVariableInfo(frame, maskVarTypes, eVariableInfoFormat_AllValues, miValueList)) - return MIstatus::failure; - - const MIchar *pUnknown = "??"; - if (fnName != pUnknown) - { - std::replace(fnName.begin(), fnName.end(), ')', ' '); - std::replace(fnName.begin(), fnName.end(), '(', ' '); - std::replace(fnName.begin(), fnName.end(), '\'', ' '); - } - - CMICmnMIValueTuple miValueTuple; - const CMIUtilString strLevel(CMIUtilString::Format("%d", nLevel)); - const CMICmnMIValueConst miValueConst(strLevel); - const CMICmnMIValueResult miValueResult("level", miValueConst); - miValueTuple.Add(miValueResult); - if (!MIResponseFormFrameInfo2(pc, miValueList.GetString(), fnName, fileName, path, nLine, miValueTuple)) - return MIstatus::failure; - - const CMICmnMIValueResult miValueResult2("frame", miValueTuple); - if (nLevel != 0) - strListCommaSeperated += ","; - strListCommaSeperated += miValueResult2.GetString(); - } - - vwrThreadFrames = strListCommaSeperated; - - return MIstatus::success; -} - -// Todo: Refactor maybe to so only one function with this name, but not just yet -//++ ------------------------------------------------------------------------------------ -// Details: Retrieve the specified thread's frame information. -// Type: Method. -// Args: vCmdData - (R) A command's information. -// vThreadIdx - (R) Thread index. -// vwrThreadFrames - (W) Frame data. -// Return: MIstatus::success - Functional succeeded. -// MIstatus::failure - Functional failed. -// Throws: None. -//-- -bool -CMICmnLLDBDebugSessionInfo::GetThreadFrames2(const SMICmdData &vCmdData, const MIuint vThreadIdx, CMIUtilString &vwrThreadFrames) -{ - lldb::SBThread thread = GetProcess().GetThreadByIndexID(vThreadIdx); - const uint32_t nFrames = thread.GetNumFrames(); - if (nFrames == 0) - { - // MI print "frame={}" - CMICmnMIValueTuple miValueTuple; - CMICmnMIValueResult miValueResult("frame", miValueTuple); - vwrThreadFrames = miValueResult.GetString(); - return MIstatus::success; - } - - // MI print - // "frame={level=\"%d\",addr=\"0x%016" PRIx64 "\",func=\"%s\",args=[%s],file=\"%s\",fullname=\"%s\",line=\"%d\"},frame={level=\"%d\",addr=\"0x%016" PRIx64 "\",func=\"%s\",args=[%s],file=\"%s\",fullname=\"%s\",line=\"%d\"}, - // ..." - CMIUtilString strListCommaSeperated; - for (MIuint nLevel = 0; nLevel < nFrames; nLevel++) - { - lldb::SBFrame frame = thread.GetFrameAtIndex(nLevel); - lldb::addr_t pc = 0; - CMIUtilString fnName; - CMIUtilString fileName; - CMIUtilString path; - MIuint nLine = 0; - if (!GetFrameInfo(frame, pc, fnName, fileName, path, nLine)) - return MIstatus::failure; - - // Function args - CMICmnMIValueList miValueList(true); - const MIuint maskVarTypes = eVariableType_Arguments; - if (!MIResponseFormVariableInfo2(frame, maskVarTypes, eVariableInfoFormat_AllValues, miValueList)) - return MIstatus::failure; - - const MIchar *pUnknown = "??"; - if (fnName != pUnknown) - { - std::replace(fnName.begin(), fnName.end(), ')', ' '); - std::replace(fnName.begin(), fnName.end(), '(', ' '); - std::replace(fnName.begin(), fnName.end(), '\'', ' '); - } - CMICmnMIValueTuple miValueTuple; - const CMIUtilString strLevel(CMIUtilString::Format("%d", nLevel)); - const CMICmnMIValueConst miValueConst(strLevel); - const CMICmnMIValueResult miValueResult("level", miValueConst); - miValueTuple.Add(miValueResult); - if (!MIResponseFormFrameInfo2(pc, miValueList.GetString(), fnName, fileName, path, nLine, miValueTuple)) + if (!MIResponseFormFrameInfo(thread, nLevel, veFrameInfoFormat, miValueTuple)) return MIstatus::failure; const CMICmnMIValueResult miValueResult2("frame", miValueTuple); @@ -459,14 +360,10 @@ //-- bool CMICmnLLDBDebugSessionInfo::MIResponseFormThreadInfo(const SMICmdData &vCmdData, const lldb::SBThread &vrThread, - CMICmnMIValueTuple &vwrMIValueTuple) + const ThreadInfoFormat_e veThreadInfoFormat, CMICmnMIValueTuple &vwrMIValueTuple) { lldb::SBThread &rThread = const_cast(vrThread); - CMIUtilString strFrames; - if (!GetThreadFrames(vCmdData, rThread.GetIndexID(), strFrames)) - return MIstatus::failure; - const bool bSuspended = rThread.IsSuspended(); const lldb::StopReason eReason = rThread.GetStopReason(); const bool bValidReason = !((eReason == lldb::eStopReasonNone) || (eReason == lldb::eStopReasonInvalid)); @@ -496,128 +393,16 @@ return MIstatus::failure; // Add "frame" - const CMICmnMIValueConst miValueConst3(strFrames, true); - if (!vwrMIValueTuple.Add(miValueConst3, false)) - return MIstatus::failure; - - // Add "state" - const CMICmnMIValueConst miValueConst4(strState); - const CMICmnMIValueResult miValueResult4("state", miValueConst4); - if (!vwrMIValueTuple.Add(miValueResult4)) - return MIstatus::failure; - - return MIstatus::success; -} - -// Todo: Refactor maybe to so only one function with this name, but not just yet -//++ ------------------------------------------------------------------------------------ -// Details: Form MI partial response by appending more MI value type objects to the -// tuple type object past in. -// Type: Method. -// Args: vCmdData - (R) A command's information. -// vrThread - (R) LLDB thread object. -// vwrMIValueTuple - (W) MI value tuple object. -// Return: MIstatus::success - Functional succeeded. -// MIstatus::failure - Functional failed. -// Throws: None. -//-- -bool -CMICmnLLDBDebugSessionInfo::MIResponseFormThreadInfo3(const SMICmdData &vCmdData, const lldb::SBThread &vrThread, - CMICmnMIValueTuple &vwrMIValueTuple) -{ - lldb::SBThread &rThread = const_cast(vrThread); - - CMIUtilString strFrames; - if (!GetThreadFrames2(vCmdData, rThread.GetIndexID(), strFrames)) - return MIstatus::failure; - - const bool bSuspended = rThread.IsSuspended(); - const lldb::StopReason eReason = rThread.GetStopReason(); - const bool bValidReason = !((eReason == lldb::eStopReasonNone) || (eReason == lldb::eStopReasonInvalid)); - const CMIUtilString strState((bSuspended || bValidReason) ? "stopped" : "running"); - - // Add "id" - const CMIUtilString strId(CMIUtilString::Format("%d", rThread.GetIndexID())); - const CMICmnMIValueConst miValueConst1(strId); - const CMICmnMIValueResult miValueResult1("id", miValueConst1); - if (!vwrMIValueTuple.Add(miValueResult1)) - return MIstatus::failure; - - // Add "target-id" - const MIchar *pThreadName = rThread.GetName(); - const MIuint len = (pThreadName != nullptr) ? CMIUtilString(pThreadName).length() : 0; - const bool bHaveName = ((pThreadName != nullptr) && (len > 0) && (len < 32) && - CMIUtilString::IsAllValidAlphaAndNumeric(*pThreadName)); // 32 is arbitary number - const MIchar *pThrdFmt = bHaveName ? "%s" : "Thread %d"; - CMIUtilString strThread; - if (bHaveName) - strThread = CMIUtilString::Format(pThrdFmt, pThreadName); - else - strThread = CMIUtilString::Format(pThrdFmt, rThread.GetIndexID()); - const CMICmnMIValueConst miValueConst2(strThread); - const CMICmnMIValueResult miValueResult2("target-id", miValueConst2); - if (!vwrMIValueTuple.Add(miValueResult2)) - return MIstatus::failure; - - // Add "frame" - const CMICmnMIValueConst miValueConst3(strFrames, true); - if (!vwrMIValueTuple.Add(miValueConst3, false)) - return MIstatus::failure; - - // Add "state" - const CMICmnMIValueConst miValueConst4(strState); - const CMICmnMIValueResult miValueResult4("state", miValueConst4); - if (!vwrMIValueTuple.Add(miValueResult4)) - return MIstatus::failure; - - return MIstatus::success; -} - -// Todo: Refactor maybe to so only one function with this name, but not just yet -//++ ------------------------------------------------------------------------------------ -// Details: Form MI partial response by appending more MI value type objects to the -// tuple type object past in. -// Type: Method. -// Args: vCmdData - (R) A command's information. -// vrThread - (R) LLDB thread object. -// vwrMIValueTuple - (W) MI value tuple object. -// Return: MIstatus::success - Functional succeeded. -// MIstatus::failure - Functional failed. -// Throws: None. -//-- -bool -CMICmnLLDBDebugSessionInfo::MIResponseFormThreadInfo2(const SMICmdData &vCmdData, const lldb::SBThread &vrThread, - CMICmnMIValueTuple &vwrMIValueTuple) -{ - lldb::SBThread &rThread = const_cast(vrThread); - - const bool bSuspended = rThread.IsSuspended(); - const lldb::StopReason eReason = rThread.GetStopReason(); - const bool bValidReason = !((eReason == lldb::eStopReasonNone) || (eReason == lldb::eStopReasonInvalid)); - const CMIUtilString strState((bSuspended || bValidReason) ? "stopped" : "running"); - - // Add "id" - const CMIUtilString strId(CMIUtilString::Format("%d", rThread.GetIndexID())); - const CMICmnMIValueConst miValueConst1(strId); - const CMICmnMIValueResult miValueResult1("id", miValueConst1); - if (!vwrMIValueTuple.Add(miValueResult1)) - return MIstatus::failure; + if (veThreadInfoFormat != eThreadInfoFormat_NoFrames) + { + CMIUtilString strFrames; + if (!GetThreadFrames(vCmdData, rThread.GetIndexID(), eFrameInfoFormat_AllArgumentsInSimpleForm, strFrames)) + return MIstatus::failure; - // Add "target-id" - const MIchar *pThreadName = rThread.GetName(); - const MIuint len = (pThreadName != nullptr) ? CMIUtilString(pThreadName).length() : 0; - const bool bHaveName = ((pThreadName != nullptr) && (len > 0) && (len < 32) && - CMIUtilString::IsAllValidAlphaAndNumeric(*pThreadName)); // 32 is arbitary number - const MIchar *pThrdFmt = bHaveName ? "%s" : "Thread %d"; - CMIUtilString strThread; - if (bHaveName) - strThread = CMIUtilString::Format(pThrdFmt, pThreadName); - else - strThread = CMIUtilString::Format(pThrdFmt, rThread.GetIndexID()); - const CMICmnMIValueConst miValueConst2(strThread); - const CMICmnMIValueResult miValueResult2("target-id", miValueConst2); - if (!vwrMIValueTuple.Add(miValueResult2)) - return MIstatus::failure; + const CMICmnMIValueConst miValueConst3(strFrames, true); + if (!vwrMIValueTuple.Add(miValueConst3, false)) + return MIstatus::failure; + } // Add "state" const CMICmnMIValueConst miValueConst4(strState); @@ -628,48 +413,6 @@ return MIstatus::success; } -// Todo: Refactor maybe to so only one function with this name, but not just yet -//++ ------------------------------------------------------------------------------------ -// Details: Form MI partial response by appending more MI value type objects to the -// tuple type object past in. -// Type: Method. -// Args: vrFrame - (R) LLDB thread object. -// vMaskVarTypes - (R) Construed according to VariableType_e. -// veVarInfoFormat - (R) The type of variable info that should be shown. -// vwrMIValueList - (W) MI value list object. -// Return: MIstatus::success - Functional succeeded. -// MIstatus::failure - Functional failed. -// Throws: None. -//-- -bool -CMICmnLLDBDebugSessionInfo::MIResponseFormVariableInfo2(const lldb::SBFrame &vrFrame, const MIuint vMaskVarTypes, - const VariableInfoFormat_e veVarInfoFormat, CMICmnMIValueList &vwrMiValueList) -{ - bool bOk = MIstatus::success; - lldb::SBFrame &rFrame = const_cast(vrFrame); - - const bool bArg = (vMaskVarTypes & eVariableType_Arguments); - const bool bLocals = (vMaskVarTypes & eVariableType_Locals); - const bool bStatics = (vMaskVarTypes & eVariableType_Statics); - const bool bInScopeOnly = (vMaskVarTypes & eVariableType_InScope); - lldb::SBValueList listArg = rFrame.GetVariables(bArg, bLocals, bStatics, bInScopeOnly); - const MIuint nArgs = listArg.GetSize(); - for (MIuint i = 0; bOk && (i < nArgs); i++) - { - lldb::SBValue value = listArg.GetValueAtIndex(i); - const CMICmnLLDBUtilSBValue utilValue(value); - const CMICmnMIValueConst miValueConst(utilValue.GetName()); - const CMICmnMIValueResult miValueResult("name", miValueConst); - CMICmnMIValueTuple miValueTuple(miValueResult); - const CMICmnMIValueConst miValueConst2(utilValue.GetValue()); - const CMICmnMIValueResult miValueResult2("value", miValueConst2); - miValueTuple.Add(miValueResult2); - bOk = vwrMiValueList.Add(miValueTuple); - } - - return bOk; -} - //++ ------------------------------------------------------------------------------------ // Details: Form MI partial response by appending more MI value type objects to the // tuple type object past in. @@ -684,7 +427,8 @@ //-- bool CMICmnLLDBDebugSessionInfo::MIResponseFormVariableInfo(const lldb::SBFrame &vrFrame, const MIuint vMaskVarTypes, - const VariableInfoFormat_e veVarInfoFormat, CMICmnMIValueList &vwrMiValueList) + const VariableInfoFormat_e veVarInfoFormat, CMICmnMIValueList &vwrMiValueList, + const MIuint vnMaxDepth /* = 10 */) { bool bOk = MIstatus::success; lldb::SBFrame &rFrame = const_cast(vrFrame); @@ -693,8 +437,6 @@ const bool bLocals = (vMaskVarTypes & eVariableType_Locals); const bool bStatics = (vMaskVarTypes & eVariableType_Statics); const bool bInScopeOnly = (vMaskVarTypes & eVariableType_InScope); - const MIuint nMaxRecusiveDepth = 10; - const MIuint nCurrentRecursiveDepth = 0; lldb::SBValueList listArg = rFrame.GetVariables(bArg, bLocals, bStatics, bInScopeOnly); const MIuint nArgs = listArg.GetSize(); for (MIuint i = 0; bOk && (i < nArgs); i++) @@ -711,14 +453,10 @@ (bIsPointerType && nChildren == 1) || // pointers veVarInfoFormat == eVariableInfoFormat_AllValues) // show all values { - CMICmnMIValueList miValueList(true); - if (GetVariableInfo(nMaxRecusiveDepth, value, false, nCurrentRecursiveDepth, miValueList)) + CMIUtilString strValue; + if (GetVariableInfo(value, vnMaxDepth == 0, strValue)) { - CMIUtilString valueStr = miValueList.ExtractContentNoBrackets(); - // Surround by {} if there is , inside indicating multiple values. - if (valueStr.find (',') != CMIUtilString::npos) - valueStr = CMIUtilString::Format("{%s}", valueStr.c_str()); - const CMICmnMIValueConst miValueConst2(valueStr); + const CMICmnMIValueConst miValueConst2(strValue.Escape().AddSlashes()); const CMICmnMIValueResult miValueResult2("value", miValueConst2); miValueTuple.Add(miValueResultName); // name miValueTuple.Add(miValueResult2); @@ -736,118 +474,21 @@ //++ ------------------------------------------------------------------------------------ // Details: Extract the value's name and value or recurse into child value object. // Type: Method. -// Args: vnMaxDepth - (R) The max recursive depth for this function. -// vrValue - (R) LLDB value object. -// vbIsChildValue - (R) True = Value object is a child of a higher Value object, -// - False = Value object not a child. -// vwrMIValueList - (W) MI value list object. -// vnDepth - (RW) The current recursive depth of this function. +// Args: vrValue - (R) LLDB value object. +// vbInSimpleForm - (R) True = Get variable info in simple form (i.e. don't expand aggregates). +// - False = Get variable info (and expand aggregates if any). +// vwrStrValue t - (W) The string representatin of this value. // Return: MIstatus::success - Functional succeeded. // MIstatus::failure - Functional failed. // Throws: None. //-- bool -CMICmnLLDBDebugSessionInfo::GetVariableInfo(const MIuint vnMaxDepth, const lldb::SBValue &vrValue, const bool vbIsChildValue, - const MIuint vnDepth, CMICmnMIValueList &vwrMiValueList) +CMICmnLLDBDebugSessionInfo::GetVariableInfo(const lldb::SBValue &vrValue, const bool vbInSimpleForm, CMIUtilString &vwrStrValue) { - // Check recursive depth - if (vnDepth >= vnMaxDepth) - return MIstatus::success; - - bool bOk = MIstatus::success; - lldb::SBValue &rValue = const_cast(vrValue); - const CMICmnLLDBUtilSBValue utilValue(vrValue, true); - const MIchar *pName = rValue.GetName(); - MIunused(pName); - const bool bIsPointerType = rValue.GetType().IsPointerType(); - const MIuint nChildren = rValue.GetNumChildren(); - if (nChildren == 0) - { - if (vbIsChildValue) - { - // For composite types - const CMICmnMIValueConst miValueConst( - CMIUtilString::Format("%s = %s", utilValue.GetName().c_str(), utilValue.GetValue().c_str()), true); - return vwrMiValueList.Add(miValueConst); - } - else - { - // Basic types - const CMICmnMIValueConst miValueConst(utilValue.GetValue(), true); - return vwrMiValueList.Add(miValueConst); - } - } - else if (bIsPointerType && utilValue.IsChildCharType()) - { - const CMIUtilString &rText(utilValue.GetChildValueCString()); - if (rText.empty()) - { - const CMICmnMIValueConst miValueConst(utilValue.GetValue(), true); - bOk = vwrMiValueList.Add(miValueConst); - } - else - { - if (utilValue.IsValueUnknown()) - { - const CMICmnMIValueConst miValueConst(rText, true); - bOk = vwrMiValueList.Add(miValueConst); - } - else - { - // Note code that has const in will not show the text suffix to the string pointer - // i.e. const char * pMyStr = "blah"; ==> "0x00007000"" <-- Eclipse shows this - // but char * pMyStr = "blah"; ==> "0x00007000" "blah"" <-- Eclipse shows this - const CMICmnMIValueConst miValueConst(CMIUtilString::Format("%s %s", utilValue.GetValue().c_str(), rText.c_str()), true); - bOk = vwrMiValueList.Add(miValueConst); - } - } - return bOk; - } - else if (bIsPointerType) - { - if (vbIsChildValue) - { - // For composite types - const CMICmnMIValueConst miValueConst( - CMIUtilString::Format("%s = %s", utilValue.GetName().c_str(), utilValue.GetValue().c_str()), true); - return vwrMiValueList.Add(miValueConst); - } - else - { - // Basic types - const CMICmnMIValueConst miValueConst(utilValue.GetValue(), true); - return vwrMiValueList.Add(miValueConst); - } - } - else - { - CMICmnMIValueList miValueList2(true); - // Build parent child composite types - for (MIuint i = 0; bOk && (i < nChildren); i++) - { - lldb::SBValue member = rValue.GetChildAtIndex(i); - bOk = GetVariableInfo(vnMaxDepth, member, true, vnDepth + 1, miValueList2); - } - if (bOk) - { - CMIUtilString valueStr = miValueList2.ExtractContentNoBrackets(); - // This is to handle case when a child has further children. For example, - // a struct containing another struct member - // value="{var_a = 10,var_b = 97 'a',inner_ = { var_d = 30 }} - if(vbIsChildValue) - { - const CMICmnMIValueConst miValueConst( - CMIUtilString::Format("%s = { %s }", utilValue.GetName().c_str (), valueStr.c_str()), true); - return vwrMiValueList.Add(miValueConst); - } - else - { - const CMICmnMIValueConst miValueConst(valueStr, true); - return vwrMiValueList.Add(miValueConst); - } - } - return bOk; - } + const CMICmnLLDBUtilSBValue utilValue(vrValue, true, false); + const bool bExpandAggregates = vbInSimpleForm ? false : true; + vwrStrValue = utilValue.GetValue(bExpandAggregates); + return MIstatus::success; } //++ ------------------------------------------------------------------------------------ @@ -856,13 +497,14 @@ // Type: Method. // Args: vrThread - (R) LLDB thread object. // vwrMIValueTuple - (W) MI value tuple object. +// vArgInfo - (R) Args information in MI response form. // Return: MIstatus::success - Functional succeeded. // MIstatus::failure - Functional failed. // Throws: None. //-- bool CMICmnLLDBDebugSessionInfo::MIResponseFormFrameInfo(const lldb::SBThread &vrThread, const MIuint vnLevel, - CMICmnMIValueTuple &vwrMiValueTuple) + const FrameInfoFormat_e veFrameInfoFormat, CMICmnMIValueTuple &vwrMiValueTuple) { lldb::SBThread &rThread = const_cast(vrThread); @@ -879,11 +521,47 @@ const CMIUtilString strLevel(CMIUtilString::Format("%d", vnLevel)); const CMICmnMIValueConst miValueConst(strLevel); const CMICmnMIValueResult miValueResult("level", miValueConst); - CMICmnMIValueTuple miValueTuple(miValueResult); - if (!MIResponseFormFrameInfo(pc, fnName, fileName, path, nLine, miValueTuple)) + if (!vwrMiValueTuple.Add(miValueResult)) + return MIstatus::failure; + const CMIUtilString strAddr(CMIUtilString::Format("0x%016" PRIx64, pc)); + const CMICmnMIValueConst miValueConst2(strAddr); + const CMICmnMIValueResult miValueResult2("addr", miValueConst2); + if (!vwrMiValueTuple.Add(miValueResult2)) + return MIstatus::failure; + const CMICmnMIValueConst miValueConst3(fnName); + const CMICmnMIValueResult miValueResult3("func", miValueConst3); + if (!vwrMiValueTuple.Add(miValueResult3)) return MIstatus::failure; + if (veFrameInfoFormat != eFrameInfoFormat_NoArguments) + { + CMICmnMIValueList miValueList(true); + const MIuint maskVarTypes = eVariableType_Arguments; + if (veFrameInfoFormat == eFrameInfoFormat_AllArgumentsInSimpleForm) + { + if (!MIResponseFormVariableInfo(frame, maskVarTypes, eVariableInfoFormat_AllValues, miValueList, 0)) + return MIstatus::failure; + } + else + if (!MIResponseFormVariableInfo(frame, maskVarTypes, eVariableInfoFormat_AllValues, miValueList)) + return MIstatus::failure; - vwrMiValueTuple = miValueTuple; + const CMICmnMIValueResult miValueResult4("args", miValueList); + if (!vwrMiValueTuple.Add(miValueResult4)) + return MIstatus::failure; + } + const CMICmnMIValueConst miValueConst5(fileName); + const CMICmnMIValueResult miValueResult5("file", miValueConst5); + if (!vwrMiValueTuple.Add(miValueResult5)) + return MIstatus::failure; + const CMICmnMIValueConst miValueConst6(path); + const CMICmnMIValueResult miValueResult6("fullname", miValueConst6); + if (!vwrMiValueTuple.Add(miValueResult6)) + return MIstatus::failure; + const CMIUtilString strLine(CMIUtilString::Format("%d", nLine)); + const CMICmnMIValueConst miValueConst7(strLine); + const CMICmnMIValueResult miValueResult7("line", miValueConst7); + if (!vwrMiValueTuple.Add(miValueResult7)) + return MIstatus::failure; return MIstatus::success; } @@ -933,101 +611,6 @@ // Details: Form MI partial response by appending more MI value type objects to the // tuple type object past in. // Type: Method. -// Args: vPc - (R) Address number. -// vFnName - (R) Function name. -// vFileName - (R) File name text. -// vPath - (R) Full file name and path text. -// vnLine - (R) File line number. -// vwrMIValueTuple - (W) MI value tuple object. -// Return: MIstatus::success - Functional succeeded. -// MIstatus::failure - Functional failed. -// Throws: None. -//-- -bool -CMICmnLLDBDebugSessionInfo::MIResponseFormFrameInfo(const lldb::addr_t vPc, const CMIUtilString &vFnName, const CMIUtilString &vFileName, - const CMIUtilString &vPath, const MIuint vnLine, CMICmnMIValueTuple &vwrMiValueTuple) -{ - const CMIUtilString strAddr(CMIUtilString::Format("0x%016" PRIx64, vPc)); - const CMICmnMIValueConst miValueConst2(strAddr); - const CMICmnMIValueResult miValueResult2("addr", miValueConst2); - if (!vwrMiValueTuple.Add(miValueResult2)) - return MIstatus::failure; - const CMICmnMIValueConst miValueConst3(vFnName); - const CMICmnMIValueResult miValueResult3("func", miValueConst3); - if (!vwrMiValueTuple.Add(miValueResult3)) - return MIstatus::failure; - const CMICmnMIValueConst miValueConst5(vFileName); - const CMICmnMIValueResult miValueResult5("file", miValueConst5); - if (!vwrMiValueTuple.Add(miValueResult5)) - return MIstatus::failure; - const CMICmnMIValueConst miValueConst6(vPath); - const CMICmnMIValueResult miValueResult6("fullname", miValueConst6); - if (!vwrMiValueTuple.Add(miValueResult6)) - return MIstatus::failure; - const CMIUtilString strLine(CMIUtilString::Format("%d", vnLine)); - const CMICmnMIValueConst miValueConst7(strLine); - const CMICmnMIValueResult miValueResult7("line", miValueConst7); - if (!vwrMiValueTuple.Add(miValueResult7)) - return MIstatus::failure; - - return MIstatus::success; -} - -// Todo: Refactor maybe to so only one function with this name, but not just yet -//++ ------------------------------------------------------------------------------------ -// Details: Form MI partial response by appending more MI value type objects to the -// tuple type object past in. -// Type: Method. -// Args: vPc - (R) Address number. -// vArgInfo - (R) Args information in MI response form. -// vFnName - (R) Function name. -// vFileName - (R) File name text. -// vPath - (R) Full file name and path text. -// vnLine - (R) File line number. -// vwrMIValueTuple - (W) MI value tuple object. -// Return: MIstatus::success - Functional succeeded. -// MIstatus::failure - Functional failed. -// Throws: None. -//-- -bool -CMICmnLLDBDebugSessionInfo::MIResponseFormFrameInfo2(const lldb::addr_t vPc, const CMIUtilString &vArgInfo, const CMIUtilString &vFnName, - const CMIUtilString &vFileName, const CMIUtilString &vPath, const MIuint vnLine, - CMICmnMIValueTuple &vwrMiValueTuple) -{ - const CMIUtilString strAddr(CMIUtilString::Format("0x%016" PRIx64, vPc)); - const CMICmnMIValueConst miValueConst2(strAddr); - const CMICmnMIValueResult miValueResult2("addr", miValueConst2); - if (!vwrMiValueTuple.Add(miValueResult2)) - return MIstatus::failure; - const CMICmnMIValueConst miValueConst3(vFnName); - const CMICmnMIValueResult miValueResult3("func", miValueConst3); - if (!vwrMiValueTuple.Add(miValueResult3)) - return MIstatus::failure; - const CMICmnMIValueConst miValueConst4(vArgInfo, true); - const CMICmnMIValueResult miValueResult4("args", miValueConst4); - if (!vwrMiValueTuple.Add(miValueResult4)) - return MIstatus::failure; - const CMICmnMIValueConst miValueConst5(vFileName); - const CMICmnMIValueResult miValueResult5("file", miValueConst5); - if (!vwrMiValueTuple.Add(miValueResult5)) - return MIstatus::failure; - const CMICmnMIValueConst miValueConst6(vPath); - const CMICmnMIValueResult miValueResult6("fullname", miValueConst6); - if (!vwrMiValueTuple.Add(miValueResult6)) - return MIstatus::failure; - const CMIUtilString strLine(CMIUtilString::Format("%d", vnLine)); - const CMICmnMIValueConst miValueConst7(strLine); - const CMICmnMIValueResult miValueResult7("line", miValueConst7); - if (!vwrMiValueTuple.Add(miValueResult7)) - return MIstatus::failure; - - return MIstatus::success; -} - -//++ ------------------------------------------------------------------------------------ -// Details: Form MI partial response by appending more MI value type objects to the -// tuple type object past in. -// Type: Method. // Args: vrBrkPtInfo - (R) Break point information object. // vwrMIValueTuple - (W) MI value tuple object. // Return: MIstatus::success - Functional succeeded. Index: tools/lldb-mi/MICmnLLDBDebugSessionInfoVarObj.cpp =================================================================== --- tools/lldb-mi/MICmnLLDBDebugSessionInfoVarObj.cpp +++ tools/lldb-mi/MICmnLLDBDebugSessionInfoVarObj.cpp @@ -257,7 +257,9 @@ } //++ ------------------------------------------------------------------------------------ -// Details: Return the equivalent var value formatted string for the given value type. +// Details: Return the equivalent var value formatted string for the given value type, +// which was prepared for printing (i.e. value was escaped and now it's ready +// for wrapping into quotes). // The SBValue vrValue parameter is checked by LLDB private code for valid // scalar type via MI Driver proxy function as the valued returned can also be // an error condition. The proxy function determines if the check was valid @@ -272,21 +274,8 @@ CMICmnLLDBDebugSessionInfoVarObj::GetValueStringFormatted(const lldb::SBValue &vrValue, const CMICmnLLDBDebugSessionInfoVarObj::varFormat_e veVarFormat) { - CMIUtilString strFormattedValue; - - MIuint64 nValue = 0; - if (CMICmnLLDBProxySBValue::GetValueAsUnsigned(vrValue, nValue) == MIstatus::success) - { - lldb::SBValue &rValue = const_cast(vrValue); - strFormattedValue = GetStringFormatted(nValue, rValue.GetValue(), veVarFormat); - } - else - { - // Composite variable type i.e. struct - strFormattedValue = "{...}"; - } - - return strFormattedValue; + const CMICmnLLDBUtilSBValue utilValue(vrValue, true); + return utilValue.GetValue().Escape().AddSlashes(); } //++ ------------------------------------------------------------------------------------ @@ -564,7 +553,7 @@ void CMICmnLLDBDebugSessionInfoVarObj::UpdateValue(void) { - m_strFormattedValue = CMICmnLLDBDebugSessionInfoVarObj::GetValueStringFormatted(m_SBValue, m_eVarFormat); + m_strFormattedValue = GetValueStringFormatted(m_SBValue, m_eVarFormat); MIuint64 nValue = 0; if (CMICmnLLDBProxySBValue::GetValueAsUnsigned(m_SBValue, nValue) == MIstatus::failure) Index: tools/lldb-mi/MICmnLLDBDebuggerHandleEvents.cpp =================================================================== --- tools/lldb-mi/MICmnLLDBDebuggerHandleEvents.cpp +++ tools/lldb-mi/MICmnLLDBDebuggerHandleEvents.cpp @@ -1177,7 +1177,7 @@ } CMICmnMIValueTuple miValueTuple; - if (!CMICmnLLDBDebugSessionInfo::Instance().MIResponseFormFrameInfo(thread, 0, miValueTuple)) + if (!CMICmnLLDBDebugSessionInfo::Instance().MIResponseFormFrameInfo(thread, 0, CMICmnLLDBDebugSessionInfo::eFrameInfoFormat_NoArguments, miValueTuple)) { SetErrorDescription(CMIUtilString::Format(MIRSRC(IDS_LLDBOUTOFBAND_ERR_FORM_MI_RESPONSE), "MiHelpGetCurrentThreadFrame()")); return MIstatus::failure; @@ -1260,19 +1260,7 @@ return bOk; } - CMICmnLLDBDebugSessionInfo &rSession = CMICmnLLDBDebugSessionInfo::Instance(); - - lldb::SBFrame frame = thread.GetFrameAtIndex(0); - lldb::addr_t pc = 0; - CMIUtilString fnName; - CMIUtilString fileName; - CMIUtilString path; - MIuint nLine = 0; - if (!rSession.GetFrameInfo(frame, pc, fnName, fileName, path, nLine)) - { - SetErrorDescription(CMIUtilString::Format(MIRSRC(IDS_LLDBOUTOFBAND_ERR_FRAME_INFO_GET), "MiStoppedAtBreakPoint()")); - return MIstatus::failure; - } + CMICmnLLDBDebugSessionInfo &rSessionInfo(CMICmnLLDBDebugSessionInfo::Instance()); // MI print // "*stopped,reason=\"breakpoint-hit\",disp=\"del\",bkptno=\"%d\",frame={addr=\"0x%016" PRIx64 "\",func=\"%s\",args=[],file=\"%s\",fullname=\"%s\",line=\"%d\"},thread-id=\"%d\",stopped-threads=\"all\"" @@ -1290,12 +1278,8 @@ // frame={addr=\"0x%016" PRIx64 "\",func=\"%s\",args=[],file=\"%s\",fullname=\"%s\",line=\"%d\"} if (bOk) { - CMICmnMIValueList miValueList(true); - const MIuint maskVarTypes = CMICmnLLDBDebugSessionInfo::eVariableType_Arguments; - bOk = rSession.MIResponseFormVariableInfo2(frame, maskVarTypes, CMICmnLLDBDebugSessionInfo::eVariableInfoFormat_AllValues, miValueList); - CMICmnMIValueTuple miValueTuple; - bOk = bOk && rSession.MIResponseFormFrameInfo2(pc, miValueList.GetString(), fnName, fileName, path, nLine, miValueTuple); + bOk = bOk && rSessionInfo.MIResponseFormFrameInfo(thread, 0, CMICmnLLDBDebugSessionInfo::eFrameInfoFormat_AllArguments, miValueTuple); const CMICmnMIValueResult miValueResult8("frame", miValueTuple); bOk = bOk && miOutOfBandRecord.Add(miValueResult8); } @@ -1349,29 +1333,14 @@ return bOk; } - CMICmnLLDBDebugSessionInfo &rSession = CMICmnLLDBDebugSessionInfo::Instance(); + CMICmnLLDBDebugSessionInfo &rSessionInfo(CMICmnLLDBDebugSessionInfo::Instance()); // MI print // "*stopped,reason=\"end-stepping-range\",frame={addr=\"0x%016" PRIx64 "\",func=\"%s\",args=[\"%s\"],file=\"%s\",fullname=\"%s\",line=\"%d\"},thread-id=\"%d\",stopped-threads=\"all\"" - lldb::SBFrame frame = thread.GetFrameAtIndex(0); - lldb::addr_t pc = 0; - CMIUtilString fnName; - CMIUtilString fileName; - CMIUtilString path; - MIuint nLine = 0; - if (!rSession.GetFrameInfo(frame, pc, fnName, fileName, path, nLine)) - { - SetErrorDescription(CMIUtilString::Format(MIRSRC(IDS_LLDBOUTOFBAND_ERR_FRAME_INFO_GET), "HandleProcessEventStopReasonTrace()")); - return MIstatus::failure; - } // Function args - CMICmnMIValueList miValueList(true); - const MIuint maskVarTypes = CMICmnLLDBDebugSessionInfo::eVariableType_Arguments; - if (!rSession.MIResponseFormVariableInfo2(frame, maskVarTypes, CMICmnLLDBDebugSessionInfo::eVariableInfoFormat_AllValues, miValueList)) - return MIstatus::failure; CMICmnMIValueTuple miValueTuple; - if (!rSession.MIResponseFormFrameInfo2(pc, miValueList.GetString(), fnName, fileName, path, nLine, miValueTuple)) + if (!rSessionInfo.MIResponseFormFrameInfo(thread, 0, CMICmnLLDBDebugSessionInfo::eFrameInfoFormat_AllArguments, miValueTuple)) return MIstatus::failure; const CMICmnMIValueConst miValueConst("end-stepping-range"); Index: tools/lldb-mi/MICmnLLDBUtilSBValue.h =================================================================== --- tools/lldb-mi/MICmnLLDBUtilSBValue.h +++ tools/lldb-mi/MICmnLLDBUtilSBValue.h @@ -14,6 +14,7 @@ // In-house headers: #include "MIDataTypes.h" +#include "MICmnMIValueTuple.h" // Declerations: class CMIUtilString; @@ -29,17 +30,20 @@ { // Methods: public: - /* ctor */ CMICmnLLDBUtilSBValue(const lldb::SBValue &vrValue, const bool vbHandleCharType = false); + /* ctor */ CMICmnLLDBUtilSBValue(const lldb::SBValue &vrValue, const bool vbHandleCharType = false, + const bool vbHandleArrayType = true); /* dtor */ ~CMICmnLLDBUtilSBValue(void); // CMIUtilString GetName(void) const; - CMIUtilString GetValue(void) const; + CMIUtilString GetValue(const bool vbExpandAggregates = false) const; CMIUtilString GetValueCString(void) const; CMIUtilString GetChildValueCString(void) const; CMIUtilString GetTypeName(void) const; CMIUtilString GetTypeNameDisplay(void) const; bool IsCharType(void) const; - bool IsChildCharType(void) const; + bool IsFirstChildCharType(void) const; + bool IsPointerType(void) const; + bool IsArrayType(void) const; bool IsLLDBVariable(void) const; bool IsNameUnknown(void) const; bool IsValueUnknown(void) const; @@ -49,11 +53,15 @@ // Methods: private: CMIUtilString ReadCStringFromHostMemory(const lldb::SBValue &vrValueObj) const; + bool GetSimpleValue(const bool vbHandleArrayType, CMIUtilString &vrValue) const; + bool GetCompositeValue(CMICmnMIValueTuple &vwrMiValueTuple, const MIuint vnDepth = 1) const; // Attributes: private: lldb::SBValue &m_rValue; const MIchar *m_pUnkwn; - bool m_bValidSBValue; // True = SBValue is a valid object, false = not valid. - bool m_bHandleCharType; // True = Yes return text molding to char type, false = just return data. + const MIchar *m_pComposite; + bool m_bValidSBValue; // True = SBValue is a valid object, false = not valid. + bool m_bHandleCharType; // True = Yes return text molding to char type, false = just return data. + bool m_bHandleArrayType; // True = Yes return special stub for array type, false = just return data. }; Index: tools/lldb-mi/MICmnLLDBUtilSBValue.cpp =================================================================== --- tools/lldb-mi/MICmnLLDBUtilSBValue.cpp +++ tools/lldb-mi/MICmnLLDBUtilSBValue.cpp @@ -9,8 +9,10 @@ // In-house headers: #include "MICmnLLDBUtilSBValue.h" -#include "MIUtilString.h" #include "MICmnLLDBDebugSessionInfo.h" +#include "MICmnMIValueConst.h" +#include "MICmnMIValueTuple.h" +#include "MIUtilString.h" //++ ------------------------------------------------------------------------------------ // Details: CMICmnLLDBUtilSBValue constructor. @@ -21,10 +23,13 @@ // Return: None. // Throws: None. //-- -CMICmnLLDBUtilSBValue::CMICmnLLDBUtilSBValue(const lldb::SBValue &vrValue, const bool vbHandleCharType /* = false */) +CMICmnLLDBUtilSBValue::CMICmnLLDBUtilSBValue(const lldb::SBValue &vrValue, const bool vbHandleCharType /* = false */, + const bool vbHandleArrayType /* = true */) : m_rValue(const_cast(vrValue)) , m_pUnkwn("??") + , m_pComposite("{...}") , m_bHandleCharType(vbHandleCharType) + , m_bHandleArrayType(vbHandleArrayType) { m_bValidSBValue = m_rValue.IsValid(); } @@ -67,28 +72,138 @@ // Throws: None. //-- CMIUtilString -CMICmnLLDBUtilSBValue::GetValue(void) const +CMICmnLLDBUtilSBValue::GetValue(const bool vbExpandAggregates /* = false */) const { - CMIUtilString text; + if (!m_bValidSBValue) + return m_pUnkwn; + + const bool bHandleArrayTypeAsSimple = m_bHandleArrayType && !vbExpandAggregates; + CMIUtilString value; + const bool bIsSimpleValue = GetSimpleValue(bHandleArrayTypeAsSimple, value); + if (bIsSimpleValue) + return value; + + if (!vbExpandAggregates) + return m_pComposite; + + CMICmnMIValueTuple miValueTuple; + const bool bOk = GetCompositeValue(miValueTuple); + if (!bOk) + return m_pUnkwn; - if (m_bHandleCharType && IsCharType()) + value = miValueTuple.GetString(); + return value; +} + +//++ ------------------------------------------------------------------------------------ +// Details: Retrieve from the LLDB SB Value object the value of the variable described in +// text if it has a simple format (not composite). +// Type: Method. +// Args: vwrValue - (W) The SBValue in a string format. +// Return: MIstatus::success - Function succeeded. +// MIstatus::failure - Function failed. +// Throws: None. +//-- +bool +CMICmnLLDBUtilSBValue::GetSimpleValue(const bool vbHandleArrayType, CMIUtilString &vwrValue) const +{ + const MIuint nChildren = m_rValue.GetNumChildren(); + if (nChildren == 0) + { + if (m_bHandleCharType && IsCharType()) + { + const uint8_t value = m_rValue.GetValueAsUnsigned(); + const CMIUtilString prefix(CMIUtilString::Format("%c", value).Escape().AddSlashes()); + vwrValue = CMIUtilString::Format("%hhu '%s'", value, prefix.c_str()); + return MIstatus::success; + } + else + { + const MIchar *pValue = m_bValidSBValue ? m_rValue.GetValue() : nullptr; + vwrValue = pValue != nullptr ? pValue : m_pUnkwn; + return MIstatus::success; + } + } + else if (IsPointerType()) { - uint8_t val = (uint8_t)m_rValue.GetValueAsUnsigned (); - text += CMIUtilString::Format("%d '%c'", val, (char)val); + if (m_bHandleCharType && IsFirstChildCharType()) + { + const MIchar *pValue = m_bValidSBValue ? m_rValue.GetValue() : nullptr; + const CMIUtilString value = pValue != nullptr ? pValue : m_pUnkwn; + const CMIUtilString prefix(GetChildValueCString().Escape().AddSlashes()); + // Note code that has const in will not show the text suffix to the string pointer + // i.e. const char * pMyStr = "blah"; ==> "0x00007000"" <-- Eclipse shows this + // but char * pMyStr = "blah"; ==> "0x00007000" "blah"" <-- Eclipse shows this + vwrValue = CMIUtilString::Format("%s \"%s\"", value.c_str(), prefix.c_str()); + return MIstatus::success; + } + else + { + const MIchar *pValue = m_bValidSBValue ? m_rValue.GetValue() : nullptr; + vwrValue = pValue != nullptr ? pValue : m_pUnkwn; + return MIstatus::success; + } } - else + else if (IsArrayType() && vbHandleArrayType) { - const MIchar *pValue = m_bValidSBValue ? m_rValue.GetValue() : nullptr; - text = (pValue != nullptr) ? pValue : m_pUnkwn; + vwrValue = CMIUtilString::Format("[%u]", nChildren); + return MIstatus::success; } - return text; + // Composite variable type i.e. struct + return MIstatus::failure; +} + +bool +CMICmnLLDBUtilSBValue::GetCompositeValue(CMICmnMIValueTuple &vwrMiValueTuple, + const MIuint vnDepth /* = 1 */) const +{ + const MIuint nMaxDepth = 10; + const MIuint nChildren = m_rValue.GetNumChildren(); + for (MIuint i = 0; i < nChildren; ++i) + { + const lldb::SBValue member = m_rValue.GetChildAtIndex(i); + const CMICmnLLDBUtilSBValue utilMember(member, m_bHandleCharType, m_bHandleArrayType); + const bool bHandleArrayTypeAsSimple = false; + CMIUtilString value; + const bool bIsSimpleValue = utilMember.GetSimpleValue(bHandleArrayTypeAsSimple, value); + if (bIsSimpleValue) + { + // OK. Value is simple (not composite) and was successfully got + } + else if (vnDepth < nMaxDepth) + { + // Need to get value from composite type + CMICmnMIValueTuple miValueTuple; + const bool bOk = utilMember.GetCompositeValue(miValueTuple, vnDepth + 1); + if (!bOk) + // Can't obtain composite type + value = m_pUnkwn; + else + // OK. Value is composite and was successfully got + value = miValueTuple.GetString(); + } + else + { + // Need to get value from composite type, but vnMaxDepth is reached + value = m_pComposite; + } + const bool bNoQuotes = true; + const CMICmnMIValueConst miValueConst(value, bNoQuotes); + const bool bUseSpacing = true; + const CMICmnMIValueResult miValueResult(utilMember.GetName(), miValueConst, bUseSpacing); + const bool bOk = vwrMiValueTuple.Add(miValueResult, bUseSpacing); + if (!bOk) + return MIstatus::failure; + } + + return MIstatus::success; } //++ ------------------------------------------------------------------------------------ -// Details: If the LLDB SB Value object is a char type then form the text data string -// otherwise return nothing. m_bHandleCharType must be true to return text data -// if any. +// Details: If the LLDB SB Value object is a char or char[] type then form the text data +// string otherwise return nothing. m_bHandleCharType must be true to return +// text data if any. // Type: Method. // Args: None. // Return: CMIUtilString - Text description of the variable's value. @@ -99,7 +214,7 @@ { CMIUtilString text; - if (m_bHandleCharType && IsCharType()) + if (m_bHandleCharType && (IsCharType() || (IsArrayType() && IsFirstChildCharType()))) { text = ReadCStringFromHostMemory(m_rValue); } @@ -123,8 +238,8 @@ } //++ ------------------------------------------------------------------------------------ -// Details: Retrieve the flag stating whether any child value object of *this object is a -// char type or some other type. Returns false if there are not children. Char +// Details: Retrieve the flag stating whether first child value object of *this object is +// a char type or some other type. Returns false if there are not children. Char // type can be signed or unsigned. // Type: Method. // Args: None. @@ -132,7 +247,7 @@ // Throws: None. //-- bool -CMICmnLLDBUtilSBValue::IsChildCharType(void) const +CMICmnLLDBUtilSBValue::IsFirstChildCharType(void) const { const MIuint nChildren = m_rValue.GetNumChildren(); @@ -140,16 +255,40 @@ if (nChildren == 0) return false; - // Is it a composite type - if (nChildren > 1) - return false; - - lldb::SBValue member = m_rValue.GetChildAtIndex(0); + const lldb::SBValue member = m_rValue.GetChildAtIndex(0); const CMICmnLLDBUtilSBValue utilValue(member); return utilValue.IsCharType(); } //++ ------------------------------------------------------------------------------------ +// Details: Retrieve the flag stating whether this value object is a pointer type or some +// other type. +// Type: Method. +// Args: None. +// Return: bool - True = Yes is a pointer type, false = some other type. +// Throws: None. +//-- +bool +CMICmnLLDBUtilSBValue::IsPointerType(void) const +{ + return m_rValue.GetType().IsPointerType(); +} + +//++ ------------------------------------------------------------------------------------ +// Details: Retrieve the flag stating whether this value object is an array type or some +// other type. +// Type: Method. +// Args: None. +// Return: bool - True = Yes is an array type, false = some other type. +// Throws: None. +//-- +bool +CMICmnLLDBUtilSBValue::IsArrayType(void) const +{ + return m_rValue.GetType().IsArrayType(); +} + +//++ ------------------------------------------------------------------------------------ // Details: Retrieve the C string data for a child of char type (one and only child) for // the parent value object. If the child is not a char type or the parent has // more than one child then an empty string is returned. Char type can be @@ -200,14 +339,11 @@ const lldb::addr_t addr = rValue.GetLoadAddress(); CMICmnLLDBDebugSessionInfo &rSessionInfo(CMICmnLLDBDebugSessionInfo::Instance()); const MIuint nBytes(128); - const MIchar *pBufferMemory = new MIchar[nBytes]; + std::unique_ptr apBufferMemory(new char[nBytes]); lldb::SBError error; - const MIuint64 nReadBytes = rSessionInfo.GetProcess().ReadMemory(addr, (void *)pBufferMemory, nBytes, error); + const MIuint64 nReadBytes = rSessionInfo.GetProcess().ReadMemory(addr, apBufferMemory.get(), nBytes, error); MIunused(nReadBytes); - text = CMIUtilString::Format("\\\"%s\\\"", pBufferMemory); - delete[] pBufferMemory; - - return text; + return CMIUtilString(apBufferMemory.get()); } //++ ------------------------------------------------------------------------------------