Skip to content

Commit

Permalink
Print out address, number of elements, refcount of Array types
Browse files Browse the repository at this point in the history
Summary:
Quick fix while still we finishing implementing printing the elements of Arrays in LLDB. We should not print out the contents as "None" (as is done right now for unimplemented/unhandled) -- this is misleading. This fixes the following, e.g.:
```
(HPHP::Array) {
  m_arr = None
}
```

to instead print something like
```
(HPHP::Array) (0x6060008122a0) ArrayData[Vec]: 4 element(s) refcount=2
        { (Showing elements not yet implemented) }
```

Note: for every variable, you can use `dwim-print -R -- v` (or `expression -R -- v`) to print it out without the pretty printers, in case there are issues in the future.

In the next diff in the works, I'll add printing the elements, and update the newly added test cases.

Reviewed By: oulgen

Differential Revision: D45932994

fbshipit-source-id: 1885732bbd4ece3705750fbec9cf7cfa82fbe01b
  • Loading branch information
mdko authored and facebook-github-bot committed May 17, 2023
1 parent a8e92f1 commit 174c69c
Show file tree
Hide file tree
Showing 3 changed files with 48 additions and 14 deletions.
19 changes: 11 additions & 8 deletions hphp/tools/lldb/pretty.py
Original file line number Diff line number Diff line change
Expand Up @@ -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)


Expand Down
11 changes: 10 additions & 1 deletion hphp/tools/lldb/test/main.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -152,22 +152,31 @@ void takeOptional(Optional<String> UNUSED v) { return; }
void takeLowPtr(LowPtr<Class> 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"));
takeStaticString(StaticString("hello"));
takeStrNR(StrNR(StringData::MakeStatic("hello")));
takeResource(Resource(req::make<DummyResource>()));
takeObject(TestObject);
takeReqPtr(*reinterpret_cast<req::ptr<ObjectData> *>(&TestObject)); // Want to its sole private member m_obj
takeReqPtr(*reinterpret_cast<req::ptr<ObjectData> *>(&TestObject)); // Want to get its sole private member m_obj
takeOptional(Optional<String>("hello"));
takeOptional(Optional<String>());
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
Expand Down
32 changes: 27 additions & 5 deletions hphp/tools/lldb/test/test_pretty.py
Original file line number Diff line number Diff line change
Expand Up @@ -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<false>")
_, 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):
Expand Down Expand Up @@ -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)

0 comments on commit 174c69c

Please sign in to comment.