Skip to content
Open
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
3 changes: 2 additions & 1 deletion src/etc/lldb_commands
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
# Forces test-compliant formatting to all other types
type synthetic add -l lldb_lookup.synthetic_lookup -x ".*" --category Rust
type summary add -F _ -e -x -h "^.*$" --category Rust
# Std String
type synthetic add -l lldb_lookup.StdStringSyntheticProvider -x "^(alloc::([a-z_]+::)+)String$" --category Rust
type summary add -F lldb_lookup.StdStringSummaryProvider -e -x -h "^(alloc::([a-z_]+::)+)String$" --category Rust
Expand Down Expand Up @@ -66,6 +65,7 @@ type summary add -F lldb_lookup.summary_lookup -e -x -h "^(std::([a-z_]+::)+)Pa
type synthetic add -l lldb_lookup.synthetic_lookup -x "^&(mut )?(std::([a-z_]+::)+)Path$" --category Rust
type summary add -F lldb_lookup.summary_lookup -e -x -h "^&(mut )?(std::([a-z_]+::)+)Path$" --category Rust
# Enum
# type summary add -F lldb_lookup.ClangEncodedEnumSummaryProvider -e -h "lldb_lookup.is_sum_type_enum" --recognizer-function --category Rust
## MSVC
type synthetic add -l lldb_lookup.MSVCEnumSyntheticProvider -x "^enum2\$<.+>$" --category Rust
type summary add -F lldb_lookup.MSVCEnumSummaryProvider -e -x -h "^enum2\$<.+>$" --category Rust
Expand All @@ -74,6 +74,7 @@ type synthetic add -l lldb_lookup.synthetic_lookup -x "^enum2\$<.+>::.*$" --cate
type summary add -F lldb_lookup.summary_lookup -e -x -h "^enum2\$<.+>::.*$" --category Rust
# Tuple
type synthetic add -l lldb_lookup.synthetic_lookup -x "^\(.*\)$" --category Rust
type summary add -F lldb_lookup.TupleSummaryProvider -e -x -h "^\(.*\)$" --category Rust
## MSVC
type synthetic add -l lldb_lookup.MSVCTupleSyntheticProvider -x "^tuple\$<.+>$" --category Rust
type summary add -F lldb_lookup.TupleSummaryProvider -e -x -h "^tuple\$<.+>$" --category Rust
Expand Down
23 changes: 20 additions & 3 deletions src/etc/lldb_lookup.py
Original file line number Diff line number Diff line change
Expand Up @@ -10,9 +10,6 @@ def is_hashbrown_hashmap(hash_map: lldb.SBValue) -> bool:


def classify_rust_type(type: lldb.SBType) -> str:
if type.IsPointerType():
type = type.GetPointeeType()

type_class = type.GetTypeClass()
if type_class == lldb.eTypeClassStruct:
return classify_struct(type.name, type.fields)
Expand Down Expand Up @@ -88,6 +85,26 @@ def synthetic_lookup(valobj: lldb.SBValue, _dict: LLDBOpaque) -> object:
if rust_type == RustType.SINGLETON_ENUM:
return synthetic_lookup(valobj.GetChildAtIndex(0), _dict)
if rust_type == RustType.ENUM:
# this little trick lets us treat `synthetic_lookup` as a "recognizer function" for the enum
# summary providers, reducing the number of lookups we have to do. This is a huge time save
# because there's no way (via type name) to recognize sum-type enums on `*-gnu` targets. The
# alternative would be to shove every single type through `summary_lookup`, which is
# incredibly wasteful. Once these scripts are updated for LLDB 19.0 and we can use
# `--recognizer-function`, this hack will only be needed for backwards compatibility.
summary: lldb.SBTypeSummary = valobj.GetTypeSummary()
if (
summary.summary_data is None
or summary.summary_data.strip()
!= "lldb_lookup.ClangEncodedEnumSummaryProvider(valobj,internal_dict)"
):
rust_category: lldb.SBTypeCategory = lldb.debugger.GetCategory("Rust")
rust_category.AddTypeSummary(
lldb.SBTypeNameSpecifier(valobj.GetTypeName()),
lldb.SBTypeSummary().CreateWithFunctionName(
"lldb_lookup.ClangEncodedEnumSummaryProvider"
),
)

return ClangEncodedEnumProvider(valobj, _dict)
if rust_type == RustType.STD_VEC:
return StdVecSyntheticProvider(valobj, _dict)
Expand Down
124 changes: 74 additions & 50 deletions src/etc/lldb_providers.py
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
from __future__ import annotations
import re
import sys
from typing import List, TYPE_CHECKING
from typing import Generator, List, TYPE_CHECKING

