[Lldb-commits] [lldb] r229132 - Fix -data-read-memory-bytes command (MI)
Ilia K
ki.stfu at gmail.com
Fri Feb 13 10:42:25 PST 2015
Author: ki.stfu
Date: Fri Feb 13 12:42:25 2015
New Revision: 229132
URL: http://llvm.org/viewvc/llvm-project?rev=229132&view=rev
Log:
Fix -data-read-memory-bytes command (MI)
Summary:
* Add IsHexadecimalNumber method to CMIUtilString (MI)
* Add number format (dec,hex,auto) to CMICmdArgValNumber (MI)
* Fix -data-read-memory-bytes to pass address in hex format (MI)
* Fix output begin/end/offset fields format in -data-read-memory-bytes
* Fix CMICmdArgValNumber::ExtractNumber to extract 64bit value
* + tests
All tests passed on OS X
Reviewers: abidh, zturner, clayborg
Reviewed By: clayborg
Subscribers: lldb-commits, zturner, clayborg, abidh
Differential Revision: http://reviews.llvm.org/D7610
Modified:
lldb/trunk/test/tools/lldb-mi/TestMiData.py
lldb/trunk/test/tools/lldb-mi/TestMiExec.py
lldb/trunk/test/tools/lldb-mi/main.c
lldb/trunk/tools/lldb-mi/MICmdArgValNumber.cpp
lldb/trunk/tools/lldb-mi/MICmdArgValNumber.h
lldb/trunk/tools/lldb-mi/MICmdCmdData.cpp
lldb/trunk/tools/lldb-mi/MIUtilString.cpp
lldb/trunk/tools/lldb-mi/MIUtilString.h
Modified: lldb/trunk/test/tools/lldb-mi/TestMiData.py
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/test/tools/lldb-mi/TestMiData.py?rev=229132&r1=229131&r2=229132&view=diff
==============================================================================
--- lldb/trunk/test/tools/lldb-mi/TestMiData.py (original)
+++ lldb/trunk/test/tools/lldb-mi/TestMiData.py Fri Feb 13 12:42:25 2015
@@ -37,6 +37,34 @@ class MiDataTestCase(lldbmi_testcase.MiT
@lldbmi_test
@expectedFailureWindows("llvm.org/pr22274: need a pexpect replacement for windows")
+ def test_lldbmi_data_read_memory_bytes(self):
+ """Test that 'lldb-mi --interpreter' works for -data-read-memory-bytes."""
+
+ self.spawnLldbMi(args = None)
+
+ # Load executable
+ self.runCmd("-file-exec-and-symbols %s" % self.myexe)
+ self.expect("\^done")
+
+ # Run to main
+ self.runCmd("-break-insert -f main")
+ self.expect("\^done,bkpt={number=\"1\"")
+ self.runCmd("-exec-run")
+ self.expect("\^running")
+ self.expect("\*stopped,reason=\"breakpoint-hit\"")
+
+ # Get address of s_RawData
+ self.runCmd("-data-evaluate-expression &s_RawData")
+ self.expect("\^done,value=\"0x[0-9a-f]+\"",timeout=1)
+ addr = int(self.child.after.split("\"")[1], 16)
+ size = 5
+
+ # Test -data-read-memory-bytes: try to read data of s_RawData
+ self.runCmd("-data-read-memory-bytes %#x %d" % (addr, size))
+ self.expect("\^done,memory=\[{begin=\"0x0*%x\",offset=\"0x0+\",end=\"0x0*%x\",contents=\"1234567800\"}\]" % (addr, addr + size))
+
+ @lldbmi_test
+ @expectedFailureWindows("llvm.org/pr22274: need a pexpect replacement for windows")
def test_lldbmi_data_list_register_names(self):
"""Test that 'lldb-mi --interpreter' works for -data-list-register-names."""
Modified: lldb/trunk/test/tools/lldb-mi/TestMiExec.py
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/test/tools/lldb-mi/TestMiExec.py?rev=229132&r1=229131&r2=229132&view=diff
==============================================================================
--- lldb/trunk/test/tools/lldb-mi/TestMiExec.py (original)
+++ lldb/trunk/test/tools/lldb-mi/TestMiExec.py Fri Feb 13 12:42:25 2015
@@ -152,22 +152,22 @@ class MiExecTestCase(lldbmi_testcase.MiT
# Test -exec-next
self.runCmd("-exec-next --thread 1 --frame 0")
self.expect("\^running")
- self.expect("\*stopped,reason=\"end-stepping-range\".*main.c\",line=\"24\"")
+ self.expect("\*stopped,reason=\"end-stepping-range\".*main.c\",line=\"26\"")
# Test that --thread is optional
self.runCmd("-exec-next --frame 0")
self.expect("\^running")
- self.expect("\*stopped,reason=\"end-stepping-range\".*main.c\",line=\"25\"")
+ self.expect("\*stopped,reason=\"end-stepping-range\".*main.c\",line=\"27\"")
# Test that --frame is optional
self.runCmd("-exec-next --thread 1")
self.expect("\^running")
- self.expect("\*stopped,reason=\"end-stepping-range\".*main.c\",line=\"27\"")
+ self.expect("\*stopped,reason=\"end-stepping-range\".*main.c\",line=\"29\"")
# Test that both --thread and --frame are optional
self.runCmd("-exec-next --thread 1")
self.expect("\^running")
- self.expect("\*stopped,reason=\"end-stepping-range\".*main.c\",line=\"29\"")
+ self.expect("\*stopped,reason=\"end-stepping-range\".*main.c\",line=\"31\"")
# Test that an invalid --thread is handled
self.runCmd("-exec-next --thread 0")
@@ -204,23 +204,23 @@ class MiExecTestCase(lldbmi_testcase.MiT
# Test -exec-next-instruction
self.runCmd("-exec-next-instruction --thread 1 --frame 0")
self.expect("\^running")
- self.expect("\*stopped,reason=\"end-stepping-range\".*main.c\",line=\"22\"")
+ self.expect("\*stopped,reason=\"end-stepping-range\".*main.c\",line=\"24\"")
# Test that --thread is optional
self.runCmd("-exec-next-instruction --frame 0")
self.expect("\^running")
- self.expect("\*stopped,reason=\"end-stepping-range\".*main.c\",line=\"22\"")
+ self.expect("\*stopped,reason=\"end-stepping-range\".*main.c\",line=\"24\"")
# Test that --frame is optional
self.runCmd("-exec-next-instruction --thread 1")
self.expect("\^running")
- self.expect("\*stopped,reason=\"end-stepping-range\".*main.c\",line=\"22\"")
+ self.expect("\*stopped,reason=\"end-stepping-range\".*main.c\",line=\"24\"")
# Test that both --thread and --frame are optional
self.runCmd("-exec-next-instruction --thread 1")
self.expect("\^running")
# Depending on compiler, it can stop at different line.
- self.expect("\*stopped,reason=\"end-stepping-range\".*main.c\",line=\"2[2-4]\"")
+ self.expect("\*stopped,reason=\"end-stepping-range\".*main.c\",line=\"2[4-6]\"")
# Test that an invalid --thread is handled
self.runCmd("-exec-next-instruction --thread 0")
@@ -259,7 +259,7 @@ class MiExecTestCase(lldbmi_testcase.MiT
#FIXME: is this supposed to step into printf?
self.runCmd("-exec-step --thread 1 --frame 0")
self.expect("\^running")
- self.expect("\*stopped,reason=\"end-stepping-range\".*main.c\",line=\"24\"")
+ self.expect("\*stopped,reason=\"end-stepping-range\".*main.c\",line=\"26\"")
# Test that -exec-step steps into a_MyFunction and back out
# (and that --thread is optional)
@@ -274,10 +274,10 @@ class MiExecTestCase(lldbmi_testcase.MiT
# -exec-step can keep us in the a_MyFunction for gcc
self.runCmd("-exec-finish --frame 0")
self.expect("\^running")
- self.expect("\*stopped,reason=\"end-stepping-range\".*main.c\",line=\"24\"")
+ self.expect("\*stopped,reason=\"end-stepping-range\".*main.c\",line=\"26\"")
self.runCmd("-exec-step --frame 0")
self.expect("\^running")
- self.expect("\*stopped,reason=\"end-stepping-range\".*main.c\",line=\"25\"")
+ self.expect("\*stopped,reason=\"end-stepping-range\".*main.c\",line=\"27\"")
# Test that -exec-step steps into b_MyFunction
# (and that --frame is optional)
@@ -329,13 +329,13 @@ class MiExecTestCase(lldbmi_testcase.MiT
# instruction
self.runCmd("-exec-step-instruction --thread 1 --frame 0")
self.expect("\^running")
- self.expect("\*stopped,reason=\"end-stepping-range\".*main.c\",line=\"2[2-4]\"")
+ self.expect("\*stopped,reason=\"end-stepping-range\".*main.c\",line=\"2[4-6]\"")
# Test that -exec-step-instruction steps over non branching
# instruction (and that --thread is optional)
self.runCmd("-exec-step-instruction --frame 0")
self.expect("\^running")
- self.expect("\*stopped,reason=\"end-stepping-range\".*main.c\",line=\"2[2-4]\"")
+ self.expect("\*stopped,reason=\"end-stepping-range\".*main.c\",line=\"2[4-6]\"")
# Test that -exec-step-instruction steps into a_MyFunction
# (and that --frame is optional)
Modified: lldb/trunk/test/tools/lldb-mi/main.c
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/test/tools/lldb-mi/main.c?rev=229132&r1=229131&r2=229132&view=diff
==============================================================================
--- lldb/trunk/test/tools/lldb-mi/main.c (original)
+++ lldb/trunk/test/tools/lldb-mi/main.c Fri Feb 13 12:42:25 2015
@@ -15,6 +15,8 @@ extern int local_test();
int doloop, dosegfault;
int g_MyVar = 3;
static int s_MyVar = 4;
+//FIXME -data-evaluate-expression/print can't evaluate value of type "static char[]"
+const char s_RawData[] = "\x12\x34\x56\x78"; //FIXME static const char s_RawData[] = "\x12\x34\x56\x78";
int main (int argc, char const *argv[])
{
Modified: lldb/trunk/tools/lldb-mi/MICmdArgValNumber.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/tools/lldb-mi/MICmdArgValNumber.cpp?rev=229132&r1=229131&r2=229132&view=diff
==============================================================================
--- lldb/trunk/tools/lldb-mi/MICmdArgValNumber.cpp (original)
+++ lldb/trunk/tools/lldb-mi/MICmdArgValNumber.cpp Fri Feb 13 12:42:25 2015
@@ -31,21 +31,25 @@
// Throws: None.
//--
CMICmdArgValNumber::CMICmdArgValNumber(void)
- : m_nNumber(0)
+ : m_nNumberFormatMask(CMICmdArgValNumber::eArgValNumberFormat_Decimal)
+ , m_nNumber(0)
{
}
//++ ------------------------------------------------------------------------------------
// Details: CMICmdArgValNumber constructor.
// Type: Method.
-// Args: vrArgName - (R) Argument's name to search by.
-// vbMandatory - (R) True = Yes must be present, false = optional argument.
-// vbHandleByCmd - (R) True = Command processes *this option, false = not handled.
+// Args: vrArgName - (R) Argument's name to search by.
+// vbMandatory - (R) True = Yes must be present, false = optional argument.
+// vbHandleByCmd - (R) True = Command processes *this option, false = not handled.
+// vnNumberFormatMask - (R) Mask of the number formats. (Dflt = CMICmdArgValNumber::eArgValNumberFormat_Decimal)
// Return: None.
// Throws: None.
//--
-CMICmdArgValNumber::CMICmdArgValNumber(const CMIUtilString &vrArgName, const bool vbMandatory, const bool vbHandleByCmd)
+CMICmdArgValNumber::CMICmdArgValNumber(const CMIUtilString &vrArgName, const bool vbMandatory, const bool vbHandleByCmd,
+ const MIuint vnNumberFormatMask /* = CMICmdArgValNumber::eArgValNumberFormat_Decimal*/)
: CMICmdArgValBaseTemplate(vrArgName, vbMandatory, vbHandleByCmd)
+ , m_nNumberFormatMask(vnNumberFormatMask)
, m_nNumber(0)
{
}
@@ -128,11 +132,20 @@ CMICmdArgValNumber::Validate(CMICmdArgCo
bool
CMICmdArgValNumber::IsArgNumber(const CMIUtilString &vrTxt) const
{
+ const bool bFormatDecimal(m_nNumberFormatMask & CMICmdArgValNumber::eArgValNumberFormat_Decimal);
+ const bool bFormatHexadecimal(m_nNumberFormatMask & CMICmdArgValNumber::eArgValNumberFormat_Hexadecimal);
+
// Look for --someLongOption
if (std::string::npos != vrTxt.find("--"))
return false;
- return vrTxt.IsNumber();
+ if (bFormatDecimal && vrTxt.IsNumber())
+ return true;
+
+ if (bFormatHexadecimal && vrTxt.IsHexadecimalNumber())
+ return true;
+
+ return false;
}
//++ ------------------------------------------------------------------------------------
@@ -150,7 +163,7 @@ CMICmdArgValNumber::ExtractNumber(const
bool bOk = vrTxt.ExtractNumber(nNumber);
if (bOk)
{
- m_nNumber = static_cast<MIint>(nNumber);
+ m_nNumber = static_cast<MIint64>(nNumber);
}
return bOk;
Modified: lldb/trunk/tools/lldb-mi/MICmdArgValNumber.h
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/tools/lldb-mi/MICmdArgValNumber.h?rev=229132&r1=229131&r2=229132&view=diff
==============================================================================
--- lldb/trunk/tools/lldb-mi/MICmdArgValNumber.h (original)
+++ lldb/trunk/tools/lldb-mi/MICmdArgValNumber.h Fri Feb 13 12:42:25 2015
@@ -40,10 +40,24 @@ class CMICmdArgContext;
//--
class CMICmdArgValNumber : public CMICmdArgValBaseTemplate<MIint64>
{
+ // Enums:
+ public:
+ //++ ---------------------------------------------------------------------------------
+ // Details: CMICmdArgValNumber needs to know what format of argument to look for in
+ // the command options text.
+ //--
+ enum ArgValNumberFormat_e
+ {
+ eArgValNumberFormat_Decimal = (1u << 0),
+ eArgValNumberFormat_Hexadecimal = (1u << 1),
+ eArgValNumberFormat_Auto = ((eArgValNumberFormat_Hexadecimal << 1) - 1u) ///< Indicates to try and lookup everything up during a query.
+ };
+
// Methods:
public:
/* ctor */ CMICmdArgValNumber(void);
- /* ctor */ CMICmdArgValNumber(const CMIUtilString &vrArgName, const bool vbMandatory, const bool vbHandleByCmd);
+ /* ctor */ CMICmdArgValNumber(const CMIUtilString &vrArgName, const bool vbMandatory, const bool vbHandleByCmd,
+ const MIuint vnNumberFormatMask = eArgValNumberFormat_Decimal);
//
bool IsArgNumber(const CMIUtilString &vrTxt) const;
@@ -61,5 +75,6 @@ class CMICmdArgValNumber : public CMICmd
// Attributes:
private:
+ MIuint m_nNumberFormatMask;
MIint64 m_nNumber;
};
Modified: lldb/trunk/tools/lldb-mi/MICmdCmdData.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/tools/lldb-mi/MICmdCmdData.cpp?rev=229132&r1=229131&r2=229132&view=diff
==============================================================================
--- lldb/trunk/tools/lldb-mi/MICmdCmdData.cpp (original)
+++ lldb/trunk/tools/lldb-mi/MICmdCmdData.cpp Fri Feb 13 12:42:25 2015
@@ -568,7 +568,7 @@ CMICmdCmdDataReadMemoryBytes::ParseArgs(
bOk =
bOk &&
m_setCmdArgs.Add(*(new CMICmdArgValOptionShort(m_constStrArgByteOffset, false, true, CMICmdArgValListBase::eArgValType_Number, 1)));
- bOk = bOk && m_setCmdArgs.Add(*(new CMICmdArgValNumber(m_constStrArgAddrStart, true, true)));
+ bOk = bOk && m_setCmdArgs.Add(*(new CMICmdArgValNumber(m_constStrArgAddrStart, true, true, CMICmdArgValNumber::eArgValNumberFormat_Auto)));
bOk = bOk && m_setCmdArgs.Add(*(new CMICmdArgValNumber(m_constStrArgNumBytes, true, true)));
return (bOk && ParseValidateCmdOptions());
}
@@ -640,13 +640,13 @@ bool
CMICmdCmdDataReadMemoryBytes::Acknowledge(void)
{
// MI: memory=[{begin=\"0x%08x\",offset=\"0x%08x\",end=\"0x%08x\",contents=\" \" }]"
- const CMICmnMIValueConst miValueConst(CMIUtilString::Format("0x%08x", m_nAddrStart));
+ const CMICmnMIValueConst miValueConst(CMIUtilString::Format("0x%08llx", m_nAddrStart));
const CMICmnMIValueResult miValueResult("begin", miValueConst);
CMICmnMIValueTuple miValueTuple(miValueResult);
- const CMICmnMIValueConst miValueConst2(CMIUtilString::Format("0x%08x", m_nAddrOffset));
+ const CMICmnMIValueConst miValueConst2(CMIUtilString::Format("0x%08llx", m_nAddrOffset));
const CMICmnMIValueResult miValueResult2("offset", miValueConst2);
miValueTuple.Add(miValueResult2);
- const CMICmnMIValueConst miValueConst3(CMIUtilString::Format("0x%08x", m_nAddrStart + m_nAddrNumBytesToRead));
+ const CMICmnMIValueConst miValueConst3(CMIUtilString::Format("0x%08llx", m_nAddrStart + m_nAddrNumBytesToRead));
const CMICmnMIValueResult miValueResult3("end", miValueConst3);
miValueTuple.Add(miValueResult3);
@@ -655,7 +655,7 @@ CMICmdCmdDataReadMemoryBytes::Acknowledg
strContent.reserve((m_nAddrNumBytesToRead << 1) + 1);
for (MIuint64 i = 0; i < m_nAddrNumBytesToRead; i++)
{
- strContent += CMIUtilString::Format("%02x", m_pBufferMemory[i]);
+ strContent += CMIUtilString::Format("%02hhx", m_pBufferMemory[i]);
}
const CMICmnMIValueConst miValueConst4(strContent);
const CMICmnMIValueResult miValueResult4("contents", miValueConst4);
Modified: lldb/trunk/tools/lldb-mi/MIUtilString.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/tools/lldb-mi/MIUtilString.cpp?rev=229132&r1=229131&r2=229132&view=diff
==============================================================================
--- lldb/trunk/tools/lldb-mi/MIUtilString.cpp (original)
+++ lldb/trunk/tools/lldb-mi/MIUtilString.cpp Fri Feb 13 12:42:25 2015
@@ -23,7 +23,7 @@
#include <memory> // std::unique_ptr
#include <stdarg.h> // va_list, va_start, var_end
#include <sstream> // std::stringstream
-#include <string.h> // for strcpy
+#include <string.h> // for strncmp
#include <limits.h> // for ULONG_MAX
// In-house headers:
@@ -395,6 +395,28 @@ CMIUtilString::IsNumber(void) const
}
//++ ------------------------------------------------------------------------------------
+// Details: Check if *this string is a hexadecimal number.
+// Type: Method.
+// Args: None.
+// Return: bool - True = yes number, false not a number.
+// Throws: None.
+//--
+bool
+CMIUtilString::IsHexadecimalNumber(void) const
+{
+ // Compare '0x..' prefix
+ if ((strncmp(c_str(), "0x", 2) != 0) && (strncmp(c_str(), "0X", 2) != 0))
+ return false;
+
+ // Skip '0x..' prefix
+ const MIint nPos = find_first_not_of("01234567890ABCDEFabcedf", 2);
+ if (nPos != (MIint)std::string::npos)
+ return false;
+
+ return true;
+}
+
+//++ ------------------------------------------------------------------------------------
// Details: Extract the number from the string. The number can be either a hexadecimal or
// natural number. It cannot contain other non-numeric characters.
// Type: Method.
@@ -433,16 +455,16 @@ CMIUtilString::ExtractNumberFromHexadeci
{
vwrNumber = 0;
- const MIint nPos = find_first_not_of("x01234567890ABCDEFabcedf");
+ const MIint nPos = find_first_not_of("xX01234567890ABCDEFabcedf");
if (nPos != (MIint)std::string::npos)
return false;
- const MIint64 nNum = ::strtoul(this->c_str(), nullptr, 16);
- if (nNum != LONG_MAX)
- {
- vwrNumber = nNum;
- return true;
- }
+ errno = 0;
+ const MIuint64 nNum = ::strtoull(this->c_str(), nullptr, 16);
+ if (errno == ERANGE)
+ return false;
+
+ vwrNumber = static_cast<MIint64>(nNum);
return true;
}
Modified: lldb/trunk/tools/lldb-mi/MIUtilString.h
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/tools/lldb-mi/MIUtilString.h?rev=229132&r1=229131&r2=229132&view=diff
==============================================================================
--- lldb/trunk/tools/lldb-mi/MIUtilString.h (original)
+++ lldb/trunk/tools/lldb-mi/MIUtilString.h Fri Feb 13 12:42:25 2015
@@ -58,6 +58,7 @@ class CMIUtilString : public std::string
bool ExtractNumber(MIint64 &vwrNumber) const;
CMIUtilString FindAndReplace(const CMIUtilString &vFind, const CMIUtilString &vReplaceWith) const;
bool IsNumber(void) const;
+ bool IsHexadecimalNumber(void) const;
bool IsQuoted(void) const;
CMIUtilString RemoveRepeatedCharacters(const MIchar vChar);
MIuint Split(const CMIUtilString &vDelimiter, VecString_t &vwVecSplits) const;
More information about the lldb-commits
mailing list