Fix evaluation commands (MI)

Summary:
These changes include:
* Fix -var-create to be able use current frame '*' (MI)
* Fix print-values option in -var-update (MI)
* Fix 'variable doesn't exist' error in -var-show-attributes (MI)
* Mark print-values option as 'handled-by-cmd' in -var-update (MI)
* Fix SBValue::GetValueDidChange if value was changed
* Fix lldb-mi: -data-evaluate-expression shows undef vars. Before this fix -data-evaluate-expression perceives undefined variables as strings:
```
(gdb)
-data-evaluate-expression undef
^done,value="undef"
```
* Minor fix: -data-evaluate-expression uses IsUnknownValue()
* Enable MiEvaluateTestCase test

All test pass on OS X.

Reviewers: abidh, clayborg

Subscribers: lldb-commits, clayborg, abidh

Differential Revision: http://reviews.llvm.org/D7463

llvm-svn: 228414
This commit is contained in:
Ilia K 2015-02-06 18:10:30 +00:00
parent 3ffb61b4ae
commit 761a7a4b67
5 changed files with 54 additions and 32 deletions

View File

@ -608,7 +608,8 @@ SBValue::GetValueDidChange ()
lldb::ValueObjectSP value_sp(GetSP(locker)); lldb::ValueObjectSP value_sp(GetSP(locker));
if (value_sp) if (value_sp)
{ {
result = value_sp->GetValueDidChange (); if (value_sp->UpdateValueIfNeeded(false))
result = value_sp->GetValueDidChange ();
} }
if (log) if (log)
log->Printf ("SBValue(%p)::GetValueDidChange() => %i", log->Printf ("SBValue(%p)::GetValueDidChange() => %i",

View File

@ -10,7 +10,6 @@ class MiEvaluateTestCase(lldbmi_testcase.MiTestCaseBase):
@lldbmi_test @lldbmi_test
@expectedFailureWindows("llvm.org/pr22274: need a pexpect replacement for windows") @expectedFailureWindows("llvm.org/pr22274: need a pexpect replacement for windows")
@unittest2.skip("evaluation doesn't work properly")
def test_lldbmi_eval(self): def test_lldbmi_eval(self):
"""Test that 'lldb-mi --interpreter' works for evaluating.""" """Test that 'lldb-mi --interpreter' works for evaluating."""

View File

@ -130,14 +130,14 @@ CMICmdCmdDataEvaluateExpression::Execute(void)
lldb::SBFrame frame = thread.GetSelectedFrame(); lldb::SBFrame frame = thread.GetSelectedFrame();
lldb::SBValue value = frame.EvaluateExpression(rExpression.c_str()); lldb::SBValue value = frame.EvaluateExpression(rExpression.c_str());
if (!value.IsValid()) if (!value.IsValid() || value.GetError().Fail())
value = frame.FindVariable(rExpression.c_str()); value = frame.FindVariable(rExpression.c_str());
if (!value.IsValid()) const CMICmnLLDBUtilSBValue utilValue(value);
if (!utilValue.IsValid() || utilValue.IsValueUnknown())
{ {
m_bEvaluatedExpression = false; m_bEvaluatedExpression = false;
return MIstatus::success; return MIstatus::success;
} }
const CMICmnLLDBUtilSBValue utilValue(value);
if (!utilValue.HasName()) if (!utilValue.HasName())
{ {
if (HaveInvalidCharacterInExpression(rExpression, m_cExpressionInvalidChar)) if (HaveInvalidCharacterInExpression(rExpression, m_cExpressionInvalidChar))
@ -279,16 +279,10 @@ CMICmdCmdDataEvaluateExpression::CreateSelf(void)
bool bool
CMICmdCmdDataEvaluateExpression::HaveInvalidCharacterInExpression(const CMIUtilString &vrExpr, MIchar &vrwInvalidChar) CMICmdCmdDataEvaluateExpression::HaveInvalidCharacterInExpression(const CMIUtilString &vrExpr, MIchar &vrwInvalidChar)
{ {
bool bFoundInvalidCharInExpression = false; static const std::string strInvalidCharacters(";#\\");
vrwInvalidChar = 0x00; const size_t nInvalidCharacterOffset = vrExpr.find_first_of(strInvalidCharacters);
const bool bFoundInvalidCharInExpression = (nInvalidCharacterOffset != CMIUtilString::npos);
if (vrExpr.at(0) == '\\') vrwInvalidChar = bFoundInvalidCharInExpression ? vrExpr[nInvalidCharacterOffset] : 0x00;
{
// Example: Mouse hover over "%5d" expression has \"%5d\" in it
bFoundInvalidCharInExpression = true;
vrwInvalidChar = '\\';
}
return bFoundInvalidCharInExpression; return bFoundInvalidCharInExpression;
} }

View File

@ -137,7 +137,7 @@ CMICmdCmdVarCreate::Execute(void)
// Retrieve the --frame option's number // Retrieve the --frame option's number
MIuint64 nFrame = UINT64_MAX; MIuint64 nFrame = UINT64_MAX;
if (!pArgFrame->GetExpectedOption<CMICmdArgValNumber, MIuint64>(nFrame)) if (pArgThread->GetFound() && !pArgFrame->GetExpectedOption<CMICmdArgValNumber, MIuint64>(nFrame))
{ {
SetError(CMIUtilString::Format(MIRSRC(IDS_CMD_ERR_OPTION_NOT_FOUND), m_cmdData.strMiCmd.c_str(), m_constStrArgFrame.c_str())); SetError(CMIUtilString::Format(MIRSRC(IDS_CMD_ERR_OPTION_NOT_FOUND), m_cmdData.strMiCmd.c_str(), m_constStrArgFrame.c_str()));
return MIstatus::failure; return MIstatus::failure;
@ -151,28 +151,41 @@ CMICmdCmdVarCreate::Execute(void)
nFrame = pOption->GetValue(); nFrame = pOption->GetValue();
} }
bool bAutoName = false; m_strVarName = "<unnamedvariable>";
const CMIUtilString strArgName;
if (pArgName->GetFound()) if (pArgName->GetFound())
{ {
const CMIUtilString &rArg = pArgName->GetValue(); const CMIUtilString &rArg = pArgName->GetValue();
bAutoName = (rArg == "-"); const bool bAutoName = (rArg == "-");
if (bAutoName)
{
m_strVarName = CMIUtilString::Format("var%u", CMICmnLLDBDebugSessionInfoVarObj::VarObjIdGet());
CMICmnLLDBDebugSessionInfoVarObj::VarObjIdInc();
}
else
m_strVarName = rArg;
}
bool bCurrentFrame = false;
if (pArgFrameAddr->GetFound())
{
const CMIUtilString &rStrFrameAddr(pArgFrameAddr->GetValue());
bCurrentFrame = CMIUtilString::Compare(rStrFrameAddr, "*");
if (!bCurrentFrame && (nFrame == UINT64_MAX))
{
//FIXME: *addr isn't implemented. Exit with error if --thread isn't specified.
SetError(CMIUtilString::Format(MIRSRC(IDS_CMD_ERR_OPTION_NOT_FOUND), m_cmdData.strMiCmd.c_str(), m_constStrArgFrame.c_str()));
return MIstatus::failure;
}
} }
const CMIUtilString &rStrExpression(pArgExpression->GetValue()); const CMIUtilString &rStrExpression(pArgExpression->GetValue());
m_strExpression = rStrExpression; m_strExpression = rStrExpression;
CMICmnLLDBDebugSessionInfo &rSessionInfo(CMICmnLLDBDebugSessionInfo::Instance()); CMICmnLLDBDebugSessionInfo &rSessionInfo(CMICmnLLDBDebugSessionInfo::Instance());
m_strVarName = "<unnamedvariable>";
if (bAutoName)
{
m_strVarName = CMIUtilString::Format("var%u", CMICmnLLDBDebugSessionInfoVarObj::VarObjIdGet());
CMICmnLLDBDebugSessionInfoVarObj::VarObjIdInc();
}
lldb::SBProcess sbProcess = rSessionInfo.GetProcess(); lldb::SBProcess sbProcess = rSessionInfo.GetProcess();
lldb::SBThread thread = (nThreadId != UINT64_MAX) ? sbProcess.GetThreadByIndexID(nThreadId) : sbProcess.GetSelectedThread(); lldb::SBThread thread = (nThreadId != UINT64_MAX) ? sbProcess.GetThreadByIndexID(nThreadId) : sbProcess.GetSelectedThread();
m_nThreadId = thread.GetIndexID(); m_nThreadId = thread.GetIndexID();
lldb::SBFrame frame = thread.GetFrameAtIndex(nFrame); lldb::SBFrame frame = bCurrentFrame ? thread.GetSelectedFrame() : thread.GetFrameAtIndex(nFrame);
lldb::SBValue value = frame.FindVariable(rStrExpression.c_str()); lldb::SBValue value = frame.FindVariable(rStrExpression.c_str());
if (!value.IsValid()) if (!value.IsValid())
value = frame.EvaluateExpression(rStrExpression.c_str()); value = frame.EvaluateExpression(rStrExpression.c_str());
@ -260,7 +273,8 @@ CMICmdCmdVarCreate::CreateSelf(void)
// Throws: None. // Throws: None.
//-- //--
CMICmdCmdVarUpdate::CMICmdCmdVarUpdate(void) CMICmdCmdVarUpdate::CMICmdCmdVarUpdate(void)
: m_constStrArgPrintValues("print-values") : m_eVarInfoFormat(CMICmnLLDBDebugSessionInfo::eVariableInfoFormat_NoValues)
, m_constStrArgPrintValues("print-values")
, m_constStrArgName("name") , m_constStrArgName("name")
, m_bValueChangedArrayType(false) , m_bValueChangedArrayType(false)
, m_bValueChangedCompositeType(false) , m_bValueChangedCompositeType(false)
@ -297,7 +311,7 @@ CMICmdCmdVarUpdate::~CMICmdCmdVarUpdate(void)
bool bool
CMICmdCmdVarUpdate::ParseArgs(void) CMICmdCmdVarUpdate::ParseArgs(void)
{ {
bool bOk = m_setCmdArgs.Add(*(new CMICmdArgValNumber(m_constStrArgPrintValues, false, false))); bool bOk = m_setCmdArgs.Add(*(new CMICmdArgValNumber(m_constStrArgPrintValues, false, true)));
bOk = bOk && m_setCmdArgs.Add(*(new CMICmdArgValString(m_constStrArgName, true, true))); bOk = bOk && m_setCmdArgs.Add(*(new CMICmdArgValString(m_constStrArgName, true, true)));
return (bOk && ParseValidateCmdOptions()); return (bOk && ParseValidateCmdOptions());
} }
@ -314,6 +328,7 @@ CMICmdCmdVarUpdate::ParseArgs(void)
bool bool
CMICmdCmdVarUpdate::Execute(void) CMICmdCmdVarUpdate::Execute(void)
{ {
CMICMDBASE_GETOPTION(pArgPrintValues, Number, m_constStrArgPrintValues);
CMICMDBASE_GETOPTION(pArgName, String, m_constStrArgName); CMICMDBASE_GETOPTION(pArgName, String, m_constStrArgName);
const CMIUtilString &rVarObjName(pArgName->GetValue()); const CMIUtilString &rVarObjName(pArgName->GetValue());
@ -324,6 +339,14 @@ CMICmdCmdVarUpdate::Execute(void)
return MIstatus::failure; return MIstatus::failure;
} }
const MIuint nPrintValues = pArgPrintValues->GetValue();
if (nPrintValues >= CMICmnLLDBDebugSessionInfo::kNumVariableInfoFormats)
{
SetError(CMIUtilString::Format(MIRSRC(IDS_CMD_ERR_INVALID_PRINT_VALUES), m_cmdData.strMiCmd.c_str()));
return MIstatus::failure;
}
m_eVarInfoFormat = static_cast<CMICmnLLDBDebugSessionInfo::VariableInfoFormat_e>(nPrintValues);
const CMIUtilString &rVarRealName(varObj.GetNameReal()); const CMIUtilString &rVarRealName(varObj.GetNameReal());
MIunused(rVarRealName); MIunused(rVarRealName);
lldb::SBValue &rValue = const_cast<lldb::SBValue &>(varObj.GetValue()); lldb::SBValue &rValue = const_cast<lldb::SBValue &>(varObj.GetValue());
@ -413,9 +436,12 @@ CMICmdCmdVarUpdate::Acknowledge(void)
const CMICmnMIValueConst miValueConst(m_strValueName); const CMICmnMIValueConst miValueConst(m_strValueName);
CMICmnMIValueResult miValueResult("name", miValueConst); CMICmnMIValueResult miValueResult("name", miValueConst);
CMICmnMIValueTuple miValueTuple(miValueResult); CMICmnMIValueTuple miValueTuple(miValueResult);
const CMICmnMIValueConst miValueConst2(strValue); if (m_eVarInfoFormat != CMICmnLLDBDebugSessionInfo::eVariableInfoFormat_NoValues)
CMICmnMIValueResult miValueResult2("value", miValueConst2); {
miValueTuple.Add(miValueResult2); const CMICmnMIValueConst miValueConst2(strValue);
CMICmnMIValueResult miValueResult2("value", miValueConst2);
miValueTuple.Add(miValueResult2);
}
const CMICmnMIValueConst miValueConst3(strInScope); const CMICmnMIValueConst miValueConst3(strInScope);
CMICmnMIValueResult miValueResult3("in_scope", miValueConst3); CMICmnMIValueResult miValueResult3("in_scope", miValueConst3);
miValueTuple.Add(miValueResult3); miValueTuple.Add(miValueResult3);
@ -1526,7 +1552,7 @@ CMICmdCmdVarShowAttributes::Execute(void)
const CMIUtilString &rVarObjName(pArgName->GetValue()); const CMIUtilString &rVarObjName(pArgName->GetValue());
CMICmnLLDBDebugSessionInfoVarObj varObj; CMICmnLLDBDebugSessionInfoVarObj varObj;
if (CMICmnLLDBDebugSessionInfoVarObj::VarObjGet(rVarObjName, varObj)) if (!CMICmnLLDBDebugSessionInfoVarObj::VarObjGet(rVarObjName, varObj))
{ {
SetError(CMIUtilString::Format(MIRSRC(IDS_CMD_ERR_VARIABLE_DOESNOTEXIST), m_cmdData.strMiCmd.c_str(), rVarObjName.c_str())); SetError(CMIUtilString::Format(MIRSRC(IDS_CMD_ERR_VARIABLE_DOESNOTEXIST), m_cmdData.strMiCmd.c_str(), rVarObjName.c_str()));
return MIstatus::failure; return MIstatus::failure;

View File

@ -42,6 +42,7 @@
#include "MICmdBase.h" #include "MICmdBase.h"
#include "MICmnMIValueTuple.h" #include "MICmnMIValueTuple.h"
#include "MICmnMIValueList.h" #include "MICmnMIValueList.h"
#include "MICmnLLDBDebugSessionInfo.h"
#include "MICmnLLDBDebugSessionInfoVarObj.h" #include "MICmnLLDBDebugSessionInfoVarObj.h"
// Declarations: // Declarations:
@ -129,6 +130,7 @@ class CMICmdCmdVarUpdate : public CMICmdBase
// Attribute: // Attribute:
private: private:
CMIUtilString m_strValueName; CMIUtilString m_strValueName;
CMICmnLLDBDebugSessionInfo::VariableInfoFormat_e m_eVarInfoFormat;
const CMIUtilString m_constStrArgPrintValues; // Not handled by *this command const CMIUtilString m_constStrArgPrintValues; // Not handled by *this command
const CMIUtilString m_constStrArgName; const CMIUtilString m_constStrArgName;
bool m_bValueChangedArrayType; // True = yes value changed, false = no change bool m_bValueChangedArrayType; // True = yes value changed, false = no change