from lldb import (
SBData,
Expand All @@ -12,6 +11,8 @@
eFormatChar,
)

from rust_types import is_tuple_fields

if TYPE_CHECKING:
from lldb import SBValue, SBType, SBTypeStaticField

Expand Down Expand Up @@ -133,7 +134,7 @@ def has_children(self) -> bool:
return False


def get_template_args(type_name: str) -> list[str]:
def get_template_args(type_name: str) -> List[str]:
"""
Takes a type name `T<A, tuple$<B, C>, D>` and returns a list of its generic args
`["A", "tuple$<B, C>", "D"]`.
Expand Down Expand Up @@ -163,6 +164,34 @@ def get_template_args(type_name: str) -> list[str]:
return params


def StructSummaryProvider(valobj: SBValue, _dict: LLDBOpaque) -> str:
# structs need the field name before the field value
output = (
f"{valobj.GetChildAtIndex(i).GetName()}:{child}"
for i, child in enumerate(aggregate_field_summary(valobj, _dict))
)

return "{" + ", ".join(output) + "}"


def TupleSummaryProvider(valobj: SBValue, _dict: LLDBOpaque):
return "(" + ", ".join(aggregate_field_summary(valobj, _dict)) + ")"


def aggregate_field_summary(valobj: SBValue, _dict) -> Generator[str, None, None]:
for i in range(0, valobj.GetNumChildren()):
child: SBValue = valobj.GetChildAtIndex(i)
summary = child.summary
if summary is None:
summary = child.value
if summary is None:
if is_tuple_fields(child):
summary = TupleSummaryProvider(child, _dict)
else:
summary = StructSummaryProvider(child, _dict)
yield summary


def SizeSummaryProvider(valobj: SBValue, _dict: LLDBOpaque) -> str:
return "size=" + str(valobj.GetNumChildren())

Expand Down Expand Up @@ -411,49 +440,55 @@ def get_type_name(self):
return "&str"


def _getVariantName(variant) -> str:
def _getVariantName(variant: SBValue) -> str:
"""
Since the enum variant's type name is in the form `TheEnumName::TheVariantName$Variant`,
we can extract `TheVariantName` from it for display purpose.
"""
s = variant.GetType().GetName()
match = re.search(r"::([^:]+)\$Variant$", s)
return match.group(1) if match else ""
if not s.endswith("$Variant"):
return ""

# trim off path and "$Variant"
# len("$Variant") == 8
return s.rsplit("::", 1)[1][:-8]


class ClangEncodedEnumProvider:
"""Pretty-printer for 'clang-encoded' enums support implemented in LLDB"""

valobj: SBValue
variant: SBValue
value: SBValue

DISCRIMINANT_MEMBER_NAME = "$discr$"
VALUE_MEMBER_NAME = "value"

__slots__ = ("valobj", "variant", "value")

def __init__(self, valobj: SBValue, _dict: LLDBOpaque):
self.valobj = valobj
self.update()

def has_children(self) -> bool:
return True
return self.value.MightHaveChildren()

def num_children(self) -> int:
return 1
return self.value.GetNumChildren()

def get_child_index(self, _name: str) -> int:
return -1
def get_child_index(self, name: str) -> int:
return self.value.GetIndexOfChildWithName(name)

def get_child_at_index(self, index: int) -> SBValue:
if index == 0:
value = self.variant.GetChildMemberWithName(
ClangEncodedEnumProvider.VALUE_MEMBER_NAME
)
return value.CreateChildAtOffset(
_getVariantName(self.variant), 0, value.GetType()
)
return None
return self.value.GetChildAtIndex(index)

def update(self):
all_variants = self.valobj.GetChildAtIndex(0)
index = self._getCurrentVariantIndex(all_variants)
self.variant = all_variants.GetChildAtIndex(index)
self.value = self.variant.GetChildMemberWithName(
ClangEncodedEnumProvider.VALUE_MEMBER_NAME
).GetSyntheticValue()

def _getCurrentVariantIndex(self, all_variants: SBValue) -> int:
default_index = 0
Expand All @@ -471,6 +506,23 @@ def _getCurrentVariantIndex(self, all_variants: SBValue) -> int:
return default_index


def ClangEncodedEnumSummaryProvider(valobj: SBValue, _dict: LLDBOpaque) -> str:
enum_synth = ClangEncodedEnumProvider(valobj.GetNonSyntheticValue(), _dict)
variant = enum_synth.variant
name = _getVariantName(variant)

if valobj.GetNumChildren() == 0:
return name

child_name: str = valobj.GetChildAtIndex(0).name
if child_name == "0" or child_name == "__0":
# enum variant is a tuple struct
return name + TupleSummaryProvider(valobj, _dict)
else:
# enum variant is a regular struct
return name + StructSummaryProvider(valobj, _dict)


class MSVCEnumSyntheticProvider:
"""
Synthetic provider for sum-type enums on MSVC. For a detailed explanation of the internals,
Expand All @@ -479,12 +531,14 @@ class MSVCEnumSyntheticProvider:
https://github.com/rust-lang/rust/blob/master/compiler/rustc_codegen_llvm/src/debuginfo/metadata/enums/cpp_like.rs
"""

valobj: SBValue
variant: SBValue
value: SBValue

__slots__ = ["valobj", "variant", "value"]

def __init__(self, valobj: SBValue, _dict: LLDBOpaque):
self.valobj = valobj
self.variant: SBValue
self.value: SBValue
self.update()

def update(self):
Expand Down Expand Up @@ -652,21 +706,6 @@ def get_type_name(self) -> str:
return name


def StructSummaryProvider(valobj: SBValue, _dict: LLDBOpaque) -> str:
output = []
for i in range(valobj.GetNumChildren()):
child: SBValue = valobj.GetChildAtIndex(i)
summary = child.summary
if summary is None:
summary = child.value
if summary is None:
summary = StructSummaryProvider(child, _dict)
summary = child.GetName() + ":" + summary
output.append(summary)

return "{" + ", ".join(output) + "}"


def MSVCEnumSummaryProvider(valobj: SBValue, _dict: LLDBOpaque) -> str:
enum_synth = MSVCEnumSyntheticProvider(valobj.GetNonSyntheticValue(), _dict)
variant_names: SBType = valobj.target.FindFirstType(
Expand Down Expand Up @@ -783,21 +822,6 @@ def get_type_name(self) -> str:
return "(" + name + ")"


def TupleSummaryProvider(valobj: SBValue, _dict: LLDBOpaque):
output: List[str] = []

for i in range(0, valobj.GetNumChildren()):
child: SBValue = valobj.GetChildAtIndex(i)
summary = child.summary
if summary is None:
summary = child.value
if summary is None:
summary = "{...}"
output.append(summary)

return "(" + ", ".join(output) + ")"


class StdVecSyntheticProvider:
"""Pretty-printer for alloc::vec::Vec<T>

