diff --git a/hphp/tools/lldb/pretty.py b/hphp/tools/lldb/pretty.py index 1b1d3e0c8ad114..b672434a926690 100644 --- a/hphp/tools/lldb/pretty.py +++ b/hphp/tools/lldb/pretty.py @@ -146,29 +146,32 @@ def pretty_array_data(val_obj: lldb.SBValue) -> typing.Optional[str]: if val_obj.type.IsPointerType(): return '' - array_kind = val_obj.target.FindFirstType("HPHP::ArrayData::ArrayKind") - array_kind_enums = array_kind.GetEnumMembers() + # array_kind = val_obj.target.FindFirstType("HPHP::ArrayData::ArrayKind") + # array_kind_enums = array_kind.GetEnumMembers() heap_obj = val_obj.children[0].children[0] # HPHP::HeapObject - m_kind = heap_obj.GetChildMemberWithName("m_kind").Cast(array_kind) + m_kind = heap_obj.GetChildMemberWithName("m_kind") # TODO Try and just compare enums: left is lldb.SBValue, right is lldb.SBTypeEnumMember - if m_kind.unsigned != array_kind_enums['kVecKind'].unsigned: - return val_obj - # Just Vec kind right now + # if m_kind.unsigned != array_kind_enums['kVecKind'].unsigned: + # return val_obj m_size = val_obj.GetChildMemberWithName("m_size").unsigned m_count = heap_obj.GetChildMemberWithName("m_count").unsigned # TODO show elements + elements = "{ (Showing elements not yet implemented) }" - return f"ArrayData[{m_kind.name}]: {m_size} element(s) refcount={m_count}" + return ( + f"({val_obj.addr}) ArrayData[{m_kind.value}]: {m_size} element(s) refcount={m_count}" + + "\n\t" + elements + ) @format("^HPHP::Array$", regex=True) def pp_Array(val_obj: lldb.SBValue, _internal_dict) -> typing.Optional[str]: if val_obj.type.IsPointerType(): return '' - val = utils.rawptr(utils.get(val_obj, "m_arr")) + val = utils.deref(utils.get(val_obj, "m_arr")) return pretty_array_data(val) diff --git a/hphp/tools/lldb/test/main.cpp b/hphp/tools/lldb/test/main.cpp index e76868b730603b..44a8d0c4fe71c0 100644 --- a/hphp/tools/lldb/test/main.cpp +++ b/hphp/tools/lldb/test/main.cpp @@ -152,9 +152,15 @@ void takeOptional(Optional UNUSED v) { return; } void takeLowPtr(LowPtr UNUSED v) { return; } void takeLowStrPtr(LowStrPtr UNUSED v) { return; } void takeExtension(Extension UNUSED v) { return; } +void takeArrayVec(Array UNUSED v) { return; } +void takeArrayDict(Array UNUSED v) { return; } +void takeArrayKeyset(Array UNUSED v) { return; } void buildOtherValues() { TestObject = SystemLib::AllocInvalidArgumentExceptionObject("This is a test exception object for lldb"); + Array vec = make_vec_array(1, 2, 3, 4); + Array dict = make_dict_array("key1", 1, "key2", 2.718, "key3", "Hello, world!"); + Array keyset = make_keyset_array(1, 2, 3, 2, 3); takeStringData(StringData::MakeStatic("hello")); takeString(String("hello")); @@ -162,12 +168,15 @@ void buildOtherValues() { takeStrNR(StrNR(StringData::MakeStatic("hello"))); takeResource(Resource(req::make())); takeObject(TestObject); - takeReqPtr(*reinterpret_cast *>(&TestObject)); // Want to its sole private member m_obj + takeReqPtr(*reinterpret_cast *>(&TestObject)); // Want to get its sole private member m_obj takeOptional(Optional("hello")); takeOptional(Optional()); takeLowPtr(LowPtr(TestObject->getVMClass())); takeLowStrPtr(LowStrPtr(StringData::MakeStatic("hello"))); takeExtension(Extension("test-extension", "0.5", "test-oncall")); + takeArrayVec(vec); + takeArrayDict(dict); + takeArrayKeyset(keyset); } } // namespace lldb_test diff --git a/hphp/tools/lldb/test/test_pretty.py b/hphp/tools/lldb/test/test_pretty.py index d65ead403903b6..b6f76cd8402cac 100644 --- a/hphp/tools/lldb/test/test_pretty.py +++ b/hphp/tools/lldb/test/test_pretty.py @@ -13,11 +13,6 @@ def test_pp_string_data(self): _, output = self.run_commands(["p *name"]) self.assertEqual(output.strip(), "(const HPHP::StringData) C") - def test_pp_array_data(self): - self.run_until_breakpoint("checkReifiedGenericMismatchHelper") - _, output = self.run_commands(["p *reified_generics"]) - self.assertEqual(output.strip(), "(const HPHP::ArrayData) ArrayData[m_kind]: 2 element(s) refcount=3") - class PrettyPrintTypedValuesTestCase(base.TestHHVMTypesBinary): def setUp(self): @@ -150,3 +145,30 @@ def test_pp_other_values(self): _, output = self.run_commands(["p v"]) expected_output = r'\(HPHP::Extension\) test-extension \(version: 0.5, oncall: test-oncall\)' self.assertRegex(output.strip(), expected_output) + + with self.subTest("HPHP::Array (Vec)"): + self.run_until_breakpoint("takeArrayVec") + _, output = self.run_commands(["p v"]) + expected_line1 = r'\(HPHP::Array\) \(0x[0-9a-f]+\) ArrayData\[Vec\]: 4 element\(s\) refcount=2' + expected_line2 = "{ (Showing elements not yet implemented) }" + actual_line1, actual_line2, _ = output.split("\n") + self.assertRegex(actual_line1.strip(), expected_line1) + self.assertEqual(actual_line2.strip(), expected_line2) + + with self.subTest("HPHP::Array (Dict)"): + self.run_until_breakpoint("takeArrayDict") + _, output = self.run_commands(["p v"]) + expected_line1 = r'\(HPHP::Array\) \(0x[0-9a-f]+\) ArrayData\[Dict\]: 3 element\(s\) refcount=2' + expected_line2 = "{ (Showing elements not yet implemented) }" + actual_line1, actual_line2, _ = output.split("\n") + self.assertRegex(actual_line1.strip(), expected_line1) + self.assertEqual(actual_line2.strip(), expected_line2) + + with self.subTest("HPHP::Array (Keyset)"): + self.run_until_breakpoint("takeArrayDict") + _, output = self.run_commands(["p v"]) + expected_line1 = r'\(HPHP::Array\) \(0x[0-9a-f]+\) ArrayData\[Dict\]: 3 element\(s\) refcount=2' + expected_line2 = "{ (Showing elements not yet implemented) }" + actual_line1, actual_line2, _ = output.split("\n") + self.assertRegex(actual_line1.strip(), expected_line1) + self.assertEqual(actual_line2.strip(), expected_line2)