Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
170 changes: 159 additions & 11 deletions runtime/etc/debug/chpl_lldb_pretty_print.py
Original file line number Diff line number Diff line change
Expand Up @@ -292,7 +292,9 @@ def DomainSummary(valobj, internal_dict):
_instance = MaybeResolveWidePointer(
valobj.GetNonSyntheticValue().GetChildMemberWithName("_instance")
)
ranges = _instance.get().GetNonSyntheticValue().GetChildMemberWithName("ranges")
ranges = (
_instance.get().GetNonSyntheticValue().GetChildMemberWithName("ranges")
)
return "{" + RangesToString(ranges) + "}"


Expand All @@ -305,7 +307,11 @@ def __init__(self, valobj, internal_dict):
_instance = MaybeResolveWidePointer(
valobj.GetNonSyntheticValue().GetChildMemberWithName("_instance")
)
ranges = _instance.get().GetNonSyntheticValue().GetChildMemberWithName("ranges")
ranges = (
_instance.get()
.GetNonSyntheticValue()
.GetChildMemberWithName("ranges")
)
self.synthetic_children["dim"] = ranges

def has_children(self):
Expand Down Expand Up @@ -347,13 +353,15 @@ def IsChapelArrayType(sbtype):
match = array_regex_c.match(typename) or array_regex_llvm.match(typename)
return match is not None


def GetArrayRank(sbtype):
typename = sbtype.GetName()
if sbtype.IsReferenceType():
typename = sbtype.GetPointeeType().GetName()
match = array_regex_c.match(typename) or array_regex_llvm.match(typename)
return int(match.group("rank"))


def ArrayRecognizer(sbtype, internal_dict):
return IsChapelArrayType(sbtype)

Expand All @@ -370,8 +378,12 @@ def ArraySummary(valobj, internal_dict):
domClass = MaybeResolveWidePointer(
_instance.get().GetChildMemberWithName("dom")
)
ranges = domClass.get().GetNonSyntheticValue().GetChildMemberWithName("ranges")
return f"[{RangesToString(ranges)}] {GetArrayType(_instance.get()).GetName()}"
ranges = (
domClass.get().GetNonSyntheticValue().GetChildMemberWithName("ranges")
)
return (
f"[{RangesToString(ranges)}] {GetArrayType(_instance.get()).GetName()}"
)


def GetArrayType(_instance):
Expand Down Expand Up @@ -523,7 +535,9 @@ def ManagedObjectRecognizer(sbtype, internal_dict):


def ManagedObjectSummary(valobj, internal_dict):
chpl_p = MaybeResolveWidePointer(valobj.GetNonSyntheticValue().GetChildMemberWithName("chpl_p"))
chpl_p = MaybeResolveWidePointer(
valobj.GetNonSyntheticValue().GetChildMemberWithName("chpl_p")
)

if chpl_p.get().GetValueAsUnsigned() == 0:
return "nil"
Expand All @@ -535,9 +549,9 @@ class ManagedObjectProvider:
def __init__(self, valobj, internal_dict):
self.valobj = valobj

chpl_p = MaybeResolveWidePointer(self.valobj.GetNonSyntheticValue().GetChildMemberWithName(
"chpl_p"
))
chpl_p = MaybeResolveWidePointer(
self.valobj.GetNonSyntheticValue().GetChildMemberWithName("chpl_p")
)
if chpl_p.get().GetValueAsUnsigned() == 0:
self.synthetic_children = {}
else:
Expand Down Expand Up @@ -619,6 +633,130 @@ def get_child_at_index(self, index):
)


# TODO: fix List's of owned

hashtable_entry_regex_llvm = re.compile(
r"^(ChapelHashtable::chpl_TableEntry\((?P<keyType>[a-zA-Z0-9_()? ]+),(?P<valType>[a-zA-Z0-9_()? ]+)\))$"
)
hashtable_regex_llvm = re.compile(
r"^(ChapelHashtable::chpl__hashtable\((?P<keyType>[a-zA-Z0-9_()? ]+),(?P<valType>[a-zA-Z0-9_()? ]+)\))$"
)


def HashTableEntryRecognizer(sbtype, internal_dict):
typename = sbtype.GetName()
match = hashtable_entry_regex_llvm.match(typename)
return match is not None