Expand Down
2 changes: 1 addition & 1 deletion tests/debuginfo/basic-types-globals.rs
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@
// lldb-command:v I
// lldb-check: ::I::[...] = -1
// lldb-command:v --format=d C
// lldb-check: ::C::[...] = 97
// lldb-check: ::C::[...] = 97 U+0x00000061 U'a'
// lldb-command:v --format=d I8
// lldb-check: ::I8::[...] = 68
// lldb-command:v I16
Expand Down
6 changes: 3 additions & 3 deletions tests/debuginfo/borrowed-enum.rs
Original file line number Diff line number Diff line change
Expand Up @@ -23,11 +23,11 @@
// lldb-command:run

// lldb-command:v *the_a_ref
// lldb-check:(borrowed_enum::ABC) *the_a_ref = { TheA = { x = 0 y = 8970181431921507452 } }
// lldb-check:(borrowed_enum::ABC) *the_a_ref = TheA{x:0, y:8970181431921507452} { x = 0 y = 8970181431921507452 }
// lldb-command:v *the_b_ref
// lldb-check:(borrowed_enum::ABC) *the_b_ref = { TheB = { 0 = 0 1 = 286331153 2 = 286331153 } }
// lldb-check:(borrowed_enum::ABC) *the_b_ref = TheB(0, 286331153, 286331153) { 0 = 0 1 = 286331153 2 = 286331153 }
// lldb-command:v *univariant_ref
// lldb-check:(borrowed_enum::Univariant) *univariant_ref = { TheOnlyCase = { 0 = 4820353753753434 } }
// lldb-check:(borrowed_enum::Univariant) *univariant_ref = TheOnlyCase(4820353753753434) { 0 = 4820353753753434 }

#![allow(unused_variables)]

Expand Down
2 changes: 1 addition & 1 deletion tests/debuginfo/c-style-enum-in-composite.rs
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,7 @@
// lldb-check:[...] { 0 = 0 1 = OneHundred }

// lldb-command:v tuple_padding_at_end
// lldb-check:[...] { 0 = { 0 = 1 1 = OneThousand } 1 = 2 }
// lldb-check:[...] ((1, OneThousand), 2) { 0 = (1, OneThousand) { 0 = 1 1 = OneThousand } 1 = 2 }

// lldb-command:v tuple_different_enums
// lldb-check:[...] { 0 = OneThousand 1 = MountainView 2 = OneMillion 3 = Vienna }
Expand Down
2 changes: 1 addition & 1 deletion tests/debuginfo/coroutine-objects.rs
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@

// lldb-command:run
// lldb-command:v b
// lldb-check:(coroutine_objects::main::{coroutine_env#0}) b = { value = { _ref__a = 0x[...] } $discr$ = [...] }
// lldb-check:(coroutine_objects::main::{coroutine_env#0}) b = 0{_ref__a:0x[...]} { _ref__a = 0x[...] }

// === CDB TESTS ===================================================================================

Expand Down
2 changes: 1 addition & 1 deletion tests/debuginfo/enum-thinlto.rs
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@
// lldb-command:run

// lldb-command:v *abc
// lldb-check:(enum_thinlto::ABC) *abc = { value = { x = 0 y = 8970181431921507452 } $discr$ = 0 }
// lldb-check:(enum_thinlto::ABC) *abc = TheA{x:0, y:8970181431921507452} { x = 0 y = 8970181431921507452 }

#![allow(unused_variables)]

Expand Down
4 changes: 2 additions & 2 deletions tests/debuginfo/generic-method-on-generic-struct.rs
Original file line number Diff line number Diff line change
Expand Up @@ -58,7 +58,7 @@

// STACK BY REF
// lldb-command:v *self
// lldb-check:[...] { x = { 0 = 8888 1 = -8888 } }
// lldb-check:[...] { x = (8888, -8888) { 0 = 8888 1 = -8888 } }
// lldb-command:v arg1
// lldb-check:[...] -1
// lldb-command:v arg2
Expand All @@ -67,7 +67,7 @@

// STACK BY VAL
// lldb-command:v self
// lldb-check:[...] { x = { 0 = 8888 1 = -8888 } }
// lldb-check:[...] { x = (8888, -8888) { 0 = 8888 1 = -8888 } }
// lldb-command:v arg1
// lldb-check:[...] -3
// lldb-command:v arg2
Expand Down
2 changes: 1 addition & 1 deletion tests/debuginfo/issue-57822.rs
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@
// lldb-check:(issue_57822::main::{closure_env#1}) g = { f = { x = 1 } }

// lldb-command:v b
// lldb-check:(issue_57822::main::{coroutine_env#3}) b = { value = { a = { value = { y = 2 } $discr$ = '\x02' } } $discr$ = '\x02' }
// lldb-check:(issue_57822::main::{coroutine_env#3}) b = 2{a:2{y:2}} { a = 2{y:2} { y = 2 } }

#![feature(coroutines, coroutine_trait, stmt_expr_attributes)]

Expand Down
4 changes: 2 additions & 2 deletions tests/debuginfo/method-on-generic-struct.rs
Original file line number Diff line number Diff line change
Expand Up @@ -58,7 +58,7 @@

// STACK BY REF
// lldb-command:v *self
// lldb-check:[...]Struct<(u32, i32)>) *self = { x = { 0 = 8888 1 = -8888 } }
// lldb-check:[...]Struct<(u32, i32)>) *self = { x = (8888, -8888) { 0 = 8888 1 = -8888 } }
// lldb-command:v arg1
// lldb-check:[...] -1
// lldb-command:v arg2
Expand All @@ -67,7 +67,7 @@

// STACK BY VAL
// lldb-command:v self
// lldb-check:[...]Struct<(u32, i32)>) self = { x = { 0 = 8888 1 = -8888 } }
// lldb-check:[...]Struct<(u32, i32)>) self = { x = (8888, -8888) { 0 = 8888 1 = -8888 } }
// lldb-command:v arg1
// lldb-check:[...] -3
// lldb-command:v arg2
Expand Down
1 change: 1 addition & 0 deletions tests/debuginfo/msvc-pretty-enums.rs
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
//@ only-msvc
//@ min-lldb-version: 1800
//@ ignore-gdb
//@ compile-flags:-g
Expand Down
Loading
Loading