Author: gclayton
Date: Wed Aug 10 18:25:57 2016
New Revision: 278304

URL: http://llvm.org/viewvc/llvm-project?rev=278304&view=rev
Log:
Fix a problem where if a uint64_t value is placed into a python dictionary and 
sent up to LLDB and converted to StructuredData, it would not be able to parse 
the full 64 bit value. A number like 0xf000000000000000L could be placed into a 
dictionary, and sent to LLDB and it would end up being 0xffffffffffffffff since 
it would overflow a int64_t. We leave the old code there, but if it overflows, 
we treat the number like a uint64_t and get it to decode correctly. Added a 
gtest to cover this so we don't regress. I verified the gtest failed prior to 
the fix, and it succeeds after it.

<rdar://problem/27409265>


Modified:
    lldb/trunk/source/Plugins/ScriptInterpreter/Python/PythonDataObjects.cpp
    lldb/trunk/unittests/ScriptInterpreter/Python/PythonDataObjectsTests.cpp

Modified: 
lldb/trunk/source/Plugins/ScriptInterpreter/Python/PythonDataObjects.cpp
URL: 
http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Plugins/ScriptInterpreter/Python/PythonDataObjects.cpp?rev=278304&r1=278303&r2=278304&view=diff
==============================================================================
--- lldb/trunk/source/Plugins/ScriptInterpreter/Python/PythonDataObjects.cpp 
(original)
+++ lldb/trunk/source/Plugins/ScriptInterpreter/Python/PythonDataObjects.cpp 
Wed Aug 10 18:25:57 2016
@@ -624,7 +624,18 @@ PythonInteger::GetInteger() const
     {
         assert(PyLong_Check(m_py_obj) && "PythonInteger::GetInteger has a 
PyObject that isn't a PyLong");
 
-        return PyLong_AsLongLong(m_py_obj);
+        int overflow = 0;
+        int64_t result = PyLong_AsLongLongAndOverflow(m_py_obj, &overflow);
+        if (overflow != 0)
+        {
+            // We got an integer that overflows, like 18446744072853913392L
+            // we can't use PyLong_AsLongLong() as it will return
+            // 0xffffffffffffffff. If we use the unsigned long long
+            // it will work as expected.
+            const uint64_t uval = PyLong_AsUnsignedLongLong(m_py_obj);
+            result = *((int64_t *)&uval);
+        }
+        return result;
     }
     return UINT64_MAX;
 }

Modified: 
lldb/trunk/unittests/ScriptInterpreter/Python/PythonDataObjectsTests.cpp
URL: 
http://llvm.org/viewvc/llvm-project/lldb/trunk/unittests/ScriptInterpreter/Python/PythonDataObjectsTests.cpp?rev=278304&r1=278303&r2=278304&view=diff
==============================================================================
--- lldb/trunk/unittests/ScriptInterpreter/Python/PythonDataObjectsTests.cpp 
(original)
+++ lldb/trunk/unittests/ScriptInterpreter/Python/PythonDataObjectsTests.cpp 
Wed Aug 10 18:25:57 2016
@@ -595,3 +595,27 @@ TEST_F(PythonDataObjectsTest, TestObject
     EXPECT_TRUE(numerator_attr.IsAllocated());
     EXPECT_EQ(42, numerator_attr.GetInteger());
 }
+
+TEST_F(PythonDataObjectsTest, TestExtractingUInt64ThroughStructuredData)
+{
+    // Make up a custom dictionary with "sys" pointing to the `sys` module.
+    const char *key_name = "addr";
+    const uint64_t value = 0xf000000000000000ull;
+    PythonDictionary python_dict(PyInitialValue::Empty);
+    PythonInteger python_ull_value(PyRefType::Owned, 
PyLong_FromUnsignedLongLong(value));
+    python_dict.SetItemForKey(PythonString(key_name), python_ull_value);
+    StructuredData::ObjectSP structured_data_sp = 
python_dict.CreateStructuredObject();
+    EXPECT_TRUE((bool)structured_data_sp);
+    if (structured_data_sp)
+    {
+        StructuredData::Dictionary *structured_dict_ptr = 
structured_data_sp->GetAsDictionary();
+        EXPECT_TRUE(structured_dict_ptr != nullptr);
+        if (structured_dict_ptr)
+        {
+            StructuredData::ObjectSP structured_addr_value_sp = 
structured_dict_ptr->GetValueForKey(key_name);
+            EXPECT_TRUE((bool)structured_addr_value_sp);
+            const uint64_t extracted_value = 
structured_addr_value_sp->GetIntegerValue(123);
+            EXPECT_TRUE(extracted_value == value);
+        }
+    }
+}


_______________________________________________
lldb-commits mailing list
lldb-commits@lists.llvm.org
http://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits

Reply via email to