def IsValidHashTableEntryType(valobj):
target = valobj.GetTarget()
full_enum = target.EvaluateExpression(
"ChapelHashtable::chpl__hash_status::full"
)
status = valobj.GetNonSyntheticValue().GetChildMemberWithName("status")
return status.GetValueAsUnsigned() == full_enum.GetValueAsUnsigned()


def HashTableEntrySummary(valobj, internal_dict):
if not IsValidHashTableEntryType(valobj):
return "<empty>"
key = valobj.GetNonSyntheticValue().GetChildMemberWithName("key")
val = valobj.GetNonSyntheticValue().GetChildMemberWithName("val")
if val.IsValid():
return f"{key.GetSummary() or key.GetValue() or ''} => {val.GetSummary() or val.GetValue() or ''}"
else:
return f"{key.GetSummary() or key.GetValue() or ''}"


def GetHashTableElements(valobj):
tablePtr = valobj.GetNonSyntheticValue().GetChildMemberWithName("table")
tableSize = (
valobj.GetNonSyntheticValue()
.GetChildMemberWithName("tableSize")
.GetValueAsUnsigned()
)
hashTableEntryType = (
MaybeResolveWidePointer(tablePtr).get().GetType().GetPointeeType()
)
hashTableEntrySize = hashTableEntryType.GetByteSize()
resolved_table = MaybeResolveWidePointer(
tablePtr, tableSize * hashTableEntrySize
)
elements = []
table_address = resolved_table.get().GetValueAsUnsigned()
idx = 0
for i in range(tableSize):
offset = i * hashTableEntrySize
element = valobj.CreateValueFromAddress(
f"[{i}]", table_address + offset, hashTableEntryType
)
if IsValidHashTableEntryType(element):
elements.append((idx, element))
idx += 1
return elements


def HashTableRecognizer(sbtype, internal_dict):
typename = sbtype.GetName()
match = hashtable_regex_llvm.match(typename)
return match is not None


def HashTableSummary(valobj, internal_dict):
size = (
valobj.GetNonSyntheticValue()
.GetChildMemberWithName("tableNumFullSlots")
.GetValueAsUnsigned()
)
return f"size = {size}"


class HashTableProvider:
def __init__(self, valobj, internal_dict):
self.valobj = valobj
self.tablePtr = valobj.GetNonSyntheticValue().GetChildMemberWithName(
"table"
)
self.size = (
valobj.GetNonSyntheticValue()
.GetChildMemberWithName("tableNumFullSlots")
.GetValueAsUnsigned()
)
self.capacity = (
valobj.GetNonSyntheticValue()
.GetChildMemberWithName("tableSize")
.GetValueAsUnsigned()
)

self.synthetic_children = {}

elements = GetHashTableElements(self.valobj)
for index, element in elements:
self.synthetic_children[f"[{index}]"] = element

def has_children(self):
return self.num_children() > 0

def num_children(self):
return len(self.synthetic_children)

def get_child_index(self, name):
if name in self.synthetic_children:
return list(self.synthetic_children.keys()).index(name)
else:
return -1

def get_child_at_index(self, index):
if index < 0 or index >= self.num_children():
return None
key = list(self.synthetic_children.keys())[index]
child_obj = self.synthetic_children[key]
return self.valobj.CreateValueFromAddress(
key, child_obj.GetLoadAddress(), child_obj.GetType()
)


