Skip to content

Commit 592a2de

Browse files
authored
Merge pull request #282 from cppalliance/pretty_printer
Add LLDB pretty printer module
2 parents 5b2dc9a + b7e5ee3 commit 592a2de

File tree

3 files changed

+138
-0
lines changed

3 files changed

+138
-0
lines changed

doc/int128.adoc

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,8 @@ Matt Borland
2020

2121
include::int128/overview.adoc[]
2222

23+
include::int128/printer.adoc[]
24+
2325
include::int128/api_reference.adoc[]
2426

2527
include::int128/file_structure.adoc[]

doc/int128/printer.adoc

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
////
2+
Copyright 2025 Matt Borland
3+
Distributed under the Boost Software License, Version 1.0.
4+
https://www.boost.org/LICENSE_1_0.txt
5+
////
6+
7+
[#pretty_printer]
8+
= Pretty Printers
9+
:idprefix: pretty_printers_
10+
11+
The library contains a pretty printer for LLDB in the `extra/` folder.
12+
To use this, add the following line to your `~/.lldbinit` file:
13+
14+
[source]
15+
----
16+
command script import /path/to/int128/extra/int128_printer.py
17+
----
18+
19+
If this is successful, you should see the following message in your debugger upon startup:
20+
21+
"int128_t and uint128_t pretty printers loaded successfully"

extra/int128_printer.py

Lines changed: 115 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,115 @@
1+
# int128_printer.py
2+
#
3+
# Struct definitions:
4+
# struct uint128_t { std::uint64_t low; std::uint64_t high; };
5+
# struct int128_t { std::uint64_t low; std::int64_t high; };
6+
#
7+
# On big endian machines the word order is reversed
8+
9+
import lldb
10+
11+
def uint128_summary(valobj, internal_dict):
12+
"""
13+
Custom summary for uint128_t type (unsigned).
14+
Displays as decimal (base 10).
15+
"""
16+
try:
17+
val = valobj.GetNonSyntheticValue()
18+
high = val.GetChildMemberWithName("high").GetValueAsUnsigned()
19+
low = val.GetChildMemberWithName("low").GetValueAsUnsigned()
20+
21+
value = (high << 64) | low
22+
return str(value)
23+
except Exception as e:
24+
return f"<invalid uint128_t: {e}>"
25+
26+
def int128_summary(valobj, internal_dict):
27+
"""
28+
Custom summary for int128_t type (signed).
29+
Displays as decimal (base 10).
30+
"""
31+
try:
32+
val = valobj.GetNonSyntheticValue()
33+
# high is std::int64_t, so use GetValueAsSigned()
34+
high = val.GetChildMemberWithName("high").GetValueAsSigned()
35+
# low is std::uint64_t, so use GetValueAsUnsigned()
36+
low = val.GetChildMemberWithName("low").GetValueAsUnsigned()
37+
38+
value = (high << 64) + low
39+
return str(value)
40+
except Exception as e:
41+
return f"<invalid int128_t: {e}>"
42+
43+
def __lldb_init_module(debugger, internal_dict):
44+
uint128_pattern = r"^(const )?(boost::int128::uint128_t|(\w+::)*uint128_t)( &| \*)?$"
45+
int128_pattern = r"^(const )?(boost::int128::int128_t|(\w+::)*int128_t)( &| \*)?$"
46+
47+
debugger.HandleCommand(
48+
f'type summary add -x "{uint128_pattern}" -e -F int128_printer.uint128_summary'
49+
)
50+
debugger.HandleCommand(
51+
f'type synthetic add -x "{uint128_pattern}" -l int128_printer.Uint128SyntheticProvider'
52+
)
53+
54+
debugger.HandleCommand(
55+
f'type summary add -x "{int128_pattern}" -e -F int128_printer.int128_summary'
56+
)
57+
debugger.HandleCommand(
58+
f'type synthetic add -x "{int128_pattern}" -l int128_printer.Int128SyntheticProvider'
59+
)
60+
61+
print("int128_t and uint128_t pretty printers loaded successfully")
62+
63+
class Uint128SyntheticProvider:
64+
def __init__(self, valobj, internal_dict):
65+
self.valobj = valobj
66+
67+
def num_children(self):
68+
return 2
69+
70+
def get_child_index(self, name):
71+
if name == "low":
72+
return 0
73+
elif name == "high":
74+
return 1
75+
return -1
76+
77+
def get_child_at_index(self, index):
78+
if index == 0:
79+
return self.valobj.GetChildMemberWithName("low")
80+
elif index == 1:
81+
return self.valobj.GetChildMemberWithName("high")
82+
return None
83+
84+
def update(self):
85+
pass
86+
87+
def has_children(self):
88+
return True
89+
90+
class Int128SyntheticProvider:
91+
def __init__(self, valobj, internal_dict):
92+
self.valobj = valobj
93+
94+
def num_children(self):
95+
return 2
96+
97+
def get_child_index(self, name):
98+
if name == "low":
99+
return 0
100+
elif name == "high":
101+
return 1
102+
return -1
103+
104+
def get_child_at_index(self, index):
105+
if index == 0:
106+
return self.valobj.GetChildMemberWithName("low")
107+
elif index == 1:
108+
return self.valobj.GetChildMemberWithName("high")
109+
return None
110+
111+
def update(self):
112+
pass
113+
114+
def has_children(self):
115+
return True

0 commit comments

Comments
 (0)