summaryrefslogtreecommitdiffstats
path: root/lldb
diff options
context:
space:
mode:
authorGreg Clayton <gclayton@apple.com>2016-08-10 23:25:57 +0000
committerGreg Clayton <gclayton@apple.com>2016-08-10 23:25:57 +0000
commit008ec446440646ac154a15dc1f4a3cb2160f7295 (patch)
tree2725f8a1f6a56b382ee2c940bfeca21d52b36e41 /lldb
parent357f1be2ca5a835045643cb488f18bb152925795 (diff)
downloadbcm5719-llvm-008ec446440646ac154a15dc1f4a3cb2160f7295.tar.gz
bcm5719-llvm-008ec446440646ac154a15dc1f4a3cb2160f7295.zip
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> llvm-svn: 278304
Diffstat (limited to 'lldb')
-rw-r--r--lldb/source/Plugins/ScriptInterpreter/Python/PythonDataObjects.cpp13
-rw-r--r--lldb/unittests/ScriptInterpreter/Python/PythonDataObjectsTests.cpp24
2 files changed, 36 insertions, 1 deletions
diff --git a/lldb/source/Plugins/ScriptInterpreter/Python/PythonDataObjects.cpp b/lldb/source/Plugins/ScriptInterpreter/Python/PythonDataObjects.cpp
index b460ab59c99..2bc75150b4d 100644
--- a/lldb/source/Plugins/ScriptInterpreter/Python/PythonDataObjects.cpp
+++ b/lldb/source/Plugins/ScriptInterpreter/Python/PythonDataObjects.cpp
@@ -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;
}
diff --git a/lldb/unittests/ScriptInterpreter/Python/PythonDataObjectsTests.cpp b/lldb/unittests/ScriptInterpreter/Python/PythonDataObjectsTests.cpp
index c239a1601b3..b402beed9a2 100644
--- a/lldb/unittests/ScriptInterpreter/Python/PythonDataObjectsTests.cpp
+++ b/lldb/unittests/ScriptInterpreter/Python/PythonDataObjectsTests.cpp
@@ -595,3 +595,27 @@ TEST_F(PythonDataObjectsTest, TestObjectAttributes)
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);
+ }
+ }
+}
OpenPOWER on IntegriCloud