def DebugFunc_ResolveWidePointer(debugger, command, result, internal_dict):
"""Resolve a wide pointer manually.
Usage: RWP <wide pointer variable> [size]
Expand Down Expand Up @@ -666,9 +804,10 @@ def register(summary_function, provider_class, recognizer_str):
debugger.HandleCommand(
f"type summary add --skip-pointers --expand --python-function chpl_lldb_pretty_print.{summary_function} {recognizer_str}"
)
debugger.HandleCommand(
f"type synth add --skip-pointers --python-class chpl_lldb_pretty_print.{provider_class} {recognizer_str}"
)
if provider_class is not None:
debugger.HandleCommand(
f"type synth add --skip-pointers --python-class chpl_lldb_pretty_print.{provider_class} {recognizer_str}"
)

def regex(type_regex):
return f"-x '^({type_regex})$'"
Expand All @@ -689,6 +828,15 @@ def recognizer(func_name):
"ManagedObjectProvider",
recognizer("ManagedObjectRecognizer"),
)
register(
"HashTableEntrySummary", None, recognizer("HashTableEntryRecognizer")
)
register(
"HashTableSummary",
"HashTableProvider",
recognizer("HashTableRecognizer"),
)

# TODO: I can't decide if having a wide pointer summary/provider is useful
# or just confusing
# register("WidePointerSummary", "WidePointerProvider", regex("wide\\(.+\\)"))
Expand Down
62 changes: 62 additions & 0 deletions test/llvm/debugInfo/lldb/lists.chpl
Original file line number Diff line number Diff line change
@@ -0,0 +1,62 @@
use List;
use Debugger;

record myRec {
var x: int;
var y: real;
}
class myClass {
var a: int;
var b: real;
}

proc createList(type listTy, in v1, in v2, in v3) {
var myList = new listTy();
myList.pushBack(v1);
myList.pushBack(v2);
myList.pushBack(v3);
return myList;
}

proc main() {
var myIntList = createList(list(int), 1, 2, 3);
writeln("Integer List: ", myIntList);
breakpoint;
writeln("Integer List Again: ", myIntList);

var myRealList = createList(list(real, false), 1.1, 2.2, 3.3);
writeln("Real List: ", myRealList);
breakpoint;
writeln("Real List Again: ", myRealList);

var myRecList = createList(list(myRec, true),
new myRec(10, 20.5),
new myRec(30, 40.5),
new myRec(50, 60.5));
writeln("Record List: ", myRecList);
breakpoint;
writeln("Record List Again: ", myRecList);

var myStrList = createList(list(string), "one", "two", "three");
writeln("String List: ", myStrList);
breakpoint;
writeln("String List Again: ", myStrList);


var myOwnedClassList = createList(list(owned myClass?, true),
new myClass(1, 1.1),
new myClass(2, 2.2),
new myClass(3, 3.3));
writeln("Class List: ", myOwnedClassList);
breakpoint;
writeln("Class List Again: ", myOwnedClassList);


var myClassList = createList(list(unmanaged myClass?),
new unmanaged myClass(1, 1.1),
new unmanaged myClass(2, 2.2),
new unmanaged myClass(3, 3.3));
writeln("Class List: ", myClassList);
breakpoint;
writeln("Class List Again: ", myClassList);
}
60 changes: 60 additions & 0 deletions test/llvm/debugInfo/lldb/maps.chpl
Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@
use Map;
use Debugger;

record myRec {
var x: int;
var y: real;
}
class myClass {
var a: int;
var b: real;
}

proc createMap(type mapTy, in k1, in v1, in k2, in v2, in k3, in v3) {
var myMap = new mapTy();
myMap.add(k1, v1);
myMap.add(k2, v2);
myMap.add(k3, v3);
return myMap;
}

proc main() {
var myIntMap = createMap(map(int, int), 1, 11, 3, 13, 6, 16);
writeln("Integer Map: ", myIntMap);
breakpoint;
writeln("Integer Map Again: ", myIntMap);

var myRealMap = createMap(map(string, real, false), "1.1", 1.1, "2.2", 2.2, "3.3", 3.3);
writeln("Real Map: ", myRealMap);
breakpoint;
writeln("Real Map Again: ", myRealMap);

var myRecMap = createMap(map(int, myRec, true),
1, new myRec(10, 20.5),
2, new myRec(30, 40.5),
3, new myRec(50, 60.5));
writeln("Record Map: ", myRecMap);
breakpoint;
writeln("Record Map Again: ", myRecMap);

var myStrMap = createMap(map(string, string), "1", "one", "2", "two", "3", "three");
writeln("String Map: ", myStrMap);
breakpoint;
writeln("String Map Again: ", myStrMap);

var myOwnedClassMap = createMap(map(string, owned myClass?, true),
"first", new myClass(1, 1.1),
"second", new myClass(2, 2.2),
"third", new myClass(3, 3.3));
writeln("Class Map: ", myOwnedClassMap);
breakpoint;
writeln("Class Map Again: ", myOwnedClassMap);

var myClassMap = createMap(map(int, unmanaged myClass?, true),
1, new unmanaged myClass(1, 1.1),
2, new unmanaged myClass(2, 2.2),
3, new unmanaged myClass(3, 3.3));
writeln("Class Map: ", myClassMap);
breakpoint;
writeln("Class Map Again: ", myClassMap);
}
Loading