mirror of
https://github.com/rust-lang/rust.git
synced 2025-04-28 02:57:37 +00:00
Auto merge of #72357 - ortem:new-dbg-pretty-printers, r=pnkfelix
Implement new gdb/lldb pretty-printers Reopened #60826 This PR replaces current gdb and lldb pretty-printers with new ones that were originally written for [IntelliJ Rust](https://github.com/intellij-rust/intellij-rust/tree/master/prettyPrinters). The current state of lldb pretty-printers is poor, because [they don't use synthetic children](https://github.com/rust-lang/rust/issues/55586#issuecomment-436610063). When I started to reimplement lldb pretty-printers with synthetic children support, I've found current version strange and hard to support. I think `debugger_pretty_printers_common.py` is overkill, so I got rid of it. The new pretty-printers have to support all types supported by current pretty-printers, and also support `Rc`, `Arc`, `Cell`, `Ref`, `RefCell`, `RefMut`, `HashMap`, `HashSet`. Fixes #56252
This commit is contained in:
commit
f315c35a77
@ -619,19 +619,21 @@ impl Step for DebuggerScripts {
|
||||
cp_debugger_script("natvis/libcore.natvis");
|
||||
cp_debugger_script("natvis/libstd.natvis");
|
||||
} else {
|
||||
cp_debugger_script("debugger_pretty_printers_common.py");
|
||||
cp_debugger_script("rust_types.py");
|
||||
|
||||
// gdb debugger scripts
|
||||
builder.install(&builder.src.join("src/etc/rust-gdb"), &sysroot.join("bin"), 0o755);
|
||||
builder.install(&builder.src.join("src/etc/rust-gdbgui"), &sysroot.join("bin"), 0o755);
|
||||
|
||||
cp_debugger_script("gdb_load_rust_pretty_printers.py");
|
||||
cp_debugger_script("gdb_rust_pretty_printing.py");
|
||||
cp_debugger_script("gdb_lookup.py");
|
||||
cp_debugger_script("gdb_providers.py");
|
||||
|
||||
// lldb debugger scripts
|
||||
builder.install(&builder.src.join("src/etc/rust-lldb"), &sysroot.join("bin"), 0o755);
|
||||
|
||||
cp_debugger_script("lldb_rust_formatters.py");
|
||||
cp_debugger_script("lldb_lookup.py");
|
||||
cp_debugger_script("lldb_providers.py");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1,401 +0,0 @@
|
||||
"""
|
||||
This module provides an abstraction layer over common Rust pretty printing
|
||||
functionality needed by both GDB and LLDB.
|
||||
"""
|
||||
|
||||
import re
|
||||
|
||||
# Type codes that indicate the kind of type as it appears in DWARF debug
|
||||
# information. This code alone is not sufficient to determine the Rust type.
|
||||
# For example structs, tuples, fat pointers, or enum variants will all have
|
||||
# DWARF_TYPE_CODE_STRUCT.
|
||||
DWARF_TYPE_CODE_STRUCT = 1
|
||||
DWARF_TYPE_CODE_UNION = 2
|
||||
DWARF_TYPE_CODE_PTR = 3
|
||||
DWARF_TYPE_CODE_ARRAY = 4
|
||||
DWARF_TYPE_CODE_ENUM = 5
|
||||
|
||||
# These constants specify the most specific kind of type that could be
|
||||
# determined for a given value.
|
||||
TYPE_KIND_UNKNOWN = -1
|
||||
TYPE_KIND_EMPTY = 0
|
||||
TYPE_KIND_SLICE = 1
|
||||
TYPE_KIND_REGULAR_STRUCT = 2
|
||||
TYPE_KIND_TUPLE = 3
|
||||
TYPE_KIND_TUPLE_STRUCT = 4
|
||||
TYPE_KIND_CSTYLE_VARIANT = 5
|
||||
TYPE_KIND_TUPLE_VARIANT = 6
|
||||
TYPE_KIND_STRUCT_VARIANT = 7
|
||||
TYPE_KIND_STR_SLICE = 8
|
||||
TYPE_KIND_STD_VEC = 9
|
||||
TYPE_KIND_STD_STRING = 10
|
||||
TYPE_KIND_REGULAR_ENUM = 11
|
||||
TYPE_KIND_COMPRESSED_ENUM = 12
|
||||
TYPE_KIND_SINGLETON_ENUM = 13
|
||||
TYPE_KIND_CSTYLE_ENUM = 14
|
||||
TYPE_KIND_PTR = 15
|
||||
TYPE_KIND_FIXED_SIZE_VEC = 16
|
||||
TYPE_KIND_REGULAR_UNION = 17
|
||||
TYPE_KIND_OS_STRING = 18
|
||||
TYPE_KIND_STD_VECDEQUE = 19
|
||||
TYPE_KIND_STD_BTREESET = 20
|
||||
TYPE_KIND_STD_BTREEMAP = 21
|
||||
|
||||
ENCODED_ENUM_PREFIX = "RUST$ENCODED$ENUM$"
|
||||
ENUM_DISR_FIELD_NAME = "RUST$ENUM$DISR"
|
||||
|
||||
# Slice related constants
|
||||
SLICE_FIELD_NAME_DATA_PTR = "data_ptr"
|
||||
SLICE_FIELD_NAME_LENGTH = "length"
|
||||
SLICE_FIELD_NAMES = [SLICE_FIELD_NAME_DATA_PTR, SLICE_FIELD_NAME_LENGTH]
|
||||
|
||||
# std::Vec<> related constants
|
||||
STD_VEC_FIELD_NAME_LENGTH = "len"
|
||||
STD_VEC_FIELD_NAME_BUF = "buf"
|
||||
STD_VEC_FIELD_NAMES = [STD_VEC_FIELD_NAME_BUF,
|
||||
STD_VEC_FIELD_NAME_LENGTH]
|
||||
|
||||
# std::collections::VecDeque<> related constants
|
||||
STD_VECDEQUE_FIELD_NAME_TAIL = "tail"
|
||||
STD_VECDEQUE_FIELD_NAME_HEAD = "head"
|
||||
STD_VECDEQUE_FIELD_NAME_BUF = "buf"
|
||||
STD_VECDEQUE_FIELD_NAMES = [STD_VECDEQUE_FIELD_NAME_TAIL,
|
||||
STD_VECDEQUE_FIELD_NAME_HEAD,
|
||||
STD_VECDEQUE_FIELD_NAME_BUF]
|
||||
|
||||
# std::collections::BTreeSet<> related constants
|
||||
STD_BTREESET_FIELD_NAMES = ["map"]
|
||||
|
||||
# std::collections::BTreeMap<> related constants
|
||||
STD_BTREEMAP_FIELD_NAMES = ["root", "length"]
|
||||
|
||||
# std::String related constants
|
||||
STD_STRING_FIELD_NAMES = ["vec"]
|
||||
|
||||
# std::ffi::OsString related constants
|
||||
OS_STRING_FIELD_NAMES = ["inner"]
|
||||
|
||||
|
||||
class Type(object):
|
||||
"""
|
||||
This class provides a common interface for type-oriented operations.
|
||||
Sub-classes are supposed to wrap a debugger-specific type-object and
|
||||
provide implementations for the abstract methods in this class.
|
||||
"""
|
||||
|
||||
def __init__(self):
|
||||
self.__type_kind = None
|
||||
|
||||
def get_unqualified_type_name(self):
|
||||
"""
|
||||
Implementations of this method should return the unqualified name of the
|
||||
type-object they are wrapping. Some examples:
|
||||
|
||||
'int' -> 'int'
|
||||
'std::vec::Vec<std::string::String>' -> 'Vec<std::string::String>'
|
||||
'&std::option::Option<std::string::String>' -> '&std::option::Option<std::string::String>'
|
||||
|
||||
As you can see, type arguments stay fully qualified.
|
||||
"""
|
||||
raise NotImplementedError("Override this method")
|
||||
|
||||
def get_dwarf_type_kind(self):
|
||||
"""
|
||||
Implementations of this method should return the correct
|
||||
DWARF_TYPE_CODE_* value for the wrapped type-object.
|
||||
"""
|
||||
raise NotImplementedError("Override this method")
|
||||
|
||||
def get_fields(self):
|
||||
"""
|
||||
Implementations of this method should return a list of field-objects of
|
||||
this type. For Rust-enums (i.e. with DWARF_TYPE_CODE_UNION) these field-
|
||||
objects represent the variants of the enum. Field-objects must have a
|
||||
`name` attribute that gives their name as specified in DWARF.
|
||||
"""
|
||||
assert ((self.get_dwarf_type_kind() == DWARF_TYPE_CODE_STRUCT) or
|
||||
(self.get_dwarf_type_kind() == DWARF_TYPE_CODE_UNION))
|
||||
raise NotImplementedError("Override this method")
|
||||
|
||||
def get_wrapped_value(self):
|
||||
"""
|
||||
Returns the debugger-specific type-object wrapped by this object. This
|
||||
is sometimes needed for doing things like pointer-arithmetic in GDB.
|
||||
"""
|
||||
raise NotImplementedError("Override this method")
|
||||
|
||||
def get_type_kind(self):
|
||||
"""This method returns the TYPE_KIND_* value for this type-object."""
|
||||
if self.__type_kind is None:
|
||||
dwarf_type_code = self.get_dwarf_type_kind()
|
||||
|
||||
if dwarf_type_code == DWARF_TYPE_CODE_STRUCT:
|
||||
self.__type_kind = self.__classify_struct()
|
||||
elif dwarf_type_code == DWARF_TYPE_CODE_UNION:
|
||||
self.__type_kind = self.__classify_union()
|
||||
elif dwarf_type_code == DWARF_TYPE_CODE_PTR:
|
||||
self.__type_kind = TYPE_KIND_PTR
|
||||
elif dwarf_type_code == DWARF_TYPE_CODE_ARRAY:
|
||||
self.__type_kind = TYPE_KIND_FIXED_SIZE_VEC
|
||||
else:
|
||||
self.__type_kind = TYPE_KIND_UNKNOWN
|
||||
return self.__type_kind
|
||||
|
||||
def __classify_struct(self):
|
||||
assert self.get_dwarf_type_kind() == DWARF_TYPE_CODE_STRUCT
|
||||
|
||||
unqualified_type_name = self.get_unqualified_type_name()
|
||||
|
||||
# STR SLICE
|
||||
if unqualified_type_name == "&str":
|
||||
return TYPE_KIND_STR_SLICE
|
||||
|
||||
# REGULAR SLICE
|
||||
if (unqualified_type_name.startswith(("&[", "&mut [")) and
|
||||
unqualified_type_name.endswith("]") and
|
||||
self.__conforms_to_field_layout(SLICE_FIELD_NAMES)):
|
||||
return TYPE_KIND_SLICE
|
||||
|
||||
fields = self.get_fields()
|
||||
field_count = len(fields)
|
||||
|
||||
# EMPTY STRUCT
|
||||
if field_count == 0:
|
||||
return TYPE_KIND_EMPTY
|
||||
|
||||
# STD VEC
|
||||
if (unqualified_type_name.startswith("Vec<") and
|
||||
self.__conforms_to_field_layout(STD_VEC_FIELD_NAMES)):
|
||||
return TYPE_KIND_STD_VEC
|
||||
|
||||
# STD COLLECTION VECDEQUE
|
||||
if (unqualified_type_name.startswith("VecDeque<") and
|
||||
self.__conforms_to_field_layout(STD_VECDEQUE_FIELD_NAMES)):
|
||||
return TYPE_KIND_STD_VECDEQUE
|
||||
|
||||
# STD COLLECTION BTREESET
|
||||
if (unqualified_type_name.startswith("BTreeSet<") and
|
||||
self.__conforms_to_field_layout(STD_BTREESET_FIELD_NAMES)):
|
||||
return TYPE_KIND_STD_BTREESET
|
||||
|
||||
# STD COLLECTION BTREEMAP
|
||||
if (unqualified_type_name.startswith("BTreeMap<") and
|
||||
self.__conforms_to_field_layout(STD_BTREEMAP_FIELD_NAMES)):
|
||||
return TYPE_KIND_STD_BTREEMAP
|
||||
|
||||
# STD STRING
|
||||
if (unqualified_type_name.startswith("String") and
|
||||
self.__conforms_to_field_layout(STD_STRING_FIELD_NAMES)):
|
||||
return TYPE_KIND_STD_STRING
|
||||
|
||||
# OS STRING
|
||||
if (unqualified_type_name == "OsString" and
|
||||
self.__conforms_to_field_layout(OS_STRING_FIELD_NAMES)):
|
||||
return TYPE_KIND_OS_STRING
|
||||
|
||||
# ENUM VARIANTS
|
||||
if fields[0].name == ENUM_DISR_FIELD_NAME:
|
||||
if field_count == 1:
|
||||
return TYPE_KIND_CSTYLE_VARIANT
|
||||
elif self.__all_fields_conform_to_tuple_field_naming(1):
|
||||
return TYPE_KIND_TUPLE_VARIANT
|
||||
else:
|
||||
return TYPE_KIND_STRUCT_VARIANT
|
||||
|
||||
# TUPLE
|
||||
if self.__all_fields_conform_to_tuple_field_naming(0):
|
||||
if unqualified_type_name.startswith("("):
|
||||
return TYPE_KIND_TUPLE
|
||||
else:
|
||||
return TYPE_KIND_TUPLE_STRUCT
|
||||
|
||||
# REGULAR STRUCT
|
||||
return TYPE_KIND_REGULAR_STRUCT
|
||||
|
||||
def __classify_union(self):
|
||||
assert self.get_dwarf_type_kind() == DWARF_TYPE_CODE_UNION
|
||||
|
||||
union_members = self.get_fields()
|
||||
union_member_count = len(union_members)
|
||||
if union_member_count == 0:
|
||||
return TYPE_KIND_EMPTY
|
||||
|
||||
first_variant_name = union_members[0].name
|
||||
if first_variant_name is None:
|
||||
if union_member_count == 1:
|
||||
return TYPE_KIND_SINGLETON_ENUM
|
||||
else:
|
||||
return TYPE_KIND_REGULAR_ENUM
|
||||
elif first_variant_name.startswith(ENCODED_ENUM_PREFIX):
|
||||
assert union_member_count == 1
|
||||
return TYPE_KIND_COMPRESSED_ENUM
|
||||
else:
|
||||
return TYPE_KIND_REGULAR_UNION
|
||||
|
||||
def __conforms_to_field_layout(self, expected_fields):
|
||||
actual_fields = self.get_fields()
|
||||
actual_field_count = len(actual_fields)
|
||||
|
||||
if actual_field_count != len(expected_fields):
|
||||
return False
|
||||
|
||||
for i in range(0, actual_field_count):
|
||||
if actual_fields[i].name != expected_fields[i]:
|
||||
return False
|
||||
|
||||
return True
|
||||
|
||||
def __all_fields_conform_to_tuple_field_naming(self, start_index):
|
||||
fields = self.get_fields()
|
||||
field_count = len(fields)
|
||||
|
||||
for i in range(start_index, field_count):
|
||||
field_name = fields[i].name
|
||||
if (field_name is None) or (re.match(r"__\d+$", field_name) is None):
|
||||
return False
|
||||
return True
|
||||
|
||||
|
||||
class Value(object):
|
||||
"""
|
||||
This class provides a common interface for value-oriented operations.
|
||||
Sub-classes are supposed to wrap a debugger-specific value-object and
|
||||
provide implementations for the abstract methods in this class.
|
||||
"""
|
||||
def __init__(self, ty):
|
||||
self.type = ty
|
||||
|
||||
def get_child_at_index(self, index):
|
||||
"""Returns the value of the field, array element or variant at the given index"""
|
||||
raise NotImplementedError("Override this method")
|
||||
|
||||
def as_integer(self):
|
||||
"""
|
||||
Try to convert the wrapped value into a Python integer. This should
|
||||
always succeed for values that are pointers or actual integers.
|
||||
"""
|
||||
raise NotImplementedError("Override this method")
|
||||
|
||||
def get_wrapped_value(self):
|
||||
"""
|
||||
Returns the debugger-specific value-object wrapped by this object. This
|
||||
is sometimes needed for doing things like pointer-arithmetic in GDB.
|
||||
"""
|
||||
raise NotImplementedError("Override this method")
|
||||
|
||||
|
||||
class EncodedEnumInfo(object):
|
||||
"""
|
||||
This class provides facilities for handling enum values with compressed
|
||||
encoding where a non-null field in one variant doubles as the discriminant.
|
||||
"""
|
||||
|
||||
def __init__(self, enum_val):
|
||||
assert enum_val.type.get_type_kind() == TYPE_KIND_COMPRESSED_ENUM
|
||||
variant_name = enum_val.type.get_fields()[0].name
|
||||
last_separator_index = variant_name.rfind("$")
|
||||
start_index = len(ENCODED_ENUM_PREFIX)
|
||||
indices_substring = variant_name[start_index:last_separator_index].split("$")
|
||||
self.__enum_val = enum_val
|
||||
self.__disr_field_indices = [int(index) for index in indices_substring]
|
||||
self.__null_variant_name = variant_name[last_separator_index + 1:]
|
||||
|
||||
def is_null_variant(self):
|
||||
ty = self.__enum_val.type
|
||||
sole_variant_val = self.__enum_val.get_child_at_index(0)
|
||||
discriminant_val = sole_variant_val
|
||||
for disr_field_index in self.__disr_field_indices:
|
||||
discriminant_val = discriminant_val.get_child_at_index(disr_field_index)
|
||||
|
||||
# If the discriminant field is a fat pointer we have to consider the
|
||||
# first word as the true discriminant
|
||||
if discriminant_val.type.get_dwarf_type_kind() == DWARF_TYPE_CODE_STRUCT:
|
||||
discriminant_val = discriminant_val.get_child_at_index(0)
|
||||
|
||||
return discriminant_val.as_integer() == 0
|
||||
|
||||
def get_non_null_variant_val(self):
|
||||
return self.__enum_val.get_child_at_index(0)
|
||||
|
||||
def get_null_variant_name(self):
|
||||
return self.__null_variant_name
|
||||
|
||||
|
||||
def get_discriminant_value_as_integer(enum_val):
|
||||
assert enum_val.type.get_dwarf_type_kind() == DWARF_TYPE_CODE_UNION
|
||||
# we can take any variant here because the discriminant has to be the same
|
||||
# for all of them.
|
||||
variant_val = enum_val.get_child_at_index(0)
|
||||
disr_val = variant_val.get_child_at_index(0)
|
||||
return disr_val.as_integer()
|
||||
|
||||
|
||||
def extract_length_ptr_and_cap_from_std_vec(vec_val):
|
||||
assert vec_val.type.get_type_kind() == TYPE_KIND_STD_VEC
|
||||
length_field_index = STD_VEC_FIELD_NAMES.index(STD_VEC_FIELD_NAME_LENGTH)
|
||||
buf_field_index = STD_VEC_FIELD_NAMES.index(STD_VEC_FIELD_NAME_BUF)
|
||||
|
||||
length = vec_val.get_child_at_index(length_field_index).as_integer()
|
||||
buf = vec_val.get_child_at_index(buf_field_index)
|
||||
|
||||
vec_ptr_val = buf.get_child_at_index(0)
|
||||
capacity = buf.get_child_at_index(1).as_integer()
|
||||
data_ptr = vec_ptr_val.get_child_at_index(0)
|
||||
assert data_ptr.type.get_dwarf_type_kind() == DWARF_TYPE_CODE_PTR
|
||||
return (length, data_ptr, capacity)
|
||||
|
||||
|
||||
def extract_tail_head_ptr_and_cap_from_std_vecdeque(vec_val):
|
||||
assert vec_val.type.get_type_kind() == TYPE_KIND_STD_VECDEQUE
|
||||
tail_field_index = STD_VECDEQUE_FIELD_NAMES.index(STD_VECDEQUE_FIELD_NAME_TAIL)
|
||||
head_field_index = STD_VECDEQUE_FIELD_NAMES.index(STD_VECDEQUE_FIELD_NAME_HEAD)
|
||||
buf_field_index = STD_VECDEQUE_FIELD_NAMES.index(STD_VECDEQUE_FIELD_NAME_BUF)
|
||||
|
||||
tail = vec_val.get_child_at_index(tail_field_index).as_integer()
|
||||
head = vec_val.get_child_at_index(head_field_index).as_integer()
|
||||
buf = vec_val.get_child_at_index(buf_field_index)
|
||||
|
||||
vec_ptr_val = buf.get_child_at_index(0)
|
||||
capacity = buf.get_child_at_index(1).as_integer()
|
||||
data_ptr = vec_ptr_val.get_child_at_index(0)
|
||||
assert data_ptr.type.get_dwarf_type_kind() == DWARF_TYPE_CODE_PTR
|
||||
return (tail, head, data_ptr, capacity)
|
||||
|
||||
|
||||
def extract_length_and_ptr_from_slice(slice_val):
|
||||
assert (slice_val.type.get_type_kind() == TYPE_KIND_SLICE or
|
||||
slice_val.type.get_type_kind() == TYPE_KIND_STR_SLICE)
|
||||
|
||||
length_field_index = SLICE_FIELD_NAMES.index(SLICE_FIELD_NAME_LENGTH)
|
||||
ptr_field_index = SLICE_FIELD_NAMES.index(SLICE_FIELD_NAME_DATA_PTR)
|
||||
|
||||
length = slice_val.get_child_at_index(length_field_index).as_integer()
|
||||
data_ptr = slice_val.get_child_at_index(ptr_field_index)
|
||||
|
||||
assert data_ptr.type.get_dwarf_type_kind() == DWARF_TYPE_CODE_PTR
|
||||
return (length, data_ptr)
|
||||
|
||||
|
||||
UNQUALIFIED_TYPE_MARKERS = frozenset(["(", "[", "&", "*"])
|
||||
|
||||
|
||||
def extract_type_name(qualified_type_name):
|
||||
"""Extracts the type name from a fully qualified path"""
|
||||
if qualified_type_name[0] in UNQUALIFIED_TYPE_MARKERS:
|
||||
return qualified_type_name
|
||||
|
||||
end_of_search = qualified_type_name.find("<")
|
||||
if end_of_search < 0:
|
||||
end_of_search = len(qualified_type_name)
|
||||
|
||||
index = qualified_type_name.rfind("::", 0, end_of_search)
|
||||
if index < 0:
|
||||
return qualified_type_name
|
||||
else:
|
||||
return qualified_type_name[index + 2:]
|
||||
|
||||
|
||||
try:
|
||||
compat_str = unicode # Python 2
|
||||
except NameError:
|
||||
compat_str = str
|
@ -1,3 +1,3 @@
|
||||
import gdb
|
||||
import gdb_rust_pretty_printing
|
||||
gdb_rust_pretty_printing.register_printers(gdb.current_objfile())
|
||||
import gdb_lookup
|
||||
gdb_lookup.register_printers(gdb.current_objfile())
|
||||
|
92
src/etc/gdb_lookup.py
Normal file
92
src/etc/gdb_lookup.py
Normal file
@ -0,0 +1,92 @@
|
||||
import gdb
|
||||
import re
|
||||
|
||||
from gdb_providers import *
|
||||
from rust_types import *
|
||||
|
||||
|
||||
rust_enabled = 'set language rust' in gdb.execute('complete set language ru', to_string=True)
|
||||
_gdb_version_matched = re.search('([0-9]+)\\.([0-9]+)', gdb.VERSION)
|
||||
gdb_version = [int(num) for num in _gdb_version_matched.groups()] if _gdb_version_matched else []
|
||||
|
||||
def register_printers(objfile):
|
||||
objfile.pretty_printers.append(lookup)
|
||||
|
||||
|
||||
# BACKCOMPAT: rust 1.35
|
||||
def is_hashbrown_hashmap(hash_map):
|
||||
return len(hash_map.type.fields()) == 1
|
||||
|
||||
|
||||
def classify_rust_type(type):
|
||||
type_class = type.code
|
||||
if type_class == gdb.TYPE_CODE_STRUCT:
|
||||
return classify_struct(type.tag, type.fields())
|
||||
if type_class == gdb.TYPE_CODE_UNION:
|
||||
return classify_union(type.fields())
|
||||
|
||||
return RustType.OTHER
|
||||
|
||||
|
||||
def check_enum_discriminant(valobj):
|
||||
content = valobj[valobj.type.fields()[0]]
|
||||
fields = content.type.fields()
|
||||
if len(fields) > 1:
|
||||
discriminant = int(content[fields[0]]) + 1
|
||||
if discriminant > len(fields):
|
||||
# invalid discriminant
|
||||
return False
|
||||
return True
|
||||
|
||||
|
||||
def lookup(valobj):
|
||||
rust_type = classify_rust_type(valobj.type)
|
||||
|
||||
if rust_type == RustType.ENUM:
|
||||
# use enum provider only for GDB <7.12
|
||||
if gdb_version[0] < 7 or (gdb_version[0] == 7 and gdb_version[1] < 12):
|
||||
if check_enum_discriminant(valobj):
|
||||
return EnumProvider(valobj)
|
||||
|
||||
if rust_type == RustType.STD_STRING:
|
||||
return StdStringProvider(valobj)
|
||||
if rust_type == RustType.STD_OS_STRING:
|
||||
return StdOsStringProvider(valobj)
|
||||
if rust_type == RustType.STD_STR and not rust_enabled:
|
||||
return StdStrProvider(valobj)
|
||||
|
||||
if rust_type == RustType.STD_VEC:
|
||||
return StdVecProvider(valobj)
|
||||
if rust_type == RustType.STD_VEC_DEQUE:
|
||||
return StdVecDequeProvider(valobj)
|
||||
if rust_type == RustType.STD_BTREE_SET:
|
||||
return StdBTreeSetProvider(valobj)
|
||||
if rust_type == RustType.STD_BTREE_MAP:
|
||||
return StdBTreeMapProvider(valobj)
|
||||
if rust_type == RustType.STD_HASH_MAP:
|
||||
if is_hashbrown_hashmap(valobj):
|
||||
return StdHashMapProvider(valobj)
|
||||
else:
|
||||
return StdOldHashMapProvider(valobj)
|
||||
if rust_type == RustType.STD_HASH_SET:
|
||||
hash_map = valobj["map"]
|
||||
if is_hashbrown_hashmap(hash_map):
|
||||
return StdHashMapProvider(hash_map, show_values=False)
|
||||
else:
|
||||
return StdOldHashMapProvider(hash_map, show_values=False)
|
||||
|
||||
if rust_type == RustType.STD_RC:
|
||||
return StdRcProvider(valobj)
|
||||
if rust_type == RustType.STD_ARC:
|
||||
return StdRcProvider(valobj, is_atomic=True)
|
||||
|
||||
if rust_type == RustType.STD_CELL:
|
||||
return StdCellProvider(valobj)
|
||||
if rust_type == RustType.STD_REF:
|
||||
return StdRefProvider(valobj)
|
||||
if rust_type == RustType.STD_REF_MUT:
|
||||
return StdRefProvider(valobj)
|
||||
if rust_type == RustType.STD_REF_CELL:
|
||||
return StdRefCellProvider(valobj)
|
||||
|
||||
return None
|
385
src/etc/gdb_providers.py
Normal file
385
src/etc/gdb_providers.py
Normal file
@ -0,0 +1,385 @@
|
||||
from sys import version_info
|
||||
|
||||
import gdb
|
||||
from gdb import lookup_type
|
||||
|
||||
if version_info[0] >= 3:
|
||||
xrange = range
|
||||
|
||||
ZERO_FIELD = "__0"
|
||||
FIRST_FIELD = "__1"
|
||||
|
||||
|
||||
def unwrap_unique_or_non_null(unique_or_nonnull):
|
||||
# BACKCOMPAT: rust 1.32
|
||||
# https://github.com/rust-lang/rust/commit/7a0911528058e87d22ea305695f4047572c5e067
|
||||
ptr = unique_or_nonnull["pointer"]
|
||||
return ptr if ptr.type.code == gdb.TYPE_CODE_PTR else ptr[ZERO_FIELD]
|
||||
|
||||
|
||||
class EnumProvider:
|
||||
def __init__(self, valobj):
|
||||
content = valobj[valobj.type.fields()[0]]
|
||||
fields = content.type.fields()
|
||||
self.empty = len(fields) == 0
|
||||
if not self.empty:
|
||||
if len(fields) == 1:
|
||||
discriminant = 0
|
||||
else:
|
||||
discriminant = int(content[fields[0]]) + 1
|
||||
self.active_variant = content[fields[discriminant]]
|
||||
self.name = fields[discriminant].name
|
||||
self.full_name = "{}::{}".format(valobj.type.name, self.name)
|
||||
else:
|
||||
self.full_name = valobj.type.name
|
||||
|
||||
def to_string(self):
|
||||
return self.full_name
|
||||
|
||||
def children(self):
|
||||
if not self.empty:
|
||||
yield self.name, self.active_variant
|
||||
|
||||
|
||||
class StdStringProvider:
|
||||
def __init__(self, valobj):
|
||||
self.valobj = valobj
|
||||
vec = valobj["vec"]
|
||||
self.length = int(vec["len"])
|
||||
self.data_ptr = unwrap_unique_or_non_null(vec["buf"]["ptr"])
|
||||
|
||||
def to_string(self):
|
||||
return self.data_ptr.lazy_string(encoding="utf-8", length=self.length)
|
||||
|
||||
@staticmethod
|
||||
def display_hint():
|
||||
return "string"
|
||||
|
||||
|
||||
class StdOsStringProvider:
|
||||
def __init__(self, valobj):
|
||||
self.valobj = valobj
|
||||
buf = self.valobj["inner"]["inner"]
|
||||
is_windows = "Wtf8Buf" in buf.type.name
|
||||
vec = buf[ZERO_FIELD] if is_windows else buf
|
||||
|
||||
self.length = int(vec["len"])
|
||||
self.data_ptr = unwrap_unique_or_non_null(vec["buf"]["ptr"])
|
||||
|
||||
def to_string(self):
|
||||
return self.data_ptr.lazy_string(encoding="utf-8", length=self.length)
|
||||
|
||||
def display_hint(self):
|
||||
return "string"
|
||||
|
||||
|
||||
class StdStrProvider:
|
||||
def __init__(self, valobj):
|
||||
self.valobj = valobj
|
||||
self.length = int(valobj["length"])
|
||||
self.data_ptr = valobj["data_ptr"]
|
||||
|
||||
def to_string(self):
|
||||
return self.data_ptr.lazy_string(encoding="utf-8", length=self.length)
|
||||
|
||||
@staticmethod
|
||||
def display_hint():
|
||||
return "string"
|
||||
|
||||
|
||||
class StdVecProvider:
|
||||
def __init__(self, valobj):
|
||||
self.valobj = valobj
|
||||
self.length = int(valobj["len"])
|
||||
self.data_ptr = unwrap_unique_or_non_null(valobj["buf"]["ptr"])
|
||||
|
||||
def to_string(self):
|
||||
return "Vec(size={})".format(self.length)
|
||||
|
||||
def children(self):
|
||||
saw_inaccessible = False
|
||||
for index in xrange(self.length):
|
||||
element_ptr = self.data_ptr + index
|
||||
if saw_inaccessible:
|
||||
return
|
||||
try:
|
||||
# rust-lang/rust#64343: passing deref expr to `str` allows
|
||||
# catching exception on garbage pointer
|
||||
str(element_ptr.dereference())
|
||||
yield "[{}]".format(index), element_ptr.dereference()
|
||||
except RuntimeError:
|
||||
saw_inaccessible = True
|
||||
yield str(index), "inaccessible"
|
||||
|
||||
@staticmethod
|
||||
def display_hint():
|
||||
return "array"
|
||||
|
||||
|
||||
class StdVecDequeProvider:
|
||||
def __init__(self, valobj):
|
||||
self.valobj = valobj
|
||||
self.head = int(valobj["head"])
|
||||
self.tail = int(valobj["tail"])
|
||||
self.cap = int(valobj["buf"]["cap"])
|
||||
self.data_ptr = unwrap_unique_or_non_null(valobj["buf"]["ptr"])
|
||||
if self.head >= self.tail:
|
||||
self.size = self.head - self.tail
|
||||
else:
|
||||
self.size = self.cap + self.head - self.tail
|
||||
|
||||
def to_string(self):
|
||||
return "VecDeque(size={})".format(self.size)
|
||||
|
||||
def children(self):
|
||||
for index in xrange(0, self.size):
|
||||
value = (self.data_ptr + ((self.tail + index) % self.cap)).dereference()
|
||||
yield "[{}]".format(index), value
|
||||
|
||||
@staticmethod
|
||||
def display_hint():
|
||||
return "array"
|
||||
|
||||
|
||||
class StdRcProvider:
|
||||
def __init__(self, valobj, is_atomic=False):
|
||||
self.valobj = valobj
|
||||
self.is_atomic = is_atomic
|
||||
self.ptr = unwrap_unique_or_non_null(valobj["ptr"])
|
||||
self.value = self.ptr["data" if is_atomic else "value"]
|
||||
self.strong = self.ptr["strong"]["v" if is_atomic else "value"]["value"]
|
||||
self.weak = self.ptr["weak"]["v" if is_atomic else "value"]["value"] - 1
|
||||
|
||||
def to_string(self):
|
||||
if self.is_atomic:
|
||||
return "Arc(strong={}, weak={})".format(int(self.strong), int(self.weak))
|
||||
else:
|
||||
return "Rc(strong={}, weak={})".format(int(self.strong), int(self.weak))
|
||||
|
||||
def children(self):
|
||||
yield "value", self.value
|
||||
yield "strong", self.strong
|
||||
yield "weak", self.weak
|
||||
|
||||
|
||||
class StdCellProvider:
|
||||
def __init__(self, valobj):
|
||||
self.value = valobj["value"]["value"]
|
||||
|
||||
def to_string(self):
|
||||
return "Cell"
|
||||
|
||||
def children(self):
|
||||
yield "value", self.value
|
||||
|
||||
|
||||
class StdRefProvider:
|
||||
def __init__(self, valobj):
|
||||
self.value = valobj["value"].dereference()
|
||||
self.borrow = valobj["borrow"]["borrow"]["value"]["value"]
|
||||
|
||||
def to_string(self):
|
||||
borrow = int(self.borrow)
|
||||
if borrow >= 0:
|
||||
return "Ref(borrow={})".format(borrow)
|
||||
else:
|
||||
return "Ref(borrow_mut={})".format(-borrow)
|
||||
|
||||
def children(self):
|
||||
yield "*value", self.value
|
||||
yield "borrow", self.borrow
|
||||
|
||||
|
||||
class StdRefCellProvider:
|
||||
def __init__(self, valobj):
|
||||
self.value = valobj["value"]["value"]
|
||||
self.borrow = valobj["borrow"]["value"]["value"]
|
||||
|
||||
def to_string(self):
|
||||
borrow = int(self.borrow)
|
||||
if borrow >= 0:
|
||||
return "RefCell(borrow={})".format(borrow)
|
||||
else:
|
||||
return "RefCell(borrow_mut={})".format(-borrow)
|
||||
|
||||
def children(self):
|
||||
yield "value", self.value
|
||||
yield "borrow", self.borrow
|
||||
|
||||
|
||||
# Yield each key (and optionally value) from a BoxedNode.
|
||||
def children_of_node(boxed_node, height, want_values):
|
||||
def cast_to_internal(node):
|
||||
internal_type_name = str(node.type.target()).replace("LeafNode", "InternalNode", 1)
|
||||
internal_type = lookup_type(internal_type_name)
|
||||
return node.cast(internal_type.pointer())
|
||||
|
||||
node_ptr = unwrap_unique_or_non_null(boxed_node["ptr"])
|
||||
node_ptr = cast_to_internal(node_ptr) if height > 0 else node_ptr
|
||||
leaf = node_ptr["data"] if height > 0 else node_ptr.dereference()
|
||||
keys = leaf["keys"]
|
||||
values = leaf["vals"]
|
||||
length = int(leaf["len"])
|
||||
|
||||
for i in xrange(0, length + 1):
|
||||
if height > 0:
|
||||
child_ptr = node_ptr["edges"][i]["value"]["value"]
|
||||
for child in children_of_node(child_ptr, height - 1, want_values):
|
||||
yield child
|
||||
if i < length:
|
||||
if want_values:
|
||||
yield keys[i]["value"]["value"], values[i]["value"]["value"]
|
||||
else:
|
||||
yield keys[i]["value"]["value"]
|
||||
|
||||
|
||||
class StdBTreeSetProvider:
|
||||
def __init__(self, valobj):
|
||||
self.valobj = valobj
|
||||
|
||||
def to_string(self):
|
||||
return "BTreeSet(size={})".format(self.valobj["map"]["length"])
|
||||
|
||||
def children(self):
|
||||
inner_map = self.valobj["map"]
|
||||
if inner_map["length"] > 0:
|
||||
root = inner_map["root"]
|
||||
if "core::option::Option<" in root.type.name:
|
||||
type_name = str(root.type.name).replace("core::option::Option<", "", 1)[:-1]
|
||||
root = root.cast(gdb.lookup_type(type_name))
|
||||
|
||||
node_ptr = root["node"]
|
||||
for i, child in enumerate(children_of_node(node_ptr, root["height"], False)):
|
||||
yield "[{}]".format(i), child
|
||||
|
||||
@staticmethod
|
||||
def display_hint():
|
||||
return "array"
|
||||
|
||||
|
||||
class StdBTreeMapProvider:
|
||||
def __init__(self, valobj):
|
||||
self.valobj = valobj
|
||||
|
||||
def to_string(self):
|
||||
return "BTreeMap(size={})".format(self.valobj["length"])
|
||||
|
||||
def children(self):
|
||||
if self.valobj["length"] > 0:
|
||||
root = self.valobj["root"]
|
||||
if "core::option::Option<" in root.type.name:
|
||||
type_name = str(root.type.name).replace("core::option::Option<", "", 1)[:-1]
|
||||
root = root.cast(gdb.lookup_type(type_name))
|
||||
|
||||
node_ptr = root["node"]
|
||||
for i, child in enumerate(children_of_node(node_ptr, root["height"], True)):
|
||||
yield "key{}".format(i), child[0]
|
||||
yield "val{}".format(i), child[1]
|
||||
|
||||
@staticmethod
|
||||
def display_hint():
|
||||
return "map"
|
||||
|
||||
|
||||
# BACKCOMPAT: rust 1.35
|
||||
class StdOldHashMapProvider:
|
||||
def __init__(self, valobj, show_values=True):
|
||||
self.valobj = valobj
|
||||
self.show_values = show_values
|
||||
|
||||
self.table = self.valobj["table"]
|
||||
self.size = int(self.table["size"])
|
||||
self.hashes = self.table["hashes"]
|
||||
self.hash_uint_type = self.hashes.type
|
||||
self.hash_uint_size = self.hashes.type.sizeof
|
||||
self.modulo = 2 ** self.hash_uint_size
|
||||
self.data_ptr = self.hashes[ZERO_FIELD]["pointer"]
|
||||
|
||||
self.capacity_mask = int(self.table["capacity_mask"])
|
||||
self.capacity = (self.capacity_mask + 1) % self.modulo
|
||||
|
||||
marker = self.table["marker"].type
|
||||
self.pair_type = marker.template_argument(0)
|
||||
self.pair_type_size = self.pair_type.sizeof
|
||||
|
||||
self.valid_indices = []
|
||||
for idx in range(self.capacity):
|
||||
data_ptr = self.data_ptr.cast(self.hash_uint_type.pointer())
|
||||
address = data_ptr + idx
|
||||
hash_uint = address.dereference()
|
||||
hash_ptr = hash_uint[ZERO_FIELD]["pointer"]
|
||||
if int(hash_ptr) != 0:
|
||||
self.valid_indices.append(idx)
|
||||
|
||||
def to_string(self):
|
||||
if self.show_values:
|
||||
return "HashMap(size={})".format(self.size)
|
||||
else:
|
||||
return "HashSet(size={})".format(self.size)
|
||||
|
||||
def children(self):
|
||||
start = int(self.data_ptr) & ~1
|
||||
|
||||
hashes = self.hash_uint_size * self.capacity
|
||||
align = self.pair_type_size
|
||||
len_rounded_up = (((((hashes + align) % self.modulo - 1) % self.modulo) & ~(
|
||||
(align - 1) % self.modulo)) % self.modulo - hashes) % self.modulo
|
||||
|
||||
pairs_offset = hashes + len_rounded_up
|
||||
pairs_start = gdb.Value(start + pairs_offset).cast(self.pair_type.pointer())
|
||||
|
||||
for index in range(self.size):
|
||||
table_index = self.valid_indices[index]
|
||||
idx = table_index & self.capacity_mask
|
||||
element = (pairs_start + idx).dereference()
|
||||
if self.show_values:
|
||||
yield "key{}".format(index), element[ZERO_FIELD]
|
||||
yield "val{}".format(index), element[FIRST_FIELD]
|
||||
else:
|
||||
yield "[{}]".format(index), element[ZERO_FIELD]
|
||||
|
||||
def display_hint(self):
|
||||
return "map" if self.show_values else "array"
|
||||
|
||||
|
||||
class StdHashMapProvider:
|
||||
def __init__(self, valobj, show_values=True):
|
||||
self.valobj = valobj
|
||||
self.show_values = show_values
|
||||
|
||||
table = self.valobj["base"]["table"]
|
||||
capacity = int(table["bucket_mask"]) + 1
|
||||
ctrl = table["ctrl"]["pointer"]
|
||||
|
||||
self.size = int(table["items"])
|
||||
self.data_ptr = table["data"]["pointer"]
|
||||
self.pair_type = self.data_ptr.dereference().type
|
||||
|
||||
self.valid_indices = []
|
||||
for idx in range(capacity):
|
||||
address = ctrl + idx
|
||||
value = address.dereference()
|
||||
is_presented = value & 128 == 0
|
||||
if is_presented:
|
||||
self.valid_indices.append(idx)
|
||||
|
||||
def to_string(self):
|
||||
if self.show_values:
|
||||
return "HashMap(size={})".format(self.size)
|
||||
else:
|
||||
return "HashSet(size={})".format(self.size)
|
||||
|
||||
def children(self):
|
||||
pairs_start = self.data_ptr
|
||||
|
||||
for index in range(self.size):
|
||||
idx = self.valid_indices[index]
|
||||
element = (pairs_start + idx).dereference()
|
||||
if self.show_values:
|
||||
yield "key{}".format(index), element[ZERO_FIELD]
|
||||
yield "val{}".format(index), element[FIRST_FIELD]
|
||||
else:
|
||||
yield "[{}]".format(index), element[ZERO_FIELD]
|
||||
|
||||
def display_hint(self):
|
||||
return "map" if self.show_values else "array"
|
@ -1,466 +0,0 @@
|
||||
import gdb
|
||||
import re
|
||||
import sys
|
||||
import debugger_pretty_printers_common as rustpp
|
||||
|
||||
# We want a version of `range` which doesn't allocate an intermediate list,
|
||||
# specifically it should use a lazy iterator. In Python 2 this was `xrange`, but
|
||||
# if we're running with Python 3 then we need to use `range` instead.
|
||||
if sys.version_info[0] >= 3:
|
||||
xrange = range
|
||||
|
||||
rust_enabled = 'set language rust' in gdb.execute('complete set language ru', to_string=True)
|
||||
|
||||
# The btree pretty-printers fail in a confusing way unless
|
||||
# https://sourceware.org/bugzilla/show_bug.cgi?id=21763 is fixed.
|
||||
# This fix went in 8.1, so check for that.
|
||||
# See https://github.com/rust-lang/rust/issues/56730
|
||||
gdb_81 = False
|
||||
_match = re.search('([0-9]+)\\.([0-9]+)', gdb.VERSION)
|
||||
if _match:
|
||||
if int(_match.group(1)) > 8 or (int(_match.group(1)) == 8 and int(_match.group(2)) >= 1):
|
||||
gdb_81 = True
|
||||
|
||||
# ===============================================================================
|
||||
# GDB Pretty Printing Module for Rust
|
||||
# ===============================================================================
|
||||
|
||||
|
||||
class GdbType(rustpp.Type):
|
||||
|
||||
def __init__(self, ty):
|
||||
super(GdbType, self).__init__()
|
||||
self.ty = ty
|
||||
self.fields = None
|
||||
|
||||
def get_unqualified_type_name(self):
|
||||
tag = self.ty.tag
|
||||
|
||||
if tag is None:
|
||||
return tag
|
||||
|
||||
return rustpp.extract_type_name(tag).replace("&'static ", "&")
|
||||
|
||||
def get_dwarf_type_kind(self):
|
||||
if self.ty.code == gdb.TYPE_CODE_STRUCT:
|
||||
return rustpp.DWARF_TYPE_CODE_STRUCT
|
||||
|
||||
if self.ty.code == gdb.TYPE_CODE_UNION:
|
||||
return rustpp.DWARF_TYPE_CODE_UNION
|
||||
|
||||
if self.ty.code == gdb.TYPE_CODE_PTR:
|
||||
return rustpp.DWARF_TYPE_CODE_PTR
|
||||
|
||||
if self.ty.code == gdb.TYPE_CODE_ENUM:
|
||||
return rustpp.DWARF_TYPE_CODE_ENUM
|
||||
|
||||
def get_fields(self):
|
||||
assert ((self.get_dwarf_type_kind() == rustpp.DWARF_TYPE_CODE_STRUCT) or
|
||||
(self.get_dwarf_type_kind() == rustpp.DWARF_TYPE_CODE_UNION))
|
||||
if self.fields is None:
|
||||
self.fields = list(self.ty.fields())
|
||||
return self.fields
|
||||
|
||||
def get_wrapped_value(self):
|
||||
return self.ty
|
||||
|
||||
|
||||
class GdbValue(rustpp.Value):
|
||||
def __init__(self, gdb_val):
|
||||
super(GdbValue, self).__init__(GdbType(gdb_val.type))
|
||||
self.gdb_val = gdb_val
|
||||
self.children = {}
|
||||
|
||||
def get_child_at_index(self, index):
|
||||
child = self.children.get(index)
|
||||
if child is None:
|
||||
gdb_field = get_field_at_index(self.gdb_val, index)
|
||||
child = GdbValue(self.gdb_val[gdb_field])
|
||||
self.children[index] = child
|
||||
return child
|
||||
|
||||
def as_integer(self):
|
||||
if self.gdb_val.type.code == gdb.TYPE_CODE_PTR:
|
||||
as_str = rustpp.compat_str(self.gdb_val).split()[0]
|
||||
return int(as_str, 0)
|
||||
return int(self.gdb_val)
|
||||
|
||||
def get_wrapped_value(self):
|
||||
return self.gdb_val
|
||||
|
||||
|
||||
def register_printers(objfile):
|
||||
"""Registers Rust pretty printers for the given objfile"""
|
||||
objfile.pretty_printers.append(rust_pretty_printer_lookup_function)
|
||||
|
||||
|
||||
def rust_pretty_printer_lookup_function(gdb_val):
|
||||
"""
|
||||
Returns the correct Rust pretty printer for the given value
|
||||
if there is one
|
||||
"""
|
||||
|
||||
val = GdbValue(gdb_val)
|
||||
type_kind = val.type.get_type_kind()
|
||||
|
||||
if type_kind == rustpp.TYPE_KIND_SLICE:
|
||||
return RustSlicePrinter(val)
|
||||
|
||||
if type_kind == rustpp.TYPE_KIND_STD_VEC:
|
||||
return RustStdVecPrinter(val)
|
||||
|
||||
if type_kind == rustpp.TYPE_KIND_STD_VECDEQUE:
|
||||
return RustStdVecDequePrinter(val)
|
||||
|
||||
if type_kind == rustpp.TYPE_KIND_STD_BTREESET and gdb_81:
|
||||
return RustStdBTreeSetPrinter(val)
|
||||
|
||||
if type_kind == rustpp.TYPE_KIND_STD_BTREEMAP and gdb_81:
|
||||
return RustStdBTreeMapPrinter(val)
|
||||
|
||||
if type_kind == rustpp.TYPE_KIND_STD_STRING:
|
||||
return RustStdStringPrinter(val)
|
||||
|
||||
if type_kind == rustpp.TYPE_KIND_OS_STRING:
|
||||
return RustOsStringPrinter(val)
|
||||
|
||||
# Checks after this point should only be for "compiler" types --
|
||||
# things that gdb's Rust language support knows about.
|
||||
if rust_enabled:
|
||||
return None
|
||||
|
||||
if type_kind == rustpp.TYPE_KIND_EMPTY:
|
||||
return RustEmptyPrinter(val)
|
||||
|
||||
if type_kind == rustpp.TYPE_KIND_REGULAR_STRUCT:
|
||||
return RustStructPrinter(val,
|
||||
omit_first_field=False,
|
||||
omit_type_name=False,
|
||||
is_tuple_like=False)
|
||||
|
||||
if type_kind == rustpp.TYPE_KIND_STRUCT_VARIANT:
|
||||
return RustStructPrinter(val,
|
||||
omit_first_field=True,
|
||||
omit_type_name=False,
|
||||
is_tuple_like=False)
|
||||
|
||||
if type_kind == rustpp.TYPE_KIND_STR_SLICE:
|
||||
return RustStringSlicePrinter(val)
|
||||
|
||||
if type_kind == rustpp.TYPE_KIND_TUPLE:
|
||||
return RustStructPrinter(val,
|
||||
omit_first_field=False,
|
||||
omit_type_name=True,
|
||||
is_tuple_like=True)
|
||||
|
||||
if type_kind == rustpp.TYPE_KIND_TUPLE_STRUCT:
|
||||
return RustStructPrinter(val,
|
||||
omit_first_field=False,
|
||||
omit_type_name=False,
|
||||
is_tuple_like=True)
|
||||
|
||||
if type_kind == rustpp.TYPE_KIND_CSTYLE_VARIANT:
|
||||
return RustCStyleVariantPrinter(val.get_child_at_index(0))
|
||||
|
||||
if type_kind == rustpp.TYPE_KIND_TUPLE_VARIANT:
|
||||
return RustStructPrinter(val,
|
||||
omit_first_field=True,
|
||||
omit_type_name=False,
|
||||
is_tuple_like=True)
|
||||
|
||||
if type_kind == rustpp.TYPE_KIND_SINGLETON_ENUM:
|
||||
variant = get_field_at_index(gdb_val, 0)
|
||||
return rust_pretty_printer_lookup_function(gdb_val[variant])
|
||||
|
||||
if type_kind == rustpp.TYPE_KIND_REGULAR_ENUM:
|
||||
# This is a regular enum, extract the discriminant
|
||||
discriminant_val = rustpp.get_discriminant_value_as_integer(val)
|
||||
variant = get_field_at_index(gdb_val, discriminant_val)
|
||||
return rust_pretty_printer_lookup_function(gdb_val[variant])
|
||||
|
||||
if type_kind == rustpp.TYPE_KIND_COMPRESSED_ENUM:
|
||||
encoded_enum_info = rustpp.EncodedEnumInfo(val)
|
||||
if encoded_enum_info.is_null_variant():
|
||||
return IdentityPrinter(encoded_enum_info.get_null_variant_name())
|
||||
|
||||
non_null_val = encoded_enum_info.get_non_null_variant_val()
|
||||
return rust_pretty_printer_lookup_function(non_null_val.get_wrapped_value())
|
||||
|
||||
# No pretty printer has been found
|
||||
return None
|
||||
|
||||
|
||||
# =------------------------------------------------------------------------------
|
||||
# Pretty Printer Classes
|
||||
# =------------------------------------------------------------------------------
|
||||
class RustEmptyPrinter(object):
|
||||
def __init__(self, val):
|
||||
self.__val = val
|
||||
|
||||
def to_string(self):
|
||||
return self.__val.type.get_unqualified_type_name()
|
||||
|
||||
|
||||
class RustStructPrinter(object):
|
||||
def __init__(self, val, omit_first_field, omit_type_name, is_tuple_like):
|
||||
self.__val = val
|
||||
self.__omit_first_field = omit_first_field
|
||||
self.__omit_type_name = omit_type_name
|
||||
self.__is_tuple_like = is_tuple_like
|
||||
|
||||
def to_string(self):
|
||||
if self.__omit_type_name:
|
||||
return None
|
||||
return self.__val.type.get_unqualified_type_name()
|
||||
|
||||
def children(self):
|
||||
cs = []
|
||||
wrapped_value = self.__val.get_wrapped_value()
|
||||
|
||||
for number, field in enumerate(self.__val.type.get_fields()):
|
||||
field_value = wrapped_value[field.name]
|
||||
if self.__is_tuple_like:
|
||||
cs.append((str(number), field_value))
|
||||
else:
|
||||
cs.append((field.name, field_value))
|
||||
|
||||
if self.__omit_first_field:
|
||||
cs = cs[1:]
|
||||
|
||||
return cs
|
||||
|
||||
def display_hint(self):
|
||||
if self.__is_tuple_like:
|
||||
return "array"
|
||||
else:
|
||||
return ""
|
||||
|
||||
|
||||
class RustSlicePrinter(object):
|
||||
def __init__(self, val):
|
||||
self.__val = val
|
||||
|
||||
@staticmethod
|
||||
def display_hint():
|
||||
return "array"
|
||||
|
||||
def to_string(self):
|
||||
(length, data_ptr) = rustpp.extract_length_and_ptr_from_slice(self.__val)
|
||||
return (self.__val.type.get_unqualified_type_name() +
|
||||
("(len: %i)" % length))
|
||||
|
||||
def children(self):
|
||||
(length, data_ptr) = rustpp.extract_length_and_ptr_from_slice(self.__val)
|
||||
assert data_ptr.type.get_dwarf_type_kind() == rustpp.DWARF_TYPE_CODE_PTR
|
||||
raw_ptr = data_ptr.get_wrapped_value()
|
||||
|
||||
for index in xrange(0, length):
|
||||
yield (str(index), (raw_ptr + index).dereference())
|
||||
|
||||
|
||||
class RustStringSlicePrinter(object):
|
||||
def __init__(self, val):
|
||||
self.__val = val
|
||||
|
||||
def to_string(self):
|
||||
(length, data_ptr) = rustpp.extract_length_and_ptr_from_slice(self.__val)
|
||||
raw_ptr = data_ptr.get_wrapped_value()
|
||||
return raw_ptr.lazy_string(encoding="utf-8", length=length)
|
||||
|
||||
def display_hint(self):
|
||||
return "string"
|
||||
|
||||
|
||||
class RustStdVecPrinter(object):
|
||||
def __init__(self, val):
|
||||
self.__val = val
|
||||
|
||||
@staticmethod
|
||||
def display_hint():
|
||||
return "array"
|
||||
|
||||
def to_string(self):
|
||||
(length, data_ptr, cap) = rustpp.extract_length_ptr_and_cap_from_std_vec(self.__val)
|
||||
return (self.__val.type.get_unqualified_type_name() +
|
||||
("(len: %i, cap: %i)" % (length, cap)))
|
||||
|
||||
def children(self):
|
||||
saw_inaccessible = False
|
||||
(length, data_ptr, cap) = rustpp.extract_length_ptr_and_cap_from_std_vec(self.__val)
|
||||
gdb_ptr = data_ptr.get_wrapped_value()
|
||||
for index in xrange(0, length):
|
||||
if saw_inaccessible:
|
||||
return
|
||||
try:
|
||||
# rust-lang/rust#64343: passing deref expr to `str` allows
|
||||
# catching exception on garbage pointer
|
||||
str((gdb_ptr + index).dereference())
|
||||
yield (str(index), (gdb_ptr + index).dereference())
|
||||
except RuntimeError:
|
||||
saw_inaccessible = True
|
||||
yield (str(index), "inaccessible")
|
||||
|
||||
|
||||
class RustStdVecDequePrinter(object):
|
||||
def __init__(self, val):
|
||||
self.__val = val
|
||||
|
||||
@staticmethod
|
||||
def display_hint():
|
||||
return "array"
|
||||
|
||||
def to_string(self):
|
||||
(tail, head, data_ptr, cap) = \
|
||||
rustpp.extract_tail_head_ptr_and_cap_from_std_vecdeque(self.__val)
|
||||
if head >= tail:
|
||||
size = head - tail
|
||||
else:
|
||||
size = cap + head - tail
|
||||
return (self.__val.type.get_unqualified_type_name() +
|
||||
("(len: %i, cap: %i)" % (size, cap)))
|
||||
|
||||
def children(self):
|
||||
(tail, head, data_ptr, cap) = \
|
||||
rustpp.extract_tail_head_ptr_and_cap_from_std_vecdeque(self.__val)
|
||||
gdb_ptr = data_ptr.get_wrapped_value()
|
||||
if head >= tail:
|
||||
size = head - tail
|
||||
else:
|
||||
size = cap + head - tail
|
||||
for index in xrange(0, size):
|
||||
yield (str(index), (gdb_ptr + ((tail + index) % cap)).dereference())
|
||||
|
||||
|
||||
# Yield each key (and optionally value) from a BoxedNode.
|
||||
def children_of_node(boxed_node, height, want_values):
|
||||
node_ptr = boxed_node['ptr']['pointer']
|
||||
if height > 0:
|
||||
type_name = str(node_ptr.type.target()).replace('LeafNode', 'InternalNode', 1)
|
||||
node_type = gdb.lookup_type(type_name)
|
||||
node_ptr = node_ptr.cast(node_type.pointer())
|
||||
leaf = node_ptr['data']
|
||||
else:
|
||||
leaf = node_ptr.dereference()
|
||||
keys = leaf['keys']
|
||||
if want_values:
|
||||
values = leaf['vals']
|
||||
length = int(leaf['len'])
|
||||
for i in xrange(0, length + 1):
|
||||
if height > 0:
|
||||
child_ptr = node_ptr['edges'][i]['value']['value']
|
||||
for child in children_of_node(child_ptr, height - 1, want_values):
|
||||
yield child
|
||||
if i < length:
|
||||
if want_values:
|
||||
yield (keys[i]['value']['value'], values[i]['value']['value'])
|
||||
else:
|
||||
yield keys[i]['value']['value']
|
||||
|
||||
|
||||
class RustStdBTreeSetPrinter(object):
|
||||
def __init__(self, val):
|
||||
self.__val = val
|
||||
|
||||
@staticmethod
|
||||
def display_hint():
|
||||
return "array"
|
||||
|
||||
def to_string(self):
|
||||
return (self.__val.type.get_unqualified_type_name() +
|
||||
("(len: %i)" % self.__val.get_wrapped_value()['map']['length']))
|
||||
|
||||
def children(self):
|
||||
prev_idx = None
|
||||
innermap = GdbValue(self.__val.get_wrapped_value()['map'])
|
||||
if innermap.get_wrapped_value()['length'] > 0:
|
||||
root = GdbValue(innermap.get_wrapped_value()['root'])
|
||||
type_name = str(root.type.ty.name).replace('core::option::Option<', '', 1)[:-1]
|
||||
root = root.get_wrapped_value().cast(gdb.lookup_type(type_name))
|
||||
node_ptr = root['node']
|
||||
i = 0
|
||||
for child in children_of_node(node_ptr, root['height'], False):
|
||||
yield (str(i), child)
|
||||
i = i + 1
|
||||
|
||||
|
||||
class RustStdBTreeMapPrinter(object):
|
||||
def __init__(self, val):
|
||||
self.__val = val
|
||||
|
||||
@staticmethod
|
||||
def display_hint():
|
||||
return "map"
|
||||
|
||||
def to_string(self):
|
||||
return (self.__val.type.get_unqualified_type_name() +
|
||||
("(len: %i)" % self.__val.get_wrapped_value()['length']))
|
||||
|
||||
def children(self):
|
||||
if self.__val.get_wrapped_value()['length'] > 0:
|
||||
root = GdbValue(self.__val.get_wrapped_value()['root'])
|
||||
type_name = str(root.type.ty.name).replace('core::option::Option<', '', 1)[:-1]
|
||||
root = root.get_wrapped_value().cast(gdb.lookup_type(type_name))
|
||||
node_ptr = root['node']
|
||||
i = 0
|
||||
for child in children_of_node(node_ptr, root['height'], True):
|
||||
yield (str(i), child[0])
|
||||
yield (str(i), child[1])
|
||||
i = i + 1
|
||||
|
||||
|
||||
class RustStdStringPrinter(object):
|
||||
def __init__(self, val):
|
||||
self.__val = val
|
||||
|
||||
def to_string(self):
|
||||
vec = self.__val.get_child_at_index(0)
|
||||
(length, data_ptr, cap) = rustpp.extract_length_ptr_and_cap_from_std_vec(vec)
|
||||
return data_ptr.get_wrapped_value().lazy_string(encoding="utf-8",
|
||||
length=length)
|
||||
|
||||
def display_hint(self):
|
||||
return "string"
|
||||
|
||||
|
||||
class RustOsStringPrinter(object):
|
||||
def __init__(self, val):
|
||||
self.__val = val
|
||||
|
||||
def to_string(self):
|
||||
buf = self.__val.get_child_at_index(0)
|
||||
vec = buf.get_child_at_index(0)
|
||||
if vec.type.get_unqualified_type_name() == "Wtf8Buf":
|
||||
vec = vec.get_child_at_index(0)
|
||||
|
||||
(length, data_ptr, cap) = rustpp.extract_length_ptr_and_cap_from_std_vec(
|
||||
vec)
|
||||
return data_ptr.get_wrapped_value().lazy_string(length=length)
|
||||
|
||||
def display_hint(self):
|
||||
return "string"
|
||||
|
||||
|
||||
class RustCStyleVariantPrinter(object):
|
||||
def __init__(self, val):
|
||||
assert val.type.get_dwarf_type_kind() == rustpp.DWARF_TYPE_CODE_ENUM
|
||||
self.__val = val
|
||||
|
||||
def to_string(self):
|
||||
return str(self.__val.get_wrapped_value())
|
||||
|
||||
|
||||
class IdentityPrinter(object):
|
||||
def __init__(self, string):
|
||||
self.string = string
|
||||
|
||||
def to_string(self):
|
||||
return self.string
|
||||
|
||||
|
||||
def get_field_at_index(gdb_val, index):
|
||||
i = 0
|
||||
for field in gdb_val.type.fields():
|
||||
if i == index:
|
||||
return field
|
||||
i += 1
|
||||
return None
|
19
src/etc/lldb_commands
Normal file
19
src/etc/lldb_commands
Normal file
@ -0,0 +1,19 @@
|
||||
command script import \"$RUSTC_SYSROOT/lib/rustlib/etc/lldb_lookup.py\"
|
||||
type synthetic add -l lldb_lookup.synthetic_lookup -x \".*\" --category Rust
|
||||
type summary add -F lldb_lookup.summary_lookup -e -x -h \"^(alloc::([a-z_]+::)+)String$\" --category Rust
|
||||
type summary add -F lldb_lookup.summary_lookup -e -x -h \"^&str$\" --category Rust
|
||||
type summary add -F lldb_lookup.summary_lookup -e -x -h \"^&\\[.+\\]$\" --category Rust
|
||||
type summary add -F lldb_lookup.summary_lookup -e -x -h \"^(std::ffi::([a-z_]+::)+)OsString$\" --category Rust
|
||||
type summary add -F lldb_lookup.summary_lookup -e -x -h \"^(alloc::([a-z_]+::)+)Vec<.+>$\" --category Rust
|
||||
type summary add -F lldb_lookup.summary_lookup -e -x -h \"^(alloc::([a-z_]+::)+)VecDeque<.+>$\" --category Rust
|
||||
type summary add -F lldb_lookup.summary_lookup -e -x -h \"^(alloc::([a-z_]+::)+)BTreeSet<.+>$\" --category Rust
|
||||
type summary add -F lldb_lookup.summary_lookup -e -x -h \"^(alloc::([a-z_]+::)+)BTreeMap<.+>$\" --category Rust
|
||||
type summary add -F lldb_lookup.summary_lookup -e -x -h \"^(std::collections::([a-z_]+::)+)HashMap<.+>$\" --category Rust
|
||||
type summary add -F lldb_lookup.summary_lookup -e -x -h \"^(std::collections::([a-z_]+::)+)HashSet<.+>$\" --category Rust
|
||||
type summary add -F lldb_lookup.summary_lookup -e -x -h \"^(alloc::([a-z_]+::)+)Rc<.+>$\" --category Rust
|
||||
type summary add -F lldb_lookup.summary_lookup -e -x -h \"^(alloc::([a-z_]+::)+)Arc<.+>$\" --category Rust
|
||||
type summary add -F lldb_lookup.summary_lookup -e -x -h \"^(core::([a-z_]+::)+)Cell<.+>$\" --category Rust
|
||||
type summary add -F lldb_lookup.summary_lookup -e -x -h \"^(core::([a-z_]+::)+)Ref<.+>$\" --category Rust
|
||||
type summary add -F lldb_lookup.summary_lookup -e -x -h \"^(core::([a-z_]+::)+)RefMut<.+>$\" --category Rust
|
||||
type summary add -F lldb_lookup.summary_lookup -e -x -h \"^(core::([a-z_]+::)+)RefCell<.+>$\" --category Rust
|
||||
type category enable Rust
|
115
src/etc/lldb_lookup.py
Normal file
115
src/etc/lldb_lookup.py
Normal file
@ -0,0 +1,115 @@
|
||||
import lldb
|
||||
|
||||
from lldb_providers import *
|
||||
from rust_types import RustType, classify_struct, classify_union
|
||||
|
||||
|
||||
# BACKCOMPAT: rust 1.35
|
||||
def is_hashbrown_hashmap(hash_map):
|
||||
return len(hash_map.type.fields) == 1
|
||||
|
||||
|
||||
def classify_rust_type(type):
|
||||
type_class = type.GetTypeClass()
|
||||
if type_class == lldb.eTypeClassStruct:
|
||||
return classify_struct(type.name, type.fields)
|
||||
if type_class == lldb.eTypeClassUnion:
|
||||
return classify_union(type.fields)
|
||||
|
||||
return RustType.OTHER
|
||||
|
||||
|
||||
def summary_lookup(valobj, dict):
|
||||
# type: (SBValue, dict) -> str
|
||||
"""Returns the summary provider for the given value"""
|
||||
rust_type = classify_rust_type(valobj.GetType())
|
||||
|
||||
if rust_type == RustType.STD_STRING:
|
||||
return StdStringSummaryProvider(valobj, dict)
|
||||
if rust_type == RustType.STD_OS_STRING:
|
||||
return StdOsStringSummaryProvider(valobj, dict)
|
||||
if rust_type == RustType.STD_STR:
|
||||
return StdStrSummaryProvider(valobj, dict)
|
||||
|
||||
if rust_type == RustType.STD_VEC:
|
||||
return SizeSummaryProvider(valobj, dict)
|
||||
if rust_type == RustType.STD_VEC_DEQUE:
|
||||
return SizeSummaryProvider(valobj, dict)
|
||||
if rust_type == RustType.STD_SLICE:
|
||||
return SizeSummaryProvider(valobj, dict)
|
||||
|
||||
if rust_type == RustType.STD_HASH_MAP:
|
||||
return SizeSummaryProvider(valobj, dict)
|
||||
if rust_type == RustType.STD_HASH_SET:
|
||||
return SizeSummaryProvider(valobj, dict)
|
||||
|
||||
if rust_type == RustType.STD_RC:
|
||||
return StdRcSummaryProvider(valobj, dict)
|
||||
if rust_type == RustType.STD_ARC:
|
||||
return StdRcSummaryProvider(valobj, dict)
|
||||
|
||||
if rust_type == RustType.STD_REF:
|
||||
return StdRefSummaryProvider(valobj, dict)
|
||||
if rust_type == RustType.STD_REF_MUT:
|
||||
return StdRefSummaryProvider(valobj, dict)
|
||||
if rust_type == RustType.STD_REF_CELL:
|
||||
return StdRefSummaryProvider(valobj, dict)
|
||||
|
||||
return ""
|
||||
|
||||
|
||||
def synthetic_lookup(valobj, dict):
|
||||
# type: (SBValue, dict) -> object
|
||||
"""Returns the synthetic provider for the given value"""
|
||||
rust_type = classify_rust_type(valobj.GetType())
|
||||
|
||||
if rust_type == RustType.STRUCT:
|
||||
return StructSyntheticProvider(valobj, dict)
|
||||
if rust_type == RustType.STRUCT_VARIANT:
|
||||
return StructSyntheticProvider(valobj, dict, is_variant=True)
|
||||
if rust_type == RustType.TUPLE:
|
||||
return TupleSyntheticProvider(valobj, dict)
|
||||
if rust_type == RustType.TUPLE_VARIANT:
|
||||
return TupleSyntheticProvider(valobj, dict, is_variant=True)
|
||||
if rust_type == RustType.EMPTY:
|
||||
return EmptySyntheticProvider(valobj, dict)
|
||||
if rust_type == RustType.REGULAR_ENUM:
|
||||
discriminant = valobj.GetChildAtIndex(0).GetChildAtIndex(0).GetValueAsUnsigned()
|
||||
return synthetic_lookup(valobj.GetChildAtIndex(discriminant), dict)
|
||||
if rust_type == RustType.SINGLETON_ENUM:
|
||||
return synthetic_lookup(valobj.GetChildAtIndex(0), dict)
|
||||
|
||||
if rust_type == RustType.STD_VEC:
|
||||
return StdVecSyntheticProvider(valobj, dict)
|
||||
if rust_type == RustType.STD_VEC_DEQUE:
|
||||
return StdVecDequeSyntheticProvider(valobj, dict)
|
||||
if rust_type == RustType.STD_SLICE:
|
||||
return StdSliceSyntheticProvider(valobj, dict)
|
||||
|
||||
if rust_type == RustType.STD_HASH_MAP:
|
||||
if is_hashbrown_hashmap(valobj):
|
||||
return StdHashMapSyntheticProvider(valobj, dict)
|
||||
else:
|
||||
return StdOldHashMapSyntheticProvider(valobj, dict)
|
||||
if rust_type == RustType.STD_HASH_SET:
|
||||
hash_map = valobj.GetChildAtIndex(0)
|
||||
if is_hashbrown_hashmap(hash_map):
|
||||
return StdHashMapSyntheticProvider(hash_map, dict, show_values=False)
|
||||
else:
|
||||
return StdOldHashMapSyntheticProvider(hash_map, dict, show_values=False)
|
||||
|
||||
if rust_type == RustType.STD_RC:
|
||||
return StdRcSyntheticProvider(valobj, dict)
|
||||
if rust_type == RustType.STD_ARC:
|
||||
return StdRcSyntheticProvider(valobj, dict, is_atomic=True)
|
||||
|
||||
if rust_type == RustType.STD_CELL:
|
||||
return StdCellSyntheticProvider(valobj, dict)
|
||||
if rust_type == RustType.STD_REF:
|
||||
return StdRefSyntheticProvider(valobj, dict)
|
||||
if rust_type == RustType.STD_REF_MUT:
|
||||
return StdRefSyntheticProvider(valobj, dict)
|
||||
if rust_type == RustType.STD_REF_CELL:
|
||||
return StdRefSyntheticProvider(valobj, dict, is_cell=True)
|
||||
|
||||
return DefaultSynthteticProvider(valobj, dict)
|
715
src/etc/lldb_providers.py
Normal file
715
src/etc/lldb_providers.py
Normal file
@ -0,0 +1,715 @@
|
||||
import sys
|
||||
|
||||
from lldb import SBValue, SBData, SBError, eBasicTypeLong, eBasicTypeUnsignedLong, \
|
||||
eBasicTypeUnsignedChar
|
||||
|
||||
# from lldb.formatters import Logger
|
||||
|
||||
####################################################################################################
|
||||
# This file contains two kinds of pretty-printers: summary and synthetic.
|
||||
#
|
||||
# Important classes from LLDB module:
|
||||
# SBValue: the value of a variable, a register, or an expression
|
||||
# SBType: the data type; each SBValue has a corresponding SBType
|
||||
#
|
||||
# Summary provider is a function with the type `(SBValue, dict) -> str`.
|
||||
# The first parameter is the object encapsulating the actual variable being displayed;
|
||||
# The second parameter is an internal support parameter used by LLDB, and you should not touch it.
|
||||
#
|
||||
# Synthetic children is the way to provide a children-based representation of the object's value.
|
||||
# Synthetic provider is a class that implements the following interface:
|
||||
#
|
||||
# class SyntheticChildrenProvider:
|
||||
# def __init__(self, SBValue, dict)
|
||||
# def num_children(self)
|
||||
# def get_child_index(self, str)
|
||||
# def get_child_at_index(self, int)
|
||||
# def update(self)
|
||||
# def has_children(self)
|
||||
# def get_value(self)
|
||||
#
|
||||
#
|
||||
# You can find more information and examples here:
|
||||
# 1. https://lldb.llvm.org/varformats.html
|
||||
# 2. https://lldb.llvm.org/python-reference.html
|
||||
# 3. https://lldb.llvm.org/python_reference/lldb.formatters.cpp.libcxx-pysrc.html
|
||||
# 4. https://github.com/llvm-mirror/lldb/tree/master/examples/summaries/cocoa
|
||||
####################################################################################################
|
||||
|
||||
PY3 = sys.version_info[0] == 3
|
||||
|
||||
|
||||
class ValueBuilder:
|
||||
def __init__(self, valobj):
|
||||
# type: (SBValue) -> ValueBuilder
|
||||
self.valobj = valobj
|
||||
process = valobj.GetProcess()
|
||||
self.endianness = process.GetByteOrder()
|
||||
self.pointer_size = process.GetAddressByteSize()
|
||||
|
||||
def from_int(self, name, value):
|
||||
# type: (str, int) -> SBValue
|
||||
type = self.valobj.GetType().GetBasicType(eBasicTypeLong)
|
||||
data = SBData.CreateDataFromSInt64Array(self.endianness, self.pointer_size, [value])
|
||||
return self.valobj.CreateValueFromData(name, data, type)
|
||||
|
||||
def from_uint(self, name, value):
|
||||
# type: (str, int) -> SBValue
|
||||
type = self.valobj.GetType().GetBasicType(eBasicTypeUnsignedLong)
|
||||
data = SBData.CreateDataFromUInt64Array(self.endianness, self.pointer_size, [value])
|
||||
return self.valobj.CreateValueFromData(name, data, type)
|
||||
|
||||
|
||||
def unwrap_unique_or_non_null(unique_or_nonnull):
|
||||
# BACKCOMPAT: rust 1.32
|
||||
# https://github.com/rust-lang/rust/commit/7a0911528058e87d22ea305695f4047572c5e067
|
||||
ptr = unique_or_nonnull.GetChildMemberWithName("pointer")
|
||||
return ptr if ptr.TypeIsPointerType() else ptr.GetChildAtIndex(0)
|
||||
|
||||
|
||||
class DefaultSynthteticProvider:
|
||||
def __init__(self, valobj, dict):
|
||||
# type: (SBValue, dict) -> DefaultSynthteticProvider
|
||||
# logger = Logger.Logger()
|
||||
# logger >> "Default synthetic provider for " + str(valobj.GetName())
|
||||
self.valobj = valobj
|
||||
|
||||
def num_children(self):
|
||||
# type: () -> int
|
||||
return self.valobj.GetNumChildren()
|
||||
|
||||
def get_child_index(self, name):
|
||||
# type: (str) -> int
|
||||
return self.valobj.GetIndexOfChildWithName(name)
|
||||
|
||||
def get_child_at_index(self, index):
|
||||
# type: (int) -> SBValue
|
||||
return self.valobj.GetChildAtIndex(index)
|
||||
|
||||
def update(self):
|
||||
# type: () -> None
|
||||
pass
|
||||
|
||||
def has_children(self):
|
||||
# type: () -> bool
|
||||
return self.valobj.MightHaveChildren()
|
||||
|
||||
|
||||
class EmptySyntheticProvider:
|
||||
def __init__(self, valobj, dict):
|
||||
# type: (SBValue, dict) -> EmptySyntheticProvider
|
||||
# logger = Logger.Logger()
|
||||
# logger >> "[EmptySyntheticProvider] for " + str(valobj.GetName())
|
||||
self.valobj = valobj
|
||||
|
||||
def num_children(self):
|
||||
# type: () -> int
|
||||
return 0
|
||||
|
||||
def get_child_index(self, name):
|
||||
# type: (str) -> int
|
||||
return None
|
||||
|
||||
def get_child_at_index(self, index):
|
||||
# type: (int) -> SBValue
|
||||
return None
|
||||
|
||||
def update(self):
|
||||
# type: () -> None
|
||||
pass
|
||||
|
||||
def has_children(self):
|
||||
# type: () -> bool
|
||||
return False
|
||||
|
||||
|
||||
def SizeSummaryProvider(valobj, dict):
|
||||
# type: (SBValue, dict) -> str
|
||||
return 'size=' + str(valobj.GetNumChildren())
|
||||
|
||||
|
||||
def vec_to_string(vec):
|
||||
length = vec.GetNumChildren()
|
||||
chars = [vec.GetChildAtIndex(i).GetValueAsUnsigned() for i in range(length)]
|
||||
return bytes(chars).decode(errors='replace') if PY3 else "".join(chr(char) for char in chars)
|
||||
|
||||
|
||||
def StdStringSummaryProvider(valobj, dict):
|
||||
# type: (SBValue, dict) -> str
|
||||
# logger = Logger.Logger()
|
||||
# logger >> "[StdStringSummaryProvider] for " + str(valobj.GetName())
|
||||
vec = valobj.GetChildAtIndex(0)
|
||||
return '"%s"' % vec_to_string(vec)
|
||||
|
||||
|
||||
def StdOsStringSummaryProvider(valobj, dict):
|
||||
# type: (SBValue, dict) -> str
|
||||
# logger = Logger.Logger()
|
||||
# logger >> "[StdOsStringSummaryProvider] for " + str(valobj.GetName())
|
||||
buf = valobj.GetChildAtIndex(0).GetChildAtIndex(0)
|
||||
is_windows = "Wtf8Buf" in buf.type.name
|
||||
vec = buf.GetChildAtIndex(0) if is_windows else buf
|
||||
return '"%s"' % vec_to_string(vec)
|
||||
|
||||
|
||||
def StdStrSummaryProvider(valobj, dict):
|
||||
# type: (SBValue, dict) -> str
|
||||
# logger = Logger.Logger()
|
||||
# logger >> "[StdStrSummaryProvider] for " + str(valobj.GetName())
|
||||
|
||||
length = valobj.GetChildMemberWithName("length").GetValueAsUnsigned()
|
||||
if length == 0:
|
||||
return '""'
|
||||
|
||||
data_ptr = valobj.GetChildMemberWithName("data_ptr")
|
||||
|
||||
start = data_ptr.GetValueAsUnsigned()
|
||||
error = SBError()
|
||||
process = data_ptr.GetProcess()
|
||||
data = process.ReadMemory(start, length, error)
|
||||
data = data.decode(encoding='UTF-8') if PY3 else data
|
||||
return '"%s"' % data
|
||||
|
||||
|
||||
class StructSyntheticProvider:
|
||||
"""Pretty-printer for structs and struct enum variants"""
|
||||
|
||||
def __init__(self, valobj, dict, is_variant=False):
|
||||
# type: (SBValue, dict, bool) -> StructSyntheticProvider
|
||||
# logger = Logger.Logger()
|
||||
self.valobj = valobj
|
||||
self.is_variant = is_variant
|
||||
self.type = valobj.GetType()
|
||||
self.fields = {}
|
||||
|
||||
if is_variant:
|
||||
self.fields_count = self.type.GetNumberOfFields() - 1
|
||||
real_fields = self.type.fields[1:]
|
||||
else:
|
||||
self.fields_count = self.type.GetNumberOfFields()
|
||||
real_fields = self.type.fields
|
||||
|
||||
for number, field in enumerate(real_fields):
|
||||
self.fields[field.name] = number
|
||||
|
||||
def num_children(self):
|
||||
# type: () -> int
|
||||
return self.fields_count
|
||||
|
||||
def get_child_index(self, name):
|
||||
# type: (str) -> int
|
||||
return self.fields.get(name, -1)
|
||||
|
||||
def get_child_at_index(self, index):
|
||||
# type: (int) -> SBValue
|
||||
if self.is_variant:
|
||||
field = self.type.GetFieldAtIndex(index + 1)
|
||||
else:
|
||||
field = self.type.GetFieldAtIndex(index)
|
||||
return self.valobj.GetChildMemberWithName(field.name)
|
||||
|
||||
def update(self):
|
||||
# type: () -> None
|
||||
pass
|
||||
|
||||
def has_children(self):
|
||||
# type: () -> bool
|
||||
return True
|
||||
|
||||
|
||||
class TupleSyntheticProvider:
|
||||
"""Pretty-printer for tuples and tuple enum variants"""
|
||||
|
||||
def __init__(self, valobj, dict, is_variant=False):
|
||||
# type: (SBValue, dict, bool) -> TupleSyntheticProvider
|
||||
# logger = Logger.Logger()
|
||||
self.valobj = valobj
|
||||
self.is_variant = is_variant
|
||||
self.type = valobj.GetType()
|
||||
|
||||
if is_variant:
|
||||
self.size = self.type.GetNumberOfFields() - 1
|
||||
else:
|
||||
self.size = self.type.GetNumberOfFields()
|
||||
|
||||
def num_children(self):
|
||||
# type: () -> int
|
||||
return self.size
|
||||
|
||||
def get_child_index(self, name):
|
||||
# type: (str) -> int
|
||||
if name.isdigit():
|
||||
return int(name)
|
||||
else:
|
||||
return -1
|
||||
|
||||
def get_child_at_index(self, index):
|
||||
# type: (int) -> SBValue
|
||||
if self.is_variant:
|
||||
field = self.type.GetFieldAtIndex(index + 1)
|
||||
else:
|
||||
field = self.type.GetFieldAtIndex(index)
|
||||
element = self.valobj.GetChildMemberWithName(field.name)
|
||||
return self.valobj.CreateValueFromData(str(index), element.GetData(), element.GetType())
|
||||
|
||||
def update(self):
|
||||
# type: () -> None
|
||||
pass
|
||||
|
||||
def has_children(self):
|
||||
# type: () -> bool
|
||||
return True
|
||||
|
||||
|
||||
class StdVecSyntheticProvider:
|
||||
"""Pretty-printer for alloc::vec::Vec<T>
|
||||
|
||||
struct Vec<T> { buf: RawVec<T>, len: usize }
|
||||
struct RawVec<T> { ptr: Unique<T>, cap: usize, ... }
|
||||
rust 1.31.1: struct Unique<T: ?Sized> { pointer: NonZero<*const T>, ... }
|
||||
rust 1.33.0: struct Unique<T: ?Sized> { pointer: *const T, ... }
|
||||
struct NonZero<T>(T)
|
||||
"""
|
||||
|
||||
def __init__(self, valobj, dict):
|
||||
# type: (SBValue, dict) -> StdVecSyntheticProvider
|
||||
# logger = Logger.Logger()
|
||||
# logger >> "[StdVecSyntheticProvider] for " + str(valobj.GetName())
|
||||
self.valobj = valobj
|
||||
self.update()
|
||||
|
||||
def num_children(self):
|
||||
# type: () -> int
|
||||
return self.length
|
||||
|
||||
def get_child_index(self, name):
|
||||
# type: (str) -> int
|
||||
index = name.lstrip('[').rstrip(']')
|
||||
if index.isdigit():
|
||||
return int(index)
|
||||
else:
|
||||
return -1
|
||||
|
||||
def get_child_at_index(self, index):
|
||||
# type: (int) -> SBValue
|
||||
start = self.data_ptr.GetValueAsUnsigned()
|
||||
address = start + index * self.element_type_size
|
||||
element = self.data_ptr.CreateValueFromAddress("[%s]" % index, address, self.element_type)
|
||||
return element
|
||||
|
||||
def update(self):
|
||||
# type: () -> None
|
||||
self.length = self.valobj.GetChildMemberWithName("len").GetValueAsUnsigned()
|
||||
self.buf = self.valobj.GetChildMemberWithName("buf")
|
||||
|
||||
self.data_ptr = unwrap_unique_or_non_null(self.buf.GetChildMemberWithName("ptr"))
|
||||
|
||||
self.element_type = self.data_ptr.GetType().GetPointeeType()
|
||||
self.element_type_size = self.element_type.GetByteSize()
|
||||
|
||||
def has_children(self):
|
||||
# type: () -> bool
|
||||
return True
|
||||
|
||||
|
||||
class StdSliceSyntheticProvider:
|
||||
def __init__(self, valobj, dict):
|
||||
self.valobj = valobj
|
||||
self.update()
|
||||
|
||||
def num_children(self):
|
||||
# type: () -> int
|
||||
return self.length
|
||||
|
||||
def get_child_index(self, name):
|
||||
# type: (str) -> int
|
||||
index = name.lstrip('[').rstrip(']')
|
||||
if index.isdigit():
|
||||
return int(index)
|
||||
else:
|
||||
return -1
|
||||
|
||||
def get_child_at_index(self, index):
|
||||
# type: (int) -> SBValue
|
||||
start = self.data_ptr.GetValueAsUnsigned()
|
||||
address = start + index * self.element_type_size
|
||||
element = self.data_ptr.CreateValueFromAddress("[%s]" % index, address, self.element_type)
|
||||
return element
|
||||
|
||||
def update(self):
|
||||
# type: () -> None
|
||||
self.length = self.valobj.GetChildMemberWithName("length").GetValueAsUnsigned()
|
||||
self.data_ptr = self.valobj.GetChildMemberWithName("data_ptr")
|
||||
|
||||
self.element_type = self.data_ptr.GetType().GetPointeeType()
|
||||
self.element_type_size = self.element_type.GetByteSize()
|
||||
|
||||
def has_children(self):
|
||||
# type: () -> bool
|
||||
return True
|
||||
|
||||
|
||||
class StdVecDequeSyntheticProvider:
|
||||
"""Pretty-printer for alloc::collections::vec_deque::VecDeque<T>
|
||||
|
||||
struct VecDeque<T> { tail: usize, head: usize, buf: RawVec<T> }
|
||||
"""
|
||||
|
||||
def __init__(self, valobj, dict):
|
||||
# type: (SBValue, dict) -> StdVecDequeSyntheticProvider
|
||||
# logger = Logger.Logger()
|
||||
# logger >> "[StdVecDequeSyntheticProvider] for " + str(valobj.GetName())
|
||||
self.valobj = valobj
|
||||
self.update()
|
||||
|
||||
def num_children(self):
|
||||
# type: () -> int
|
||||
return self.size
|
||||
|
||||
def get_child_index(self, name):
|
||||
# type: (str) -> int
|
||||
index = name.lstrip('[').rstrip(']')
|
||||
if index.isdigit() and self.tail <= index and (self.tail + index) % self.cap < self.head:
|
||||
return int(index)
|
||||
else:
|
||||
return -1
|
||||
|
||||
def get_child_at_index(self, index):
|
||||
# type: (int) -> SBValue
|
||||
start = self.data_ptr.GetValueAsUnsigned()
|
||||
address = start + ((index + self.tail) % self.cap) * self.element_type_size
|
||||
element = self.data_ptr.CreateValueFromAddress("[%s]" % index, address, self.element_type)
|
||||
return element
|
||||
|
||||
def update(self):
|
||||
# type: () -> None
|
||||
self.head = self.valobj.GetChildMemberWithName("head").GetValueAsUnsigned()
|
||||
self.tail = self.valobj.GetChildMemberWithName("tail").GetValueAsUnsigned()
|
||||
self.buf = self.valobj.GetChildMemberWithName("buf")
|
||||
self.cap = self.buf.GetChildMemberWithName("cap").GetValueAsUnsigned()
|
||||
if self.head >= self.tail:
|
||||
self.size = self.head - self.tail
|
||||
else:
|
||||
self.size = self.cap + self.head - self.tail
|
||||
|
||||
self.data_ptr = unwrap_unique_or_non_null(self.buf.GetChildMemberWithName("ptr"))
|
||||
|
||||
self.element_type = self.data_ptr.GetType().GetPointeeType()
|
||||
self.element_type_size = self.element_type.GetByteSize()
|
||||
|
||||
def has_children(self):
|
||||
# type: () -> bool
|
||||
return True
|
||||
|
||||
|
||||
# BACKCOMPAT: rust 1.35
|
||||
class StdOldHashMapSyntheticProvider:
|
||||
"""Pretty-printer for std::collections::hash::map::HashMap<K, V, S>
|
||||
|
||||
struct HashMap<K, V, S> {..., table: RawTable<K, V>, ... }
|
||||
struct RawTable<K, V> { capacity_mask: usize, size: usize, hashes: TaggedHashUintPtr, ... }
|
||||
"""
|
||||
|
||||
def __init__(self, valobj, dict, show_values=True):
|
||||
# type: (SBValue, dict, bool) -> StdOldHashMapSyntheticProvider
|
||||
self.valobj = valobj
|
||||
self.show_values = show_values
|
||||
self.update()
|
||||
|
||||
def num_children(self):
|
||||
# type: () -> int
|
||||
return self.size
|
||||
|
||||
def get_child_index(self, name):
|
||||
# type: (str) -> int
|
||||
index = name.lstrip('[').rstrip(']')
|
||||
if index.isdigit():
|
||||
return int(index)
|
||||
else:
|
||||
return -1
|
||||
|
||||
def get_child_at_index(self, index):
|
||||
# type: (int) -> SBValue
|
||||
# logger = Logger.Logger()
|
||||
start = self.data_ptr.GetValueAsUnsigned() & ~1
|
||||
|
||||
# See `libstd/collections/hash/table.rs:raw_bucket_at
|
||||
hashes = self.hash_uint_size * self.capacity
|
||||
align = self.pair_type_size
|
||||
# See `libcore/alloc.rs:padding_needed_for`
|
||||
len_rounded_up = (((((hashes + align) % self.modulo - 1) % self.modulo) & ~(
|
||||
(align - 1) % self.modulo)) % self.modulo - hashes) % self.modulo
|
||||
# len_rounded_up = ((hashes + align - 1) & ~(align - 1)) - hashes
|
||||
|
||||
pairs_offset = hashes + len_rounded_up
|
||||
pairs_start = start + pairs_offset
|
||||
|
||||
table_index = self.valid_indices[index]
|
||||
idx = table_index & self.capacity_mask
|
||||
address = pairs_start + idx * self.pair_type_size
|
||||
element = self.data_ptr.CreateValueFromAddress("[%s]" % index, address, self.pair_type)
|
||||
if self.show_values:
|
||||
return element
|
||||
else:
|
||||
key = element.GetChildAtIndex(0)
|
||||
return self.valobj.CreateValueFromData("[%s]" % index, key.GetData(), key.GetType())
|
||||
|
||||
def update(self):
|
||||
# type: () -> None
|
||||
# logger = Logger.Logger()
|
||||
|
||||
self.table = self.valobj.GetChildMemberWithName("table") # type: SBValue
|
||||
self.size = self.table.GetChildMemberWithName("size").GetValueAsUnsigned()
|
||||
self.hashes = self.table.GetChildMemberWithName("hashes")
|
||||
self.hash_uint_type = self.hashes.GetType()
|
||||
self.hash_uint_size = self.hashes.GetType().GetByteSize()
|
||||
self.modulo = 2 ** self.hash_uint_size
|
||||
self.data_ptr = self.hashes.GetChildAtIndex(0).GetChildAtIndex(0)
|
||||
|
||||
self.capacity_mask = self.table.GetChildMemberWithName("capacity_mask").GetValueAsUnsigned()
|
||||
self.capacity = (self.capacity_mask + 1) % self.modulo
|
||||
|
||||
marker = self.table.GetChildMemberWithName("marker").GetType() # type: SBType
|
||||
self.pair_type = marker.template_args[0]
|
||||
self.pair_type_size = self.pair_type.GetByteSize()
|
||||
|
||||
self.valid_indices = []
|
||||
for idx in range(self.capacity):
|
||||
address = self.data_ptr.GetValueAsUnsigned() + idx * self.hash_uint_size
|
||||
hash_uint = self.data_ptr.CreateValueFromAddress("[%s]" % idx, address,
|
||||
self.hash_uint_type)
|
||||
hash_ptr = hash_uint.GetChildAtIndex(0).GetChildAtIndex(0)
|
||||
if hash_ptr.GetValueAsUnsigned() != 0:
|
||||
self.valid_indices.append(idx)
|
||||
|
||||
# logger >> "Valid indices: {}".format(str(self.valid_indices))
|
||||
|
||||
def has_children(self):
|
||||
# type: () -> bool
|
||||
return True
|
||||
|
||||
|
||||
class StdHashMapSyntheticProvider:
|
||||
"""Pretty-printer for hashbrown's HashMap"""
|
||||
|
||||
def __init__(self, valobj, dict, show_values=True):
|
||||
# type: (SBValue, dict, bool) -> StdHashMapSyntheticProvider
|
||||
self.valobj = valobj
|
||||
self.show_values = show_values
|
||||
self.update()
|
||||
|
||||
def num_children(self):
|
||||
# type: () -> int
|
||||
return self.size
|
||||
|
||||
def get_child_index(self, name):
|
||||
# type: (str) -> int
|
||||
index = name.lstrip('[').rstrip(']')
|
||||
if index.isdigit():
|
||||
return int(index)
|
||||
else:
|
||||
return -1
|
||||
|
||||
def get_child_at_index(self, index):
|
||||
# type: (int) -> SBValue
|
||||
pairs_start = self.data_ptr.GetValueAsUnsigned()
|
||||
idx = self.valid_indices[index]
|
||||
address = pairs_start + idx * self.pair_type_size
|
||||
element = self.data_ptr.CreateValueFromAddress("[%s]" % index, address, self.pair_type)
|
||||
if self.show_values:
|
||||
return element
|
||||
else:
|
||||
key = element.GetChildAtIndex(0)
|
||||
return self.valobj.CreateValueFromData("[%s]" % index, key.GetData(), key.GetType())
|
||||
|
||||
def update(self):
|
||||
# type: () -> None
|
||||
table = self.valobj.GetChildMemberWithName("base").GetChildMemberWithName("table")
|
||||
capacity = table.GetChildMemberWithName("bucket_mask").GetValueAsUnsigned() + 1
|
||||
ctrl = table.GetChildMemberWithName("ctrl").GetChildAtIndex(0)
|
||||
|
||||
self.size = table.GetChildMemberWithName("items").GetValueAsUnsigned()
|
||||
self.data_ptr = table.GetChildMemberWithName("data").GetChildAtIndex(0)
|
||||
self.pair_type = self.data_ptr.Dereference().GetType()
|
||||
self.pair_type_size = self.pair_type.GetByteSize()
|
||||
|
||||
u8_type = self.valobj.GetTarget().GetBasicType(eBasicTypeUnsignedChar)
|
||||
u8_type_size = self.valobj.GetTarget().GetBasicType(eBasicTypeUnsignedChar).GetByteSize()
|
||||
|
||||
self.valid_indices = []
|
||||
for idx in range(capacity):
|
||||
address = ctrl.GetValueAsUnsigned() + idx * u8_type_size
|
||||
value = ctrl.CreateValueFromAddress("ctrl[%s]" % idx, address,
|
||||
u8_type).GetValueAsUnsigned()
|
||||
is_present = value & 128 == 0
|
||||
if is_present:
|
||||
self.valid_indices.append(idx)
|
||||
|
||||
def has_children(self):
|
||||
# type: () -> bool
|
||||
return True
|
||||
|
||||
|
||||
def StdRcSummaryProvider(valobj, dict):
|
||||
# type: (SBValue, dict) -> str
|
||||
strong = valobj.GetChildMemberWithName("strong").GetValueAsUnsigned()
|
||||
weak = valobj.GetChildMemberWithName("weak").GetValueAsUnsigned()
|
||||
return "strong={}, weak={}".format(strong, weak)
|
||||
|
||||
|
||||
class StdRcSyntheticProvider:
|
||||
"""Pretty-printer for alloc::rc::Rc<T> and alloc::sync::Arc<T>
|
||||
|
||||
struct Rc<T> { ptr: NonNull<RcBox<T>>, ... }
|
||||
rust 1.31.1: struct NonNull<T> { pointer: NonZero<*const T> }
|
||||
rust 1.33.0: struct NonNull<T> { pointer: *const T }
|
||||
struct NonZero<T>(T)
|
||||
struct RcBox<T> { strong: Cell<usize>, weak: Cell<usize>, value: T }
|
||||
struct Cell<T> { value: UnsafeCell<T> }
|
||||
struct UnsafeCell<T> { value: T }
|
||||
|
||||
struct Arc<T> { ptr: NonNull<ArcInner<T>>, ... }
|
||||
struct ArcInner<T> { strong: atomic::AtomicUsize, weak: atomic::AtomicUsize, data: T }
|
||||
struct AtomicUsize { v: UnsafeCell<usize> }
|
||||
"""
|
||||
|
||||
def __init__(self, valobj, dict, is_atomic=False):
|
||||
# type: (SBValue, dict, bool) -> StdRcSyntheticProvider
|
||||
self.valobj = valobj
|
||||
|
||||
self.ptr = unwrap_unique_or_non_null(self.valobj.GetChildMemberWithName("ptr"))
|
||||
|
||||
self.value = self.ptr.GetChildMemberWithName("data" if is_atomic else "value")
|
||||
|
||||
self.strong = self.ptr.GetChildMemberWithName("strong").GetChildAtIndex(
|
||||
0).GetChildMemberWithName("value")
|
||||
self.weak = self.ptr.GetChildMemberWithName("weak").GetChildAtIndex(
|
||||
0).GetChildMemberWithName("value")
|
||||
|
||||
self.value_builder = ValueBuilder(valobj)
|
||||
|
||||
self.update()
|
||||
|
||||
def num_children(self):
|
||||
# type: () -> int
|
||||
# Actually there are 3 children, but only the `value` should be shown as a child
|
||||
return 1
|
||||
|
||||
def get_child_index(self, name):
|
||||
# type: (str) -> int
|
||||
if name == "value":
|
||||
return 0
|
||||
if name == "strong":
|
||||
return 1
|
||||
if name == "weak":
|
||||
return 2
|
||||
return -1
|
||||
|
||||
def get_child_at_index(self, index):
|
||||
# type: (int) -> SBValue
|
||||
if index == 0:
|
||||
return self.value
|
||||
if index == 1:
|
||||
return self.value_builder.from_uint("strong", self.strong_count)
|
||||
if index == 2:
|
||||
return self.value_builder.from_uint("weak", self.weak_count)
|
||||
|
||||
return None
|
||||
|
||||
def update(self):
|
||||
# type: () -> None
|
||||
self.strong_count = self.strong.GetValueAsUnsigned()
|
||||
self.weak_count = self.weak.GetValueAsUnsigned() - 1
|
||||
|
||||
def has_children(self):
|
||||
# type: () -> bool
|
||||
return True
|
||||
|
||||
|
||||
class StdCellSyntheticProvider:
|
||||
"""Pretty-printer for std::cell::Cell"""
|
||||
|
||||
def __init__(self, valobj, dict):
|
||||
# type: (SBValue, dict) -> StdCellSyntheticProvider
|
||||
self.valobj = valobj
|
||||
self.value = valobj.GetChildMemberWithName("value").GetChildAtIndex(0)
|
||||
|
||||
def num_children(self):
|
||||
# type: () -> int
|
||||
return 1
|
||||
|
||||
def get_child_index(self, name):
|
||||
# type: (str) -> int
|
||||
if name == "value":
|
||||
return 0
|
||||
return -1
|
||||
|
||||
def get_child_at_index(self, index):
|
||||
# type: (int) -> SBValue
|
||||
if index == 0:
|
||||
return self.value
|
||||
return None
|
||||
|
||||
def update(self):
|
||||
# type: () -> None
|
||||
pass
|
||||
|
||||
def has_children(self):
|
||||
# type: () -> bool
|
||||
return True
|
||||
|
||||
|
||||
def StdRefSummaryProvider(valobj, dict):
|
||||
# type: (SBValue, dict) -> str
|
||||
borrow = valobj.GetChildMemberWithName("borrow").GetValueAsSigned()
|
||||
return "borrow={}".format(borrow) if borrow >= 0 else "borrow_mut={}".format(-borrow)
|
||||
|
||||
|
||||
class StdRefSyntheticProvider:
|
||||
"""Pretty-printer for std::cell::Ref, std::cell::RefMut, and std::cell::RefCell"""
|
||||
|
||||
def __init__(self, valobj, dict, is_cell=False):
|
||||
# type: (SBValue, dict, bool) -> StdRefSyntheticProvider
|
||||
self.valobj = valobj
|
||||
|
||||
borrow = valobj.GetChildMemberWithName("borrow")
|
||||
value = valobj.GetChildMemberWithName("value")
|
||||
if is_cell:
|
||||
self.borrow = borrow.GetChildMemberWithName("value").GetChildMemberWithName("value")
|
||||
self.value = value.GetChildMemberWithName("value")
|
||||
else:
|
||||
self.borrow = borrow.GetChildMemberWithName("borrow").GetChildMemberWithName(
|
||||
"value").GetChildMemberWithName("value")
|
||||
self.value = value.Dereference()
|
||||
|
||||
self.value_builder = ValueBuilder(valobj)
|
||||
|
||||
self.update()
|
||||
|
||||
def num_children(self):
|
||||
# type: () -> int
|
||||
# Actually there are 2 children, but only the `value` should be shown as a child
|
||||
return 1
|
||||
|
||||
def get_child_index(self, name):
|
||||
if name == "value":
|
||||
return 0
|
||||
if name == "borrow":
|
||||
return 1
|
||||
return -1
|
||||
|
||||
def get_child_at_index(self, index):
|
||||
# type: (int) -> SBValue
|
||||
if index == 0:
|
||||
return self.value
|
||||
if index == 1:
|
||||
return self.value_builder.from_int("borrow", self.borrow_count)
|
||||
return None
|
||||
|
||||
def update(self):
|
||||
# type: () -> None
|
||||
self.borrow_count = self.borrow.GetValueAsSigned()
|
||||
|
||||
def has_children(self):
|
||||
# type: () -> bool
|
||||
return True
|
@ -1,305 +0,0 @@
|
||||
import lldb
|
||||
import debugger_pretty_printers_common as rustpp
|
||||
|
||||
# ===============================================================================
|
||||
# LLDB Pretty Printing Module for Rust
|
||||
# ===============================================================================
|
||||
|
||||
|
||||
class LldbType(rustpp.Type):
|
||||
|
||||
def __init__(self, ty):
|
||||
super(LldbType, self).__init__()
|
||||
self.ty = ty
|
||||
self.fields = None
|
||||
|
||||
def get_unqualified_type_name(self):
|
||||
qualified_name = self.ty.GetName()
|
||||
|
||||
if qualified_name is None:
|
||||
return qualified_name
|
||||
|
||||
return rustpp.extract_type_name(qualified_name).replace("&'static ", "&")
|
||||
|
||||
def get_dwarf_type_kind(self):
|
||||
type_class = self.ty.GetTypeClass()
|
||||
|
||||
if type_class == lldb.eTypeClassStruct:
|
||||
return rustpp.DWARF_TYPE_CODE_STRUCT
|
||||
|
||||
if type_class == lldb.eTypeClassUnion:
|
||||
return rustpp.DWARF_TYPE_CODE_UNION
|
||||
|
||||
if type_class == lldb.eTypeClassPointer:
|
||||
return rustpp.DWARF_TYPE_CODE_PTR
|
||||
|
||||
if type_class == lldb.eTypeClassArray:
|
||||
return rustpp.DWARF_TYPE_CODE_ARRAY
|
||||
|
||||
if type_class == lldb.eTypeClassEnumeration:
|
||||
return rustpp.DWARF_TYPE_CODE_ENUM
|
||||
|
||||
return None
|
||||
|
||||
def get_fields(self):
|
||||
assert ((self.get_dwarf_type_kind() == rustpp.DWARF_TYPE_CODE_STRUCT) or
|
||||
(self.get_dwarf_type_kind() == rustpp.DWARF_TYPE_CODE_UNION))
|
||||
if self.fields is None:
|
||||
self.fields = list(self.ty.fields)
|
||||
return self.fields
|
||||
|
||||
def get_wrapped_value(self):
|
||||
return self.ty
|
||||
|
||||
|
||||
class LldbValue(rustpp.Value):
|
||||
def __init__(self, lldb_val):
|
||||
ty = lldb_val.type
|
||||
wty = LldbType(ty)
|
||||
super(LldbValue, self).__init__(wty)
|
||||
self.lldb_val = lldb_val
|
||||
self.children = {}
|
||||
|
||||
def get_child_at_index(self, index):
|
||||
child = self.children.get(index)
|
||||
if child is None:
|
||||
lldb_field = self.lldb_val.GetChildAtIndex(index)
|
||||
child = LldbValue(lldb_field)
|
||||
self.children[index] = child
|
||||
return child
|
||||
|
||||
def as_integer(self):
|
||||
return self.lldb_val.GetValueAsUnsigned()
|
||||
|
||||
def get_wrapped_value(self):
|
||||
return self.lldb_val
|
||||
|
||||
|
||||
def print_val(lldb_val, internal_dict):
|
||||
val = LldbValue(lldb_val)
|
||||
type_kind = val.type.get_type_kind()
|
||||
|
||||
if (type_kind == rustpp.TYPE_KIND_REGULAR_STRUCT or
|
||||
type_kind == rustpp.TYPE_KIND_REGULAR_UNION or
|
||||
type_kind == rustpp.TYPE_KIND_EMPTY):
|
||||
return print_struct_val(val,
|
||||
internal_dict,
|
||||
omit_first_field=False,
|
||||
omit_type_name=False,
|
||||
is_tuple_like=False)
|
||||
|
||||
if type_kind == rustpp.TYPE_KIND_STRUCT_VARIANT:
|
||||
return print_struct_val(val,
|
||||
internal_dict,
|
||||
omit_first_field=True,
|
||||
omit_type_name=False,
|
||||
is_tuple_like=False)
|
||||
|
||||
if type_kind == rustpp.TYPE_KIND_SLICE:
|
||||
return print_vec_slice_val(val, internal_dict)
|
||||
|
||||
if type_kind == rustpp.TYPE_KIND_STR_SLICE:
|
||||
return print_str_slice_val(val, internal_dict)
|
||||
|
||||
if type_kind == rustpp.TYPE_KIND_STD_VEC:
|
||||
return print_std_vec_val(val, internal_dict)
|
||||
|
||||
if type_kind == rustpp.TYPE_KIND_STD_STRING:
|
||||
return print_std_string_val(val, internal_dict)
|
||||
|
||||
if type_kind == rustpp.TYPE_KIND_TUPLE:
|
||||
return print_struct_val(val,
|
||||
internal_dict,
|
||||
omit_first_field=False,
|
||||
omit_type_name=True,
|
||||
is_tuple_like=True)
|
||||
|
||||
if type_kind == rustpp.TYPE_KIND_TUPLE_STRUCT:
|
||||
return print_struct_val(val,
|
||||
internal_dict,
|
||||
omit_first_field=False,
|
||||
omit_type_name=False,
|
||||
is_tuple_like=True)
|
||||
|
||||
if type_kind == rustpp.TYPE_KIND_CSTYLE_VARIANT:
|
||||
return val.type.get_unqualified_type_name()
|
||||
|
||||
if type_kind == rustpp.TYPE_KIND_TUPLE_VARIANT:
|
||||
return print_struct_val(val,
|
||||
internal_dict,
|
||||
omit_first_field=True,
|
||||
omit_type_name=False,
|
||||
is_tuple_like=True)
|
||||
|
||||
if type_kind == rustpp.TYPE_KIND_SINGLETON_ENUM:
|
||||
return print_val(lldb_val.GetChildAtIndex(0), internal_dict)
|
||||
|
||||
if type_kind == rustpp.TYPE_KIND_PTR:
|
||||
return print_pointer_val(val, internal_dict)
|
||||
|
||||
if type_kind == rustpp.TYPE_KIND_FIXED_SIZE_VEC:
|
||||
return print_fixed_size_vec_val(val, internal_dict)
|
||||
|
||||
if type_kind == rustpp.TYPE_KIND_REGULAR_ENUM:
|
||||
# This is a regular enum, extract the discriminant
|
||||
discriminant_val = rustpp.get_discriminant_value_as_integer(val)
|
||||
return print_val(lldb_val.GetChildAtIndex(discriminant_val), internal_dict)
|
||||
|
||||
if type_kind == rustpp.TYPE_KIND_COMPRESSED_ENUM:
|
||||
encoded_enum_info = rustpp.EncodedEnumInfo(val)
|
||||
if encoded_enum_info.is_null_variant():
|
||||
return encoded_enum_info.get_null_variant_name()
|
||||
|
||||
non_null_val = encoded_enum_info.get_non_null_variant_val()
|
||||
return print_val(non_null_val.get_wrapped_value(), internal_dict)
|
||||
|
||||
# No pretty printer has been found
|
||||
return lldb_val.GetValue()
|
||||
|
||||
|
||||
# =---------------------------------------------------------------------------------------
|
||||
# Type-Specialized Printing Functions
|
||||
# =---------------------------------------------------------------------------------------
|
||||
|
||||
def print_struct_val(val, internal_dict, omit_first_field, omit_type_name, is_tuple_like):
|
||||
"""
|
||||
Prints a struct, tuple, or tuple struct value with Rust syntax.
|
||||
Ignores any fields before field_start_index.
|
||||
"""
|
||||
assert (val.type.get_dwarf_type_kind() == rustpp.DWARF_TYPE_CODE_STRUCT or
|
||||
val.type.get_dwarf_type_kind() == rustpp.DWARF_TYPE_CODE_UNION)
|
||||
|
||||
if omit_type_name:
|
||||
type_name = ""
|
||||
else:
|
||||
type_name = val.type.get_unqualified_type_name()
|
||||
|
||||
if is_tuple_like:
|
||||
template = "%(type_name)s(%(body)s)"
|
||||
separator = ", "
|
||||
else:
|
||||
template = "%(type_name)s {\n%(body)s\n}"
|
||||
separator = ", \n"
|
||||
|
||||
fields = val.type.get_fields()
|
||||
|
||||
def render_child(child_index):
|
||||
this = ""
|
||||
if not is_tuple_like:
|
||||
field_name = fields[child_index].name
|
||||
this += field_name + ": "
|
||||
|
||||
field_val = val.get_child_at_index(child_index)
|
||||
|
||||
if not field_val.get_wrapped_value().IsValid():
|
||||
field = fields[child_index]
|
||||
# LLDB is not good at handling zero-sized values, so we have to help
|
||||
# it a little
|
||||
if field.GetType().GetByteSize() == 0:
|
||||
return this + rustpp.extract_type_name(field.GetType().GetName())
|
||||
else:
|
||||
return this + "<invalid value>"
|
||||
|
||||
return this + print_val(field_val.get_wrapped_value(), internal_dict)
|
||||
|
||||
if omit_first_field:
|
||||
field_start_index = 1
|
||||
else:
|
||||
field_start_index = 0
|
||||
|
||||
body = separator.join([render_child(idx) for idx in range(field_start_index, len(fields))])
|
||||
|
||||
return template % {"type_name": type_name,
|
||||
"body": body}
|
||||
|
||||
|
||||
def print_pointer_val(val, internal_dict):
|
||||
"""Prints a pointer value with Rust syntax"""
|
||||
assert val.type.get_dwarf_type_kind() == rustpp.DWARF_TYPE_CODE_PTR
|
||||
sigil = "&"
|
||||
type_name = val.type.get_unqualified_type_name()
|
||||
if type_name and type_name[0:1] in ["&", "*"]:
|
||||
sigil = type_name[0:1]
|
||||
|
||||
return sigil + hex(val.as_integer())
|
||||
|
||||
|
||||
def print_fixed_size_vec_val(val, internal_dict):
|
||||
assert val.type.get_dwarf_type_kind() == rustpp.DWARF_TYPE_CODE_ARRAY
|
||||
lldb_val = val.get_wrapped_value()
|
||||
|
||||
output = "["
|
||||
|
||||
for i in range(lldb_val.num_children):
|
||||
output += print_val(lldb_val.GetChildAtIndex(i), internal_dict)
|
||||
if i != lldb_val.num_children - 1:
|
||||
output += ", "
|
||||
|
||||
output += "]"
|
||||
return output
|
||||
|
||||
|
||||
def print_vec_slice_val(val, internal_dict):
|
||||
(length, data_ptr) = rustpp.extract_length_and_ptr_from_slice(val)
|
||||
return "&[%s]" % print_array_of_values(val.get_wrapped_value().GetName(),
|
||||
data_ptr,
|
||||
length,
|
||||
internal_dict)
|
||||
|
||||
|
||||
def print_std_vec_val(val, internal_dict):
|
||||
(length, data_ptr, cap) = rustpp.extract_length_ptr_and_cap_from_std_vec(val)
|
||||
return "vec![%s]" % print_array_of_values(val.get_wrapped_value().GetName(),
|
||||
data_ptr,
|
||||
length,
|
||||
internal_dict)
|
||||
|
||||
|
||||
def print_str_slice_val(val, internal_dict):
|
||||
(length, data_ptr) = rustpp.extract_length_and_ptr_from_slice(val)
|
||||
return read_utf8_string(data_ptr, length)
|
||||
|
||||
|
||||
def print_std_string_val(val, internal_dict):
|
||||
vec = val.get_child_at_index(0)
|
||||
(length, data_ptr, cap) = rustpp.extract_length_ptr_and_cap_from_std_vec(vec)
|
||||
return read_utf8_string(data_ptr, length)
|
||||
|
||||
# =-----------------------------------------------------------------------
|
||||
# Helper Functions
|
||||
# =-----------------------------------------------------------------------
|
||||
|
||||
|
||||
def print_array_of_values(array_name, data_ptr_val, length, internal_dict):
|
||||
"""Prints a contiguous memory range, interpreting it as values of the
|
||||
pointee-type of data_ptr_val."""
|
||||
|
||||
data_ptr_type = data_ptr_val.type
|
||||
assert data_ptr_type.get_dwarf_type_kind() == rustpp.DWARF_TYPE_CODE_PTR
|
||||
|
||||
element_type = data_ptr_type.get_wrapped_value().GetPointeeType()
|
||||
element_type_size = element_type.GetByteSize()
|
||||
|
||||
start_address = data_ptr_val.as_integer()
|
||||
raw_value = data_ptr_val.get_wrapped_value()
|
||||
|
||||
def render_element(i):
|
||||
address = start_address + i * element_type_size
|
||||
element_val = raw_value.CreateValueFromAddress(array_name + ("[%s]" % i),
|
||||
address,
|
||||
element_type)
|
||||
return print_val(element_val, internal_dict)
|
||||
|
||||
return ', '.join([render_element(i) for i in range(length)])
|
||||
|
||||
|
||||
def read_utf8_string(ptr_val, byte_count):
|
||||
if byte_count == 0:
|
||||
return '""'
|
||||
error = lldb.SBError()
|
||||
process = ptr_val.get_wrapped_value().GetProcess()
|
||||
data = process.ReadMemory(ptr_val.as_integer(), byte_count, error)
|
||||
if error.Success():
|
||||
return '"%s"' % data.decode(encoding='UTF-8')
|
||||
else:
|
||||
return '<error: %s>' % error.GetCString()
|
@ -30,13 +30,5 @@ EOF
|
||||
fi
|
||||
fi
|
||||
|
||||
# Prepare commands that will be loaded before any file on the command line has been loaded
|
||||
script_import="command script import \"$RUSTC_SYSROOT/lib/rustlib/etc/lldb_rust_formatters.py\""
|
||||
category_definition="type summary add --no-value --python-function lldb_rust_formatters.print_val -x \".*\" --category Rust"
|
||||
category_enable="type category enable Rust"
|
||||
|
||||
# Call LLDB with the commands added to the argument list
|
||||
exec "$lldb" --one-line-before-file "$script_import" \
|
||||
--one-line-before-file "$category_definition" \
|
||||
--one-line-before-file "$category_enable" \
|
||||
"$@"
|
||||
exec "$lldb" --source-before-file ./lldb_commands "$@"
|
||||
|
113
src/etc/rust_types.py
Normal file
113
src/etc/rust_types.py
Normal file
@ -0,0 +1,113 @@
|
||||
import re
|
||||
|
||||
|
||||
class RustType(object):
|
||||
OTHER = "Other"
|
||||
STRUCT = "Struct"
|
||||
TUPLE = "Tuple"
|
||||
CSTYLE_VARIANT = "CStyleVariant"
|
||||
TUPLE_VARIANT = "TupleVariant"
|
||||
STRUCT_VARIANT = "StructVariant"
|
||||
ENUM = "Enum"
|
||||
EMPTY = "Empty"
|
||||
SINGLETON_ENUM = "SingletonEnum"
|
||||
REGULAR_ENUM = "RegularEnum"
|
||||
COMPRESSED_ENUM = "CompressedEnum"
|
||||
REGULAR_UNION = "RegularUnion"
|
||||
|
||||
STD_STRING = "StdString"
|
||||
STD_OS_STRING = "StdOsString"
|
||||
STD_STR = "StdStr"
|
||||
STD_SLICE = "StdSlice"
|
||||
STD_VEC = "StdVec"
|
||||
STD_VEC_DEQUE = "StdVecDeque"
|
||||
STD_BTREE_SET = "StdBTreeSet"
|
||||
STD_BTREE_MAP = "StdBTreeMap"
|
||||
STD_HASH_MAP = "StdHashMap"
|
||||
STD_HASH_SET = "StdHashSet"
|
||||
STD_RC = "StdRc"
|
||||
STD_ARC = "StdArc"
|
||||
STD_CELL = "StdCell"
|
||||
STD_REF = "StdRef"
|
||||
STD_REF_MUT = "StdRefMut"
|
||||
STD_REF_CELL = "StdRefCell"
|
||||
|
||||
|
||||
STD_STRING_REGEX = re.compile(r"^(alloc::(\w+::)+)String$")
|
||||
STD_STR_REGEX = re.compile(r"^&str$")
|
||||
STD_SLICE_REGEX = re.compile(r"^&\[.+\]$")
|
||||
STD_OS_STRING_REGEX = re.compile(r"^(std::ffi::(\w+::)+)OsString$")
|
||||
STD_VEC_REGEX = re.compile(r"^(alloc::(\w+::)+)Vec<.+>$")
|
||||
STD_VEC_DEQUE_REGEX = re.compile(r"^(alloc::(\w+::)+)VecDeque<.+>$")
|
||||
STD_BTREE_SET_REGEX = re.compile(r"^(alloc::(\w+::)+)BTreeSet<.+>$")
|
||||
STD_BTREE_MAP_REGEX = re.compile(r"^(alloc::(\w+::)+)BTreeMap<.+>$")
|
||||
STD_HASH_MAP_REGEX = re.compile(r"^(std::collections::(\w+::)+)HashMap<.+>$")
|
||||
STD_HASH_SET_REGEX = re.compile(r"^(std::collections::(\w+::)+)HashSet<.+>$")
|
||||
STD_RC_REGEX = re.compile(r"^(alloc::(\w+::)+)Rc<.+>$")
|
||||
STD_ARC_REGEX = re.compile(r"^(alloc::(\w+::)+)Arc<.+>$")
|
||||
STD_CELL_REGEX = re.compile(r"^(core::(\w+::)+)Cell<.+>$")
|
||||
STD_REF_REGEX = re.compile(r"^(core::(\w+::)+)Ref<.+>$")
|
||||
STD_REF_MUT_REGEX = re.compile(r"^(core::(\w+::)+)RefMut<.+>$")
|
||||
STD_REF_CELL_REGEX = re.compile(r"^(core::(\w+::)+)RefCell<.+>$")
|
||||
|
||||
TUPLE_ITEM_REGEX = re.compile(r"__\d+$")
|
||||
|
||||
ENCODED_ENUM_PREFIX = "RUST$ENCODED$ENUM$"
|
||||
ENUM_DISR_FIELD_NAME = "<<variant>>"
|
||||
|
||||
STD_TYPE_TO_REGEX = {
|
||||
RustType.STD_STRING: STD_STRING_REGEX,
|
||||
RustType.STD_OS_STRING: STD_OS_STRING_REGEX,
|
||||
RustType.STD_STR: STD_STR_REGEX,
|
||||
RustType.STD_SLICE: STD_SLICE_REGEX,
|
||||
RustType.STD_VEC: STD_VEC_REGEX,
|
||||
RustType.STD_VEC_DEQUE: STD_VEC_DEQUE_REGEX,
|
||||
RustType.STD_HASH_MAP: STD_HASH_MAP_REGEX,
|
||||
RustType.STD_HASH_SET: STD_HASH_SET_REGEX,
|
||||
RustType.STD_BTREE_SET: STD_BTREE_SET_REGEX,
|
||||
RustType.STD_BTREE_MAP: STD_BTREE_MAP_REGEX,
|
||||
RustType.STD_RC: STD_RC_REGEX,
|
||||
RustType.STD_ARC: STD_ARC_REGEX,
|
||||
RustType.STD_REF: STD_REF_REGEX,
|
||||
RustType.STD_REF_MUT: STD_REF_MUT_REGEX,
|
||||
RustType.STD_REF_CELL: STD_REF_CELL_REGEX,
|
||||
RustType.STD_CELL: STD_CELL_REGEX,
|
||||
}
|
||||
|
||||
def is_tuple_fields(fields):
|
||||
# type: (list) -> bool
|
||||
return all(TUPLE_ITEM_REGEX.match(str(field.name)) for field in fields)
|
||||
|
||||
|
||||
def classify_struct(name, fields):
|
||||
if len(fields) == 0:
|
||||
return RustType.EMPTY
|
||||
|
||||
for ty, regex in STD_TYPE_TO_REGEX.items():
|
||||
if regex.match(name):
|
||||
return ty
|
||||
|
||||
if fields[0].name == ENUM_DISR_FIELD_NAME:
|
||||
return RustType.ENUM
|
||||
|
||||
if is_tuple_fields(fields):
|
||||
return RustType.TUPLE
|
||||
|
||||
return RustType.STRUCT
|
||||
|
||||
|
||||
def classify_union(fields):
|
||||
if len(fields) == 0:
|
||||
return RustType.EMPTY
|
||||
|
||||
first_variant_name = fields[0].name
|
||||
if first_variant_name is None:
|
||||
if len(fields) == 1:
|
||||
return RustType.SINGLETON_ENUM
|
||||
else:
|
||||
return RustType.REGULAR_ENUM
|
||||
elif first_variant_name.startswith(ENCODED_ENUM_PREFIX):
|
||||
assert len(fields) == 1
|
||||
return RustType.COMPRESSED_ENUM
|
||||
else:
|
||||
return RustType.REGULAR_UNION
|
@ -43,8 +43,8 @@
|
||||
// lldb-command:run
|
||||
|
||||
// lldb-command:print arg
|
||||
// lldbg-check:[...]$0 = Struct<i32> { b: -1, b1: 0 }
|
||||
// lldbr-check:(associated_types::Struct<i32>) arg = Struct<i32> { b: -1, b1: 0 }
|
||||
// lldbg-check:[...]$0 = { b = -1, b1 = 0 }
|
||||
// lldbr-check:(associated_types::Struct<i32>) arg = { b = -1, b1 = 0 }
|
||||
// lldb-command:continue
|
||||
|
||||
// lldb-command:print inferred
|
||||
|
@ -35,8 +35,8 @@
|
||||
// lldb-command:run
|
||||
|
||||
// lldb-command:print *stack_val_ref
|
||||
// lldbg-check:[...]$0 = SomeStruct { x: 10, y: 23.5 }
|
||||
// lldbr-check:(borrowed_struct::SomeStruct) *stack_val_ref = SomeStruct { x: 10, y: 23.5 }
|
||||
// lldbg-check:[...]$0 = { x = 10 y = 23.5 }
|
||||
// lldbr-check:(borrowed_struct::SomeStruct) *stack_val_ref = (x = 10, y = 23.5)
|
||||
|
||||
// lldb-command:print *stack_val_interior_ref_1
|
||||
// lldbg-check:[...]$1 = 10
|
||||
@ -47,12 +47,12 @@
|
||||
// lldbr-check:(f64) *stack_val_interior_ref_2 = 23.5
|
||||
|
||||
// lldb-command:print *ref_to_unnamed
|
||||
// lldbg-check:[...]$3 = SomeStruct { x: 11, y: 24.5 }
|
||||
// lldbr-check:(borrowed_struct::SomeStruct) *ref_to_unnamed = SomeStruct { x: 11, y: 24.5 }
|
||||
// lldbg-check:[...]$3 = { x = 11 y = 24.5 }
|
||||
// lldbr-check:(borrowed_struct::SomeStruct) *ref_to_unnamed = (x = 11, y = 24.5)
|
||||
|
||||
// lldb-command:print *unique_val_ref
|
||||
// lldbg-check:[...]$4 = SomeStruct { x: 13, y: 26.5 }
|
||||
// lldbr-check:(borrowed_struct::SomeStruct) *unique_val_ref = SomeStruct { x: 13, y: 26.5 }
|
||||
// lldbg-check:[...]$4 = { x = 13 y = 26.5 }
|
||||
// lldbr-check:(borrowed_struct::SomeStruct) *unique_val_ref = (x = 13, y = 26.5)
|
||||
|
||||
// lldb-command:print *unique_val_interior_ref_1
|
||||
// lldbg-check:[...]$5 = 13
|
||||
|
@ -24,16 +24,16 @@
|
||||
// lldb-command:run
|
||||
|
||||
// lldb-command:print *stack_val_ref
|
||||
// lldbg-check:[...]$0 = (-14, -19)
|
||||
// lldbr-check:((i16, f32)) *stack_val_ref = { = -14 = -19 }
|
||||
// lldbg-check:[...]$0 = { 0 = -14 1 = -19 }
|
||||
// lldbr-check:((i16, f32)) *stack_val_ref = { 0 = -14 1 = -19 }
|
||||
|
||||
// lldb-command:print *ref_to_unnamed
|
||||
// lldbg-check:[...]$1 = (-15, -20)
|
||||
// lldbr-check:((i16, f32)) *ref_to_unnamed = { = -15 = -20 }
|
||||
// lldbg-check:[...]$1 = { 0 = -15 1 = -20 }
|
||||
// lldbr-check:((i16, f32)) *ref_to_unnamed = { 0 = -15 1 = -20 }
|
||||
|
||||
// lldb-command:print *unique_val_ref
|
||||
// lldbg-check:[...]$2 = (-17, -22)
|
||||
// lldbr-check:((i16, f32)) *unique_val_ref = { = -17 = -22 }
|
||||
// lldbg-check:[...]$2 = { 0 = -17 1 = -22 }
|
||||
// lldbr-check:((i16, f32)) *unique_val_ref = { 0 = -17 1 = -22 }
|
||||
|
||||
|
||||
#![allow(unused_variables)]
|
||||
|
@ -20,8 +20,8 @@
|
||||
// lldbg-check:[...]$0 = 1
|
||||
// lldbr-check:(i32) *a = 1
|
||||
// lldb-command:print *b
|
||||
// lldbg-check:[...]$1 = (2, 3.5)
|
||||
// lldbr-check:((i32, f64)) *b = { = 2 = 3.5 }
|
||||
// lldbg-check:[...]$1 = { 0 = 2 1 = 3.5 }
|
||||
// lldbr-check:((i32, f64)) *b = { 0 = 2 1 = 3.5 }
|
||||
|
||||
#![allow(unused_variables)]
|
||||
#![feature(box_syntax)]
|
||||
|
@ -22,12 +22,12 @@
|
||||
// lldb-command:run
|
||||
|
||||
// lldb-command:print *boxed_with_padding
|
||||
// lldbg-check:[...]$0 = StructWithSomePadding { x: 99, y: 999, z: 9999, w: 99999 }
|
||||
// lldbr-check:(boxed_struct::StructWithSomePadding) *boxed_with_padding = StructWithSomePadding { x: 99, y: 999, z: 9999, w: 99999 }
|
||||
// lldbg-check:[...]$0 = { x = 99 y = 999 z = 9999 w = 99999 }
|
||||
// lldbr-check:(boxed_struct::StructWithSomePadding) *boxed_with_padding = { x = 99 y = 999 z = 9999 w = 99999 }
|
||||
|
||||
// lldb-command:print *boxed_with_dtor
|
||||
// lldbg-check:[...]$1 = StructWithDestructor { x: 77, y: 777, z: 7777, w: 77777 }
|
||||
// lldbr-check:(boxed_struct::StructWithDestructor) *boxed_with_dtor = StructWithDestructor { x: 77, y: 777, z: 7777, w: 77777 }
|
||||
// lldbg-check:[...]$1 = { x = 77 y = 777 z = 7777 w = 77777 }
|
||||
// lldbr-check:(boxed_struct::StructWithDestructor) *boxed_with_dtor = { x = 77 y = 777 z = 7777 w = 77777 }
|
||||
|
||||
#![allow(unused_variables)]
|
||||
#![feature(box_syntax)]
|
||||
|
@ -31,13 +31,13 @@
|
||||
// lldb-command:continue
|
||||
|
||||
// lldb-command:print self
|
||||
// lldbg-check:[...]$1 = Struct { x: 2222, y: 3333 }
|
||||
// lldbr-check:(by_value_self_argument_in_trait_impl::Struct) self = Struct { x: 2222, y: 3333 }
|
||||
// lldbg-check:[...]$1 = { x = 2222 y = 3333 }
|
||||
// lldbr-check:(by_value_self_argument_in_trait_impl::Struct) self = { x = 2222 y = 3333 }
|
||||
// lldb-command:continue
|
||||
|
||||
// lldb-command:print self
|
||||
// lldbg-check:[...]$2 = (4444.5, 5555, 6666, 7777.5)
|
||||
// lldbr-check:((f64, isize, isize, f64)) self = { = 4444.5 = 5555 = 6666 = 7777.5 }
|
||||
// lldbg-check:[...] $2 = { 0 = 4444.5 1 = 5555 2 = 6666 3 = 7777.5 }
|
||||
// lldbr-check:((f64, isize, isize, f64)) self = { 0 = 4444.5 1 = 5555 2 = 6666 3 = 7777.5 }
|
||||
// lldb-command:continue
|
||||
|
||||
#![feature(omit_gdb_pretty_printer_section)]
|
||||
|
@ -40,31 +40,32 @@
|
||||
// lldb-command:run
|
||||
|
||||
// lldb-command:print tuple_interior_padding
|
||||
// lldbg-check:[...]$0 = (0, OneHundred)
|
||||
// lldbr-check:((i16, c_style_enum_in_composite::AnEnum)) tuple_interior_padding = { = 0 = c_style_enum_in_composite::AnEnum::OneHundred }
|
||||
// lldbg-check:[...]$0 = { 0 = 0 1 = OneHundred }
|
||||
// lldbr-check:((i16, c_style_enum_in_composite::AnEnum)) tuple_interior_padding = { 0 = 0 1 = OneHundred }
|
||||
|
||||
// lldb-command:print tuple_padding_at_end
|
||||
// lldbg-check:[...]$1 = ((1, OneThousand), 2)
|
||||
// lldbr-check:(((u64, c_style_enum_in_composite::AnEnum), u64)) tuple_padding_at_end = { = { = 1 = c_style_enum_in_composite::AnEnum::OneThousand } = 2 }
|
||||
// lldbg-check:[...]$1 = { 0 = { 0 = 1 1 = OneThousand } 1 = 2 }
|
||||
// lldbr-check:(((u64, c_style_enum_in_composite::AnEnum), u64)) tuple_padding_at_end = { 0 = { 0 = 1 1 = OneThousand } 1 = 2 }
|
||||
|
||||
// lldb-command:print tuple_different_enums
|
||||
// lldbg-check:[...]$2 = (OneThousand, MountainView, OneMillion, Vienna)
|
||||
// lldbr-check:((c_style_enum_in_composite::AnEnum, c_style_enum_in_composite::AnotherEnum, c_style_enum_in_composite::AnEnum, c_style_enum_in_composite::AnotherEnum)) tuple_different_enums = { = c_style_enum_in_composite::AnEnum::OneThousand = c_style_enum_in_composite::AnotherEnum::MountainView = c_style_enum_in_composite::AnEnum::OneMillion = c_style_enum_in_composite::AnotherEnum::Vienna }
|
||||
// lldbg-check:[...]$2 = { 0 = OneThousand 1 = MountainView 2 = OneMillion 3 = Vienna }
|
||||
// lldbr-check:((c_style_enum_in_composite::AnEnum, c_style_enum_in_composite::AnotherEnum, c_style_enum_in_composite::AnEnum, c_style_enum_in_composite::AnotherEnum)) tuple_different_enums = { 0 = c_style_enum_in_composite::AnEnum::OneThousand 1 = c_style_enum_in_composite::AnotherEnum::MountainView 2 = c_style_enum_in_composite::AnEnum::OneMillion 3 = c_style_enum_in_composite::AnotherEnum::Vienna }
|
||||
|
||||
// lldb-command:print padded_struct
|
||||
// lldbg-check:[...]$3 = PaddedStruct { a: 3, b: OneMillion, c: 4, d: Toronto, e: 5 }
|
||||
// lldbr-check:(c_style_enum_in_composite::PaddedStruct) padded_struct = PaddedStruct { a: 3, b: c_style_enum_in_composite::AnEnum::OneMillion, c: 4, d: c_style_enum_in_composite::AnotherEnum::Toronto, e: 5 }
|
||||
// lldbg-check:[...]$3 = { a = 3 b = OneMillion c = 4 d = Toronto e = 5 }
|
||||
// lldbr-check:(c_style_enum_in_composite::PaddedStruct) padded_struct = { a = 3 b = c_style_enum_in_composite::AnEnum::OneMillion c = 4 d = Toronto e = 5 }
|
||||
|
||||
// lldb-command:print packed_struct
|
||||
// lldbg-check:[...]$4 = PackedStruct { a: 6, b: OneHundred, c: 7, d: Vienna, e: 8 }
|
||||
// lldbr-check:(c_style_enum_in_composite::PackedStruct) packed_struct = PackedStruct { a: 6, b: c_style_enum_in_composite::AnEnum::OneHundred, c: 7, d: c_style_enum_in_composite::AnotherEnum::Vienna, e: 8 }
|
||||
// lldbg-check:[...]$4 = { a = 6 b = OneHundred c = 7 d = Vienna e = 8 }
|
||||
// lldbr-check:(c_style_enum_in_composite::PackedStruct) packed_struct = { a = 6 b = c_style_enum_in_composite::AnEnum::OneHundred c = 7 d = Vienna e = 8 }
|
||||
|
||||
// lldb-command:print non_padded_struct
|
||||
// lldbg-check:[...]$5 = NonPaddedStruct { a: OneMillion, b: MountainView, c: OneThousand, d: Toronto }
|
||||
// lldbr-check:(c_style_enum_in_composite::NonPaddedStruct) non_padded_struct = NonPaddedStruct { a: c_style_enum_in_composite::AnEnum::OneMillion, b: c_style_enum_in_composite::AnotherEnum::MountainView, c: c_style_enum_in_composite::AnEnum::OneThousand, d: c_style_enum_in_composite::AnotherEnum::Toronto }
|
||||
// lldbg-check:[...]$5 = { a = OneMillion b = MountainView c = OneThousand d = Toronto }
|
||||
// lldbr-check:(c_style_enum_in_composite::NonPaddedStruct) non_padded_struct = { a = c_style_enum_in_composite::AnEnum::OneMillion, b = c_style_enum_in_composite::AnotherEnum::MountainView, c = c_style_enum_in_composite::AnEnum::OneThousand, d = c_style_enum_in_composite::AnotherEnum::Toronto }
|
||||
|
||||
// lldb-command:print struct_with_drop
|
||||
// lldbg-check:[...]$6 = (StructWithDrop { a: OneHundred, b: Vienna }, 9)
|
||||
// lldbr-check:((c_style_enum_in_composite::StructWithDrop, i64)) struct_with_drop = { = StructWithDrop { a: c_style_enum_in_composite::AnEnum::OneHundred, b: c_style_enum_in_composite::AnotherEnum::Vienna } = 9 }
|
||||
// lldbg-check:[...]$6 = { 0 = { a = OneHundred b = Vienna } 1 = 9 }
|
||||
// lldbr-check:((c_style_enum_in_composite::StructWithDrop, i64)) struct_with_drop = { 0 = { a = c_style_enum_in_composite::AnEnum::OneHundred b = c_style_enum_in_composite::AnotherEnum::Vienna } 1 = 9 }
|
||||
|
||||
#![allow(unused_variables)]
|
||||
#![feature(omit_gdb_pretty_printer_section)]
|
||||
|
@ -44,8 +44,8 @@ extern crate cross_crate_spans;
|
||||
// lldb-command:run
|
||||
|
||||
// lldb-command:print result
|
||||
// lldbg-check:[...]$0 = (17, 17)
|
||||
// lldbr-check:((u32, u32)) result = { = 17 = 17 }
|
||||
// lldbg-check:[...]$0 = { 0 = 17 1 = 17 }
|
||||
// lldbr-check:((u32, u32)) result = { 0 = 17 1 = 17 }
|
||||
// lldb-command:print a_variable
|
||||
// lldbg-check:[...]$1 = 123456789
|
||||
// lldbr-check:(u32) a_variable = 123456789
|
||||
@ -55,8 +55,8 @@ extern crate cross_crate_spans;
|
||||
// lldb-command:continue
|
||||
|
||||
// lldb-command:print result
|
||||
// lldbg-check:[...]$3 = (1212, 1212)
|
||||
// lldbr-check:((i16, i16)) result = { = 1212 = 1212 }
|
||||
// lldbg-check:[...]$3 = { 0 = 1212 1 = 1212 }
|
||||
// lldbr-check:((i16, i16)) result = { 0 = 1212 1 = 1212 }
|
||||
// lldb-command:print a_variable
|
||||
// lldbg-check:[...]$4 = 123456789
|
||||
// lldbr-check:(u32) a_variable = 123456789
|
||||
|
@ -186,16 +186,16 @@
|
||||
// lldbg-check:[...]$5 = 5
|
||||
// lldbr-check:(isize) a = 5
|
||||
// lldb-command:print b
|
||||
// lldbg-check:[...]$6 = (6, 7)
|
||||
// lldbr-check:((u32, u32)) b = { = 6 = 7 }
|
||||
// lldbg-check:[...]$6 = { 0 = 6 1 = 7 }
|
||||
// lldbr-check:((u32, u32)) b = { 0 = 6 1 = 7 }
|
||||
// lldb-command:continue
|
||||
|
||||
// lldb-command:print h
|
||||
// lldbg-check:[...]$7 = 8
|
||||
// lldbr-check:(i16) h = 8
|
||||
// lldb-command:print i
|
||||
// lldbg-check:[...]$8 = Struct { a: 9, b: 10 }
|
||||
// lldbr-check:(destructured_fn_argument::Struct) i = Struct { a: 9, b: 10 }
|
||||
// lldbg-check:[...]$8 = { a = 9 b = 10 }
|
||||
// lldbr-check:(destructured_fn_argument::Struct) i = { a = 9 b = 10 }
|
||||
// lldb-command:print j
|
||||
// lldbg-check:[...]$9 = 11
|
||||
// lldbr-check:(i16) j = 11
|
||||
@ -229,8 +229,8 @@
|
||||
// lldbg-check:[...]$16 = 20
|
||||
// lldbr-check:(i32) q = 20
|
||||
// lldb-command:print r
|
||||
// lldbg-check:[...]$17 = Struct { a: 21, b: 22 }
|
||||
// lldbr-check:(destructured_fn_argument::Struct) r = Struct { a: 21, b: 22 }
|
||||
// lldbg-check:[...]$17 = { a = 21 b = 22 }
|
||||
// lldbr-check:(destructured_fn_argument::Struct) r = { a = 21, b = 22 }
|
||||
// lldb-command:continue
|
||||
|
||||
// lldb-command:print s
|
||||
@ -271,13 +271,13 @@
|
||||
// lldb-command:continue
|
||||
|
||||
// lldb-command:print aa
|
||||
// lldbg-check:[...]$29 = (34, 35)
|
||||
// lldbr-check:((isize, isize)) aa = { = 34 = 35 }
|
||||
// lldbg-check:[...]$29 = { 0 = 34 1 = 35 }
|
||||
// lldbr-check:((isize, isize)) aa = { 0 = 34 1 = 35 }
|
||||
// lldb-command:continue
|
||||
|
||||
// lldb-command:print bb
|
||||
// lldbg-check:[...]$30 = (36, 37)
|
||||
// lldbr-check:((isize, isize)) bb = { = 36 = 37 }
|
||||
// lldbg-check:[...]$30 = { 0 = 36 1 = 37 }
|
||||
// lldbr-check:((isize, isize)) bb = { 0 = 36 1 = 37 }
|
||||
// lldb-command:continue
|
||||
|
||||
// lldb-command:print cc
|
||||
@ -286,21 +286,21 @@
|
||||
// lldb-command:continue
|
||||
|
||||
// lldb-command:print dd
|
||||
// lldbg-check:[...]$32 = (40, 41, 42)
|
||||
// lldbr-check:((isize, isize, isize)) dd = { = 40 = 41 = 42 }
|
||||
// lldbg-check:[...]$32 = { 0 = 40 1 = 41 2 = 42 }
|
||||
// lldbr-check:((isize, isize, isize)) dd = { 0 = 40 1 = 41 2 = 42 }
|
||||
// lldb-command:continue
|
||||
|
||||
// lldb-command:print *ee
|
||||
// lldbg-check:[...]$33 = (43, 44, 45)
|
||||
// lldbr-check:((isize, isize, isize)) *ee = { = 43 = 44 = 45 }
|
||||
// lldbg-check:[...]$33 = { 0 = 43 1 = 44 2 = 45 }
|
||||
// lldbr-check:((isize, isize, isize)) *ee = { 0 = 43 1 = 44 2 = 45 }
|
||||
// lldb-command:continue
|
||||
|
||||
// lldb-command:print *ff
|
||||
// lldbg-check:[...]$34 = 46
|
||||
// lldbr-check:(isize) *ff = 46
|
||||
// lldb-command:print gg
|
||||
// lldbg-check:[...]$35 = (47, 48)
|
||||
// lldbr-check:((isize, isize)) gg = { = 47 = 48 }
|
||||
// lldbg-check:[...]$35 = { 0 = 47 1 = 48 }
|
||||
// lldbr-check:((isize, isize)) gg = { 0 = 47 1 = 48 }
|
||||
// lldb-command:continue
|
||||
|
||||
// lldb-command:print *hh
|
||||
|
@ -164,13 +164,13 @@
|
||||
// lldb-command:continue
|
||||
|
||||
// lldb-command:print simple_struct_ident
|
||||
// lldbg-check:[...]$22 = Struct { x: 3537, y: 35437.5, z: true }
|
||||
// lldbr-check:(destructured_for_loop_variable::Struct) simple_struct_ident = Struct { x: 3537, y: 35437.5, z: true }
|
||||
// lldbg-check:[...]$22 = { x = 3537 y = 35437.5 z = true }
|
||||
// lldbr-check:(destructured_for_loop_variable::Struct) simple_struct_ident = { x = 3537 y = 35437.5 z = true }
|
||||
// lldb-command:continue
|
||||
|
||||
// lldb-command:print simple_tuple_ident
|
||||
// lldbg-check:[...]$23 = (34903493, 232323)
|
||||
// lldbr-check:((u32, i64)) simple_tuple_ident = { = 34903493 = 232323 }
|
||||
// lldbg-check:[...]$23 = { 0 = 34903493 1 = 232323 }
|
||||
// lldbr-check:((u32, i64)) simple_tuple_ident = { 0 = 34903493 1 = 232323 }
|
||||
// lldb-command:continue
|
||||
|
||||
#![allow(unused_variables)]
|
||||
|
@ -150,15 +150,15 @@
|
||||
// lldbg-check:[...]$5 = 5
|
||||
// lldbr-check:(isize) f = 5
|
||||
// lldb-command:print g
|
||||
// lldbg-check:[...]$6 = (6, 7)
|
||||
// lldbr-check:((u32, u32)) g = { = 6 = 7 }
|
||||
// lldbg-check:[...]$6 = { 0 = 6 1 = 7 }
|
||||
// lldbr-check:((u32, u32)) g = { 0 = 6 1 = 7 }
|
||||
|
||||
// lldb-command:print h
|
||||
// lldbg-check:[...]$7 = 8
|
||||
// lldbr-check:(i16) h = 8
|
||||
// lldb-command:print i
|
||||
// lldbg-check:[...]$8 = Struct { a: 9, b: 10 }
|
||||
// lldbr-check:(destructured_local::Struct) i = Struct { a: 9, b: 10 }
|
||||
// lldbg-check:[...]$8 = { a = 9 b = 10 }
|
||||
// lldbr-check:(destructured_local::Struct) i = { a = 9 b = 10 }
|
||||
// lldb-command:print j
|
||||
// lldbg-check:[...]$9 = 11
|
||||
// lldbr-check:(i16) j = 11
|
||||
@ -188,8 +188,8 @@
|
||||
// lldbg-check:[...]$16 = 20
|
||||
// lldbr-check:(i32) q = 20
|
||||
// lldb-command:print r
|
||||
// lldbg-check:[...]$17 = Struct { a: 21, b: 22 }
|
||||
// lldbr-check:(destructured_local::Struct) r = Struct { a: 21, b: 22 }
|
||||
// lldbg-check:[...]$17 = { a = 21 b = 22 }
|
||||
// lldbr-check:(destructured_local::Struct) r = { a = 21 b = 22 }
|
||||
|
||||
// lldb-command:print s
|
||||
// lldbg-check:[...]$18 = 24
|
||||
@ -227,32 +227,32 @@
|
||||
// lldbr-check:(i32) ue = 33
|
||||
|
||||
// lldb-command:print aa
|
||||
// lldbg-check:[...]$29 = (34, 35)
|
||||
// lldbr-check:((i32, i32)) aa = { = 34 = 35 }
|
||||
// lldbg-check:[...]$29 = { 0 = 34 1 = 35 }
|
||||
// lldbr-check:((i32, i32)) aa = { 0 = 34 1 = 35 }
|
||||
|
||||
// lldb-command:print bb
|
||||
// lldbg-check:[...]$30 = (36, 37)
|
||||
// lldbr-check:((i32, i32)) bb = { = 36 = 37 }
|
||||
// lldbg-check:[...]$30 = { 0 = 36 1 = 37 }
|
||||
// lldbr-check:((i32, i32)) bb = { 0 = 36 1 = 37 }
|
||||
|
||||
// lldb-command:print cc
|
||||
// lldbg-check:[...]$31 = 38
|
||||
// lldbr-check:(i32) cc = 38
|
||||
|
||||
// lldb-command:print dd
|
||||
// lldbg-check:[...]$32 = (40, 41, 42)
|
||||
// lldbr-check:((i32, i32, i32)) dd = { = 40 = 41 = 42 }
|
||||
// lldbg-check:[...]$32 = { 0 = 40 1 = 41 2 = 42 }
|
||||
// lldbr-check:((i32, i32, i32)) dd = { 0 = 40 1 = 41 2 = 42}
|
||||
|
||||
// lldb-command:print *ee
|
||||
// lldbg-check:[...]$33 = (43, 44, 45)
|
||||
// lldbr-check:((i32, i32, i32)) *ee = { = 43 = 44 = 45 }
|
||||
// lldbg-check:[...]$33 = { 0 = 43 1 = 44 2 = 45 }
|
||||
// lldbr-check:((i32, i32, i32)) *ee = { 0 = 43 1 = 44 2 = 45}
|
||||
|
||||
// lldb-command:print *ff
|
||||
// lldbg-check:[...]$34 = 46
|
||||
// lldbr-check:(i32) *ff = 46
|
||||
|
||||
// lldb-command:print gg
|
||||
// lldbg-check:[...]$35 = (47, 48)
|
||||
// lldbr-check:((i32, i32)) gg = { = 47 = 48 }
|
||||
// lldbg-check:[...]$35 = { 0 = 47 1 = 48 }
|
||||
// lldbr-check:((i32, i32)) gg = { 0 = 47 1 = 48 }
|
||||
|
||||
// lldb-command:print *hh
|
||||
// lldbg-check:[...]$36 = 50
|
||||
|
@ -1,7 +1,7 @@
|
||||
// ignore-windows failing on win32 bot
|
||||
// ignore-android: FIXME(#10381)
|
||||
// compile-flags:-g
|
||||
// min-gdb-version: 7.7
|
||||
// min-gdb-version: 8.1
|
||||
// ignore-gdb-version: 7.11.90 - 8.0.9
|
||||
// min-lldb-version: 310
|
||||
|
||||
@ -20,10 +20,10 @@
|
||||
// lldb-command: run
|
||||
|
||||
// lldb-command: fr v empty_string
|
||||
// lldb-check:[...]empty_string = ""
|
||||
// lldb-check:[...]empty_string = "" { vec = size=0 }
|
||||
|
||||
// lldb-command: fr v empty_str
|
||||
// lldb-check:[...]empty_str = ""
|
||||
// lldb-check:[...]empty_str = "" { data_ptr = [...] length = 0 }
|
||||
|
||||
fn main() {
|
||||
let empty_string = String::new();
|
||||
|
@ -15,7 +15,8 @@
|
||||
// lldb-command:run
|
||||
|
||||
// lldb-command:print *abc
|
||||
// lldbg-check:(enum_thinlto::ABC) $0 = ABC { }
|
||||
// lldbg-check:(enum_thinlto::ABC) $0 =
|
||||
// lldbr-check:(enum_thinlto::ABC) *abc = (x = 0, y = 8970181431921507452)
|
||||
|
||||
#![allow(unused_variables)]
|
||||
#![feature(omit_gdb_pretty_printer_section)]
|
||||
|
@ -33,23 +33,23 @@
|
||||
// lldb-command:run
|
||||
|
||||
// lldb-command:print no_padding1
|
||||
// lldbg-check:[...]$0 = NoPadding1 { x: [0, 1, 2], y: -3, z: [4.5, 5.5] }
|
||||
// lldbr-check:(evec_in_struct::NoPadding1) no_padding1 = NoPadding1 { x: [0, 1, 2], y: -3, z: [4.5, 5.5] }
|
||||
// lldbg-check:[...]$0 = { x = { [0] = 0 [1] = 1 [2] = 2 } y = -3 z = { [0] = 4.5 [1] = 5.5 } }
|
||||
// lldbr-check:(evec_in_struct::NoPadding1) no_padding1 = { x = { [0] = 0 [1] = 1 [2] = 2 } y = -3 z = { [0] = 4.5 [1] = 5.5 } }
|
||||
// lldb-command:print no_padding2
|
||||
// lldbg-check:[...]$1 = NoPadding2 { x: [6, 7, 8], y: [[9, 10], [11, 12]] }
|
||||
// lldbr-check:(evec_in_struct::NoPadding2) no_padding2 = NoPadding2 { x: [6, 7, 8], y: [[9, 10], [11, 12]] }
|
||||
// lldbg-check:[...]$1 = { x = { [0] = 6 [1] = 7 [2] = 8 } y = { [0] = { [0] = 9 [1] = 10 } [1] = { [0] = 11 [1] = 12 } } }
|
||||
// lldbr-check:(evec_in_struct::NoPadding2) no_padding2 = { x = { [0] = 6 [1] = 7 [2] = 8 } y = { [0] = { [0] = 9 [1] = 10 } [1] = { [0] = 11 [1] = 12 } } }
|
||||
|
||||
// lldb-command:print struct_internal_padding
|
||||
// lldbg-check:[...]$2 = StructInternalPadding { x: [13, 14], y: [15, 16] }
|
||||
// lldbr-check:(evec_in_struct::StructInternalPadding) struct_internal_padding = StructInternalPadding { x: [13, 14], y: [15, 16] }
|
||||
// lldbg-check:[...]$2 = { x = { [0] = 13 [1] = 14 } y = { [0] = 15 [1] = 16 } }
|
||||
// lldbr-check:(evec_in_struct::StructInternalPadding) struct_internal_padding = { x = { [0] = 13 [1] = 14 } y = { [0] = 15 [1] = 16 } }
|
||||
|
||||
// lldb-command:print single_vec
|
||||
// lldbg-check:[...]$3 = SingleVec { x: [17, 18, 19, 20, 21] }
|
||||
// lldbr-check:(evec_in_struct::SingleVec) single_vec = SingleVec { x: [17, 18, 19, 20, 21] }
|
||||
// lldbg-check:[...]$3 = { x = { [0] = 17 [1] = 18 [2] = 19 [3] = 20 [4] = 21 } }
|
||||
// lldbr-check:(evec_in_struct::SingleVec) single_vec = { x = { [0] = 17 [1] = 18 [2] = 19 [3] = 20 [4] = 21 } }
|
||||
|
||||
// lldb-command:print struct_padded_at_end
|
||||
// lldbg-check:[...]$4 = StructPaddedAtEnd { x: [22, 23], y: [24, 25] }
|
||||
// lldbr-check:(evec_in_struct::StructPaddedAtEnd) struct_padded_at_end = StructPaddedAtEnd { x: [22, 23], y: [24, 25] }
|
||||
// lldbg-check:[...]$4 = { x = { [0] = 22 [1] = 23 } y = { [0] = 24 [1] = 25 } }
|
||||
// lldbr-check:(evec_in_struct::StructPaddedAtEnd) struct_padded_at_end = { x = { [0] = 22 [1] = 23 } y = { [0] = 24 [1] = 25 } }
|
||||
|
||||
#![allow(unused_variables)]
|
||||
#![feature(omit_gdb_pretty_printer_section)]
|
||||
|
@ -30,9 +30,9 @@
|
||||
|
||||
// NON IMMEDIATE ARGS
|
||||
// lldb-command:print a
|
||||
// lldb-check:[...]$3 = BigStruct { a: 3, b: 4, c: 5, d: 6, e: 7, f: 8, g: 9, h: 10 }
|
||||
// lldb-check:[...]$3 = { a = 3, b = 4, c = 5, d = 6, e = 7, f = 8, g = 9, h = 10 }
|
||||
// lldb-command:print b
|
||||
// lldb-check:[...]$4 = BigStruct { a: 11, b: 12, c: 13, d: 14, e: 15, f: 16, g: 17, h: 18 }
|
||||
// lldb-check:[...]$4 = { a = 11, b = 12, c = 13, d = 14, e = 15, f = 16, g = 17, h = 18 }
|
||||
// lldb-command:continue
|
||||
|
||||
// BINDING
|
||||
|
@ -1,14 +1,14 @@
|
||||
// ignore-tidy-linelength
|
||||
// ignore-lldb
|
||||
// ignore-android: FIXME(#10381)
|
||||
// min-gdb-version: 7.11
|
||||
// min-gdb-version: 8.1
|
||||
|
||||
// compile-flags:-g
|
||||
|
||||
// gdb-command: run
|
||||
|
||||
// gdb-command: print regular_struct
|
||||
// gdbg-check:$1 = RegularStruct = {the_first_field = 101, the_second_field = 102.5, the_third_field = false}
|
||||
// gdbg-check:$1 = {the_first_field = 101, the_second_field = 102.5, the_third_field = false}
|
||||
// gdbr-check:$1 = gdb_pretty_struct_and_enums::RegularStruct {the_first_field: 101, the_second_field: 102.5, the_third_field: false}
|
||||
|
||||
// gdb-command: print empty_struct
|
||||
|
@ -24,16 +24,16 @@
|
||||
|
||||
// lldb-command:run
|
||||
// lldb-command:print b
|
||||
// lldbg-check:(generator_objects::main::generator-0) $0 = generator-0(&0x[...])
|
||||
// lldbg-check:(generator_objects::main::generator-0) $0 = { 0 = 0x[...] }
|
||||
// lldb-command:continue
|
||||
// lldb-command:print b
|
||||
// lldbg-check:(generator_objects::main::generator-0) $1 = generator-0(&0x[...])
|
||||
// lldbg-check:(generator_objects::main::generator-0) $1 = { 0 = 0x[...] }
|
||||
// lldb-command:continue
|
||||
// lldb-command:print b
|
||||
// lldbg-check:(generator_objects::main::generator-0) $2 = generator-0(&0x[...])
|
||||
// lldbg-check:(generator_objects::main::generator-0) $2 = { 0 = 0x[...] }
|
||||
// lldb-command:continue
|
||||
// lldb-command:print b
|
||||
// lldbg-check:(generator_objects::main::generator-0) $3 = generator-0(&0x[...])
|
||||
// lldbg-check:(generator_objects::main::generator-0) $3 = { 0 = 0x[...] }
|
||||
|
||||
#![feature(omit_gdb_pretty_printer_section, generators, generator_trait)]
|
||||
#![omit_gdb_pretty_printer_section]
|
||||
|
@ -49,8 +49,8 @@
|
||||
// lldbg-check:[...]$4 = 5
|
||||
// lldbr-check:(i32) *t0 = 5
|
||||
// lldb-command:print *t1
|
||||
// lldbg-check:[...]$5 = Struct { a: 6, b: 7.5 }
|
||||
// lldbr-check:(generic_function::Struct) *t1 = Struct { a: 6, b: 7.5 }
|
||||
// lldbg-check:[...]$5 = { a = 6 b = 7.5 }
|
||||
// lldbr-check:(generic_function::Struct) *t1 = { a = 6 b = 7.5 }
|
||||
// lldb-command:continue
|
||||
|
||||
#![feature(omit_gdb_pretty_printer_section)]
|
||||
|
@ -67,8 +67,8 @@
|
||||
|
||||
// STACK BY REF
|
||||
// lldb-command:print *self
|
||||
// lldbg-check:[...]$0 = Struct<(u32, i32)> { x: (8888, -8888) }
|
||||
// lldbr-check:(generic_method_on_generic_struct::Struct<(u32, i32)>) *self = { x = { = 8888 = -8888 } }
|
||||
// lldbg-check:[...]$0 = { x = { 0 = 8888, 1 = -8888 } }
|
||||
// lldbr-check:(generic_method_on_generic_struct::Struct<(u32, i32)>) *self = { x = { 0 = 8888 1 = -8888 } }
|
||||
// lldb-command:print arg1
|
||||
// lldbg-check:[...]$1 = -1
|
||||
// lldbr-check:(isize) arg1 = -1
|
||||
@ -79,8 +79,8 @@
|
||||
|
||||
// STACK BY VAL
|
||||
// lldb-command:print self
|
||||
// lldbg-check:[...]$3 = Struct<(u32, i32)> { x: (8888, -8888) }
|
||||
// lldbr-check:(generic_method_on_generic_struct::Struct<(u32, i32)>) self = { x = { = 8888 = -8888 } }
|
||||
// lldbg-check:[...]$3 = { x = { 0 = 8888, 1 = -8888 } }
|
||||
// lldbr-check:(generic_method_on_generic_struct::Struct<(u32, i32)>) self = { x = { 0 = 8888, 1 = -8888 } }
|
||||
// lldb-command:print arg1
|
||||
// lldbg-check:[...]$4 = -3
|
||||
// lldbr-check:(isize) arg1 = -3
|
||||
@ -91,8 +91,8 @@
|
||||
|
||||
// OWNED BY REF
|
||||
// lldb-command:print *self
|
||||
// lldbg-check:[...]$6 = Struct<f64> { x: 1234.5 }
|
||||
// lldbr-check:(generic_method_on_generic_struct::Struct<f64>) *self = Struct<f64> { x: 1234.5 }
|
||||
// lldbg-check:[...]$6 = { x = 1234.5 }
|
||||
// lldbr-check:(generic_method_on_generic_struct::Struct<f64>) *self = { x = 1234.5 }
|
||||
// lldb-command:print arg1
|
||||
// lldbg-check:[...]$7 = -5
|
||||
// lldbr-check:(isize) arg1 = -5
|
||||
@ -103,8 +103,8 @@
|
||||
|
||||
// OWNED BY VAL
|
||||
// lldb-command:print self
|
||||
// lldbg-check:[...]$9 = Struct<f64> { x: 1234.5 }
|
||||
// lldbr-check:(generic_method_on_generic_struct::Struct<f64>) self = Struct<f64> { x: 1234.5 }
|
||||
// lldbg-check:[...]$9 = { x = 1234.5 }
|
||||
// lldbr-check:(generic_method_on_generic_struct::Struct<f64>) self = { x = 1234.5 }
|
||||
// lldb-command:print arg1
|
||||
// lldbg-check:[...]$10 = -7
|
||||
// lldbr-check:(isize) arg1 = -7
|
||||
@ -115,8 +115,8 @@
|
||||
|
||||
// OWNED MOVED
|
||||
// lldb-command:print *self
|
||||
// lldbg-check:[...]$12 = Struct<f64> { x: 1234.5 }
|
||||
// lldbr-check:(generic_method_on_generic_struct::Struct<f64>) *self = Struct<f64> { x: 1234.5 }
|
||||
// lldbg-check:[...]$12 = { x = 1234.5 }
|
||||
// lldbr-check:(generic_method_on_generic_struct::Struct<f64>) *self = { x = 1234.5 }
|
||||
// lldb-command:print arg1
|
||||
// lldbg-check:[...]$13 = -9
|
||||
// lldbr-check:(isize) arg1 = -9
|
||||
|
@ -4,7 +4,6 @@
|
||||
|
||||
// min-lldb-version: 310
|
||||
// ignore-gdb
|
||||
// ignore-tidy-linelength
|
||||
|
||||
// compile-flags:-g
|
||||
|
||||
@ -12,11 +11,11 @@
|
||||
// lldb-command:run
|
||||
|
||||
// lldb-command:print v
|
||||
// lldbg-check:[...]$0 = vec![1, 2, 3]
|
||||
// lldbr-check:(alloc::vec::Vec<i32>) v = vec![1, 2, 3]
|
||||
// lldbg-check:[...]$0 = size=3 { [0] = 1 [1] = 2 [2] = 3 }
|
||||
// lldbr-check:(alloc::vec::Vec<i32>) v = size=3 { [0] = 1 [1] = 2 [2] = 3 }
|
||||
// lldb-command:print zs
|
||||
// lldbg-check:[...]$1 = StructWithZeroSizedField { x: ZeroSizedStruct[...], y: 123, z: ZeroSizedStruct[...], w: 456 }
|
||||
// lldbr-check:(issue_22656::StructWithZeroSizedField) zs = StructWithZeroSizedField { x: ZeroSizedStruct { }, y: 123, z: ZeroSizedStruct { }, w: 456 }
|
||||
// lldbg-check:[...]$1 = { x = y = 123 z = w = 456 }
|
||||
// lldbr-check:(issue_22656::StructWithZeroSizedField) zs = { x = y = 123 z = w = 456 }
|
||||
// lldbr-command:continue
|
||||
|
||||
#![allow(unused_variables)]
|
||||
|
@ -22,10 +22,10 @@
|
||||
// lldb-command:run
|
||||
|
||||
// lldb-command:print g
|
||||
// lldbg-check:(issue_57822::main::closure-1) $0 = closure-1(closure-0(1))
|
||||
// lldbg-check:(issue_57822::main::closure-1) $0 = { 0 = { 0 = 1 } }
|
||||
|
||||
// lldb-command:print b
|
||||
// lldbg-check:(issue_57822::main::generator-3) $1 = generator-3(generator-2(2))
|
||||
// lldbg-check:(issue_57822::main::generator-3) $1 = { 0 = { 0 = 2 } }
|
||||
|
||||
#![feature(omit_gdb_pretty_printer_section, generators, generator_trait)]
|
||||
#![omit_gdb_pretty_printer_section]
|
||||
|
@ -63,7 +63,7 @@
|
||||
|
||||
// STACK BY REF
|
||||
// lldb-command:print *self
|
||||
// lldbg-check:[...]$0 = Struct { x: 100 }
|
||||
// lldbg-check:[...]$0 = { x = 100 }
|
||||
// lldbr-check:(method_on_struct::Struct) *self = Struct { x: 100 }
|
||||
// lldb-command:print arg1
|
||||
// lldbg-check:[...]$1 = -1
|
||||
@ -75,7 +75,7 @@
|
||||
|
||||
// STACK BY VAL
|
||||
// lldb-command:print self
|
||||
// lldbg-check:[...]$3 = Struct { x: 100 }
|
||||
// lldbg-check:[...]$3 = { x = 100 }
|
||||
// lldbr-check:(method_on_struct::Struct) self = Struct { x: 100 }
|
||||
// lldb-command:print arg1
|
||||
// lldbg-check:[...]$4 = -3
|
||||
@ -87,7 +87,7 @@
|
||||
|
||||
// OWNED BY REF
|
||||
// lldb-command:print *self
|
||||
// lldbg-check:[...]$6 = Struct { x: 200 }
|
||||
// lldbg-check:[...]$6 = { x = 200 }
|
||||
// lldbr-check:(method_on_struct::Struct) *self = Struct { x: 200 }
|
||||
// lldb-command:print arg1
|
||||
// lldbg-check:[...]$7 = -5
|
||||
@ -99,7 +99,7 @@
|
||||
|
||||
// OWNED BY VAL
|
||||
// lldb-command:print self
|
||||
// lldbg-check:[...]$9 = Struct { x: 200 }
|
||||
// lldbg-check:[...]$9 = { x = 200 }
|
||||
// lldbr-check:(method_on_struct::Struct) self = Struct { x: 200 }
|
||||
// lldb-command:print arg1
|
||||
// lldbg-check:[...]$10 = -7
|
||||
@ -111,7 +111,7 @@
|
||||
|
||||
// OWNED MOVED
|
||||
// lldb-command:print *self
|
||||
// lldbg-check:[...]$12 = Struct { x: 200 }
|
||||
// lldbg-check:[...]$12 = { x = 200 }
|
||||
// lldbr-check:(method_on_struct::Struct) *self = Struct { x: 200 }
|
||||
// lldb-command:print arg1
|
||||
// lldbg-check:[...]$13 = -9
|
||||
|
@ -63,8 +63,8 @@
|
||||
|
||||
// STACK BY REF
|
||||
// lldb-command:print *self
|
||||
// lldbg-check:[...]$0 = Struct { x: 100 }
|
||||
// lldbr-check:(method_on_trait::Struct) *self = Struct { x: 100 }
|
||||
// lldbg-check:[...]$0 = { x = 100 }
|
||||
// lldbr-check:(method_on_trait::Struct) *self = { x = 100 }
|
||||
// lldb-command:print arg1
|
||||
// lldbg-check:[...]$1 = -1
|
||||
// lldbr-check:(isize) arg1 = -1
|
||||
@ -75,8 +75,8 @@
|
||||
|
||||
// STACK BY VAL
|
||||
// lldb-command:print self
|
||||
// lldbg-check:[...]$3 = Struct { x: 100 }
|
||||
// lldbr-check:(method_on_trait::Struct) self = Struct { x: 100 }
|
||||
// lldbg-check:[...]$3 = { x = 100 }
|
||||
// lldbr-check:(method_on_trait::Struct) self = { x = 100 }
|
||||
// lldb-command:print arg1
|
||||
// lldbg-check:[...]$4 = -3
|
||||
// lldbr-check:(isize) arg1 = -3
|
||||
@ -87,8 +87,8 @@
|
||||
|
||||
// OWNED BY REF
|
||||
// lldb-command:print *self
|
||||
// lldbg-check:[...]$6 = Struct { x: 200 }
|
||||
// lldbr-check:(method_on_trait::Struct) *self = Struct { x: 200 }
|
||||
// lldbg-check:[...]$6 = { x = 200 }
|
||||
// lldbr-check:(method_on_trait::Struct) *self = { x = 200 }
|
||||
// lldb-command:print arg1
|
||||
// lldbg-check:[...]$7 = -5
|
||||
// lldbr-check:(isize) arg1 = -5
|
||||
@ -99,8 +99,8 @@
|
||||
|
||||
// OWNED BY VAL
|
||||
// lldb-command:print self
|
||||
// lldbg-check:[...]$9 = Struct { x: 200 }
|
||||
// lldbr-check:(method_on_trait::Struct) self = Struct { x: 200 }
|
||||
// lldbg-check:[...]$9 = { x = 200 }
|
||||
// lldbr-check:(method_on_trait::Struct) self = { x = 200 }
|
||||
// lldb-command:print arg1
|
||||
// lldbg-check:[...]$10 = -7
|
||||
// lldbr-check:(isize) arg1 = -7
|
||||
@ -111,8 +111,8 @@
|
||||
|
||||
// OWNED MOVED
|
||||
// lldb-command:print *self
|
||||
// lldbg-check:[...]$12 = Struct { x: 200 }
|
||||
// lldbr-check:(method_on_trait::Struct) *self = Struct { x: 200 }
|
||||
// lldbg-check:[...]$12 = { x = 200 }
|
||||
// lldbr-check:(method_on_trait::Struct) *self = { x = 200 }
|
||||
// lldb-command:print arg1
|
||||
// lldbg-check:[...]$13 = -9
|
||||
// lldbr-check:(isize) arg1 = -9
|
||||
|
@ -63,8 +63,8 @@
|
||||
|
||||
// STACK BY REF
|
||||
// lldb-command:print *self
|
||||
// lldbg-check:[...]$0 = TupleStruct(100, -100.5)
|
||||
// lldbr-check:(method_on_tuple_struct::TupleStruct) *self = TupleStruct(100, -100.5)
|
||||
// lldbg-check:[...]$0 = { 0 = 100 1 = -100.5 }
|
||||
// lldbr-check:(method_on_tuple_struct::TupleStruct) *self = { 0 = 100 1 = -100.5 }
|
||||
// lldb-command:print arg1
|
||||
// lldbg-check:[...]$1 = -1
|
||||
// lldbr-check:(isize) arg1 = -1
|
||||
@ -75,8 +75,8 @@
|
||||
|
||||
// STACK BY VAL
|
||||
// lldb-command:print self
|
||||
// lldbg-check:[...]$3 = TupleStruct(100, -100.5)
|
||||
// lldbr-check:(method_on_tuple_struct::TupleStruct) self = TupleStruct(100, -100.5)
|
||||
// lldbg-check:[...]$3 = { 0 = 100 1 = -100.5 }
|
||||
// lldbr-check:(method_on_tuple_struct::TupleStruct) self = { 0 = 100 1 = -100.5 }
|
||||
// lldb-command:print arg1
|
||||
// lldbg-check:[...]$4 = -3
|
||||
// lldbr-check:(isize) arg1 = -3
|
||||
@ -87,8 +87,8 @@
|
||||
|
||||
// OWNED BY REF
|
||||
// lldb-command:print *self
|
||||
// lldbg-check:[...]$6 = TupleStruct(200, -200.5)
|
||||
// lldbr-check:(method_on_tuple_struct::TupleStruct) *self = TupleStruct(200, -200.5)
|
||||
// lldbg-check:[...]$6 = { 0 = 200 1 = -200.5 }
|
||||
// lldbr-check:(method_on_tuple_struct::TupleStruct) *self = { 0 = 200 1 = -200.5 }
|
||||
// lldb-command:print arg1
|
||||
// lldbg-check:[...]$7 = -5
|
||||
// lldbr-check:(isize) arg1 = -5
|
||||
@ -99,8 +99,8 @@
|
||||
|
||||
// OWNED BY VAL
|
||||
// lldb-command:print self
|
||||
// lldbg-check:[...]$9 = TupleStruct(200, -200.5)
|
||||
// lldbr-check:(method_on_tuple_struct::TupleStruct) self = TupleStruct(200, -200.5)
|
||||
// lldbg-check:[...]$9 = { 0 = 200 1 = -200.5 }
|
||||
// lldbr-check:(method_on_tuple_struct::TupleStruct) self = { 0 = 200 1 = -200.5 }
|
||||
// lldb-command:print arg1
|
||||
// lldbg-check:[...]$10 = -7
|
||||
// lldbr-check:(isize) arg1 = -7
|
||||
@ -111,8 +111,8 @@
|
||||
|
||||
// OWNED MOVED
|
||||
// lldb-command:print *self
|
||||
// lldbg-check:[...]$12 = TupleStruct(200, -200.5)
|
||||
// lldbr-check:(method_on_tuple_struct::TupleStruct) *self = TupleStruct(200, -200.5)
|
||||
// lldbg-check:[...]$12 = { 0 = 200 1 = -200.5 }
|
||||
// lldbr-check:(method_on_tuple_struct::TupleStruct) *self = { 0 = 200 1 = -200.5 }
|
||||
// lldb-command:print arg1
|
||||
// lldbg-check:[...]$13 = -9
|
||||
// lldbr-check:(isize) arg1 = -9
|
||||
|
@ -46,36 +46,36 @@
|
||||
// lldb-command:run
|
||||
|
||||
// lldb-command:print packed
|
||||
// lldbg-check:[...]$0 = Packed { x: 123, y: 234, z: 345 }
|
||||
// lldbr-check:(packed_struct_with_destructor::Packed) packed = Packed { x: 123, y: 234, z: 345 }
|
||||
// lldbg-check:[...]$0 = { x = 123 y = 234 z = 345 }
|
||||
// lldbr-check:(packed_struct_with_destructor::Packed) packed = { x = 123 y = 234 z = 345 }
|
||||
|
||||
// lldb-command:print packedInPacked
|
||||
// lldbg-check:[...]$1 = PackedInPacked { a: 1111, b: Packed { x: 2222, y: 3333, z: 4444 }, c: 5555, d: Packed { x: 6666, y: 7777, z: 8888 } }
|
||||
// lldbr-check:(packed_struct_with_destructor::PackedInPacked) packedInPacked = PackedInPacked { a: 1111, b: Packed { x: 2222, y: 3333, z: 4444 }, c: 5555, d: Packed { x: 6666, y: 7777, z: 8888 } }
|
||||
// lldbg-check:[...]$1 = { a = 1111 b = { x = 2222 y = 3333 z = 4444 } c = 5555 d = { x = 6666 y = 7777 z = 8888 } }
|
||||
// lldbr-check:(packed_struct_with_destructor::PackedInPacked) packedInPacked = { a = 1111 b = { x = 2222 y = 3333 z = 4444 } c = 5555 d = { x = 6666 y = 7777 z = 8888 } }
|
||||
|
||||
// lldb-command:print packedInUnpacked
|
||||
// lldbg-check:[...]$2 = PackedInUnpacked { a: -1111, b: Packed { x: -2222, y: -3333, z: -4444 }, c: -5555, d: Packed { x: -6666, y: -7777, z: -8888 } }
|
||||
// lldbr-check:(packed_struct_with_destructor::PackedInUnpacked) packedInUnpacked = PackedInUnpacked { a: -1111, b: Packed { x: -2222, y: -3333, z: -4444 }, c: -5555, d: Packed { x: -6666, y: -7777, z: -8888 } }
|
||||
// lldbg-check:[...]$2 = { a = -1111 b = { x = -2222 y = -3333 z = -4444 } c = -5555 d = { x = -6666 y = -7777 z = -8888 } }
|
||||
// lldbr-check:(packed_struct_with_destructor::PackedInUnpacked) packedInUnpacked = { a = -1111 b = { x = -2222 y = -3333 z = -4444 } c = -5555 d = { x = -6666 y = -7777 z = -8888 } }
|
||||
|
||||
// lldb-command:print unpackedInPacked
|
||||
// lldbg-check:[...]$3 = UnpackedInPacked { a: 987, b: Unpacked { x: 876, y: 765, z: 654 }, c: Unpacked { x: 543, y: 432, z: 321 }, d: 210 }
|
||||
// lldbr-check:(packed_struct_with_destructor::UnpackedInPacked) unpackedInPacked = UnpackedInPacked { a: 987, b: Unpacked { x: 876, y: 765, z: 654 }, c: Unpacked { x: 543, y: 432, z: 321 }, d: 210 }
|
||||
// lldbg-check:[...]$3 = { a = 987 b = { x = 876 y = 765 z = 654 } c = { x = 543 y = 432 z = 321 } d = 210 }
|
||||
// lldbr-check:(packed_struct_with_destructor::UnpackedInPacked) unpackedInPacked = { a = 987 b = { x = 876 y = 765 z = 654 } c = { x = 543 y = 432 z = 321 } d = 210 }
|
||||
|
||||
// lldb-command:print packedInPackedWithDrop
|
||||
// lldbg-check:[...]$4 = PackedInPackedWithDrop { a: 11, b: Packed { x: 22, y: 33, z: 44 }, c: 55, d: Packed { x: 66, y: 77, z: 88 } }
|
||||
// lldbr-check:(packed_struct_with_destructor::PackedInPackedWithDrop) packedInPackedWithDrop = PackedInPackedWithDrop { a: 11, b: Packed { x: 22, y: 33, z: 44 }, c: 55, d: Packed { x: 66, y: 77, z: 88 } }
|
||||
// lldbg-check:[...]$4 = { a = 11 b = { x = 22 y = 33 z = 44 } c = 55 d = { x = 66 y = 77 z = 88 } }
|
||||
// lldbr-check:(packed_struct_with_destructor::PackedInPackedWithDrop) packedInPackedWithDrop = { a = 11 b = { x = 22 y = 33 z = 44 } c = 55 d = { x = 66 y = 77 z = 88 } }
|
||||
|
||||
// lldb-command:print packedInUnpackedWithDrop
|
||||
// lldbg-check:[...]$5 = PackedInUnpackedWithDrop { a: -11, b: Packed { x: -22, y: -33, z: -44 }, c: -55, d: Packed { x: -66, y: -77, z: -88 } }
|
||||
// lldbr-check:(packed_struct_with_destructor::PackedInUnpackedWithDrop) packedInUnpackedWithDrop = PackedInUnpackedWithDrop { a: -11, b: Packed { x: -22, y: -33, z: -44 }, c: -55, d: Packed { x: -66, y: -77, z: -88 } }
|
||||
// lldbg-check:[...]$5 = { a = -11 b = { x = -22 y = -33 z = -44 } c = -55 d = { x = -66 y = -77 z = -88 } }
|
||||
// lldbr-check:(packed_struct_with_destructor::PackedInUnpackedWithDrop) packedInUnpackedWithDrop = { a = -11 b = { x = -22 y = -33 z = -44 } c = -55 d = { x = -66 y = -77 z = -88 } }
|
||||
|
||||
// lldb-command:print unpackedInPackedWithDrop
|
||||
// lldbg-check:[...]$6 = UnpackedInPackedWithDrop { a: 98, b: Unpacked { x: 87, y: 76, z: 65 }, c: Unpacked { x: 54, y: 43, z: 32 }, d: 21 }
|
||||
// lldbr-check:(packed_struct_with_destructor::UnpackedInPackedWithDrop) unpackedInPackedWithDrop = UnpackedInPackedWithDrop { a: 98, b: Unpacked { x: 87, y: 76, z: 65 }, c: Unpacked { x: 54, y: 43, z: 32 }, d: 21 }
|
||||
// lldbg-check:[...]$6 = { a = 98 b = { x = 87 y = 76 z = 65 } c = { x = 54 y = 43 z = 32 } d = 21 }
|
||||
// lldbr-check:(packed_struct_with_destructor::UnpackedInPackedWithDrop) unpackedInPackedWithDrop = { a = 98 b = { x = 87 y = 76 z = 65 } c = { x = 54 y = 43 z = 32 } d = 21 }
|
||||
|
||||
// lldb-command:print deeplyNested
|
||||
// lldbg-check:[...]$7 = DeeplyNested { a: PackedInPacked { a: 1, b: Packed { x: 2, y: 3, z: 4 }, c: 5, d: Packed { x: 6, y: 7, z: 8 } }, b: UnpackedInPackedWithDrop { a: 9, b: Unpacked { x: 10, y: 11, z: 12 }, c: Unpacked { x: 13, y: 14, z: 15 }, d: 16 }, c: PackedInUnpacked { a: 17, b: Packed { x: 18, y: 19, z: 20 }, c: 21, d: Packed { x: 22, y: 23, z: 24 } }, d: PackedInUnpackedWithDrop { a: 25, b: Packed { x: 26, y: 27, z: 28 }, c: 29, d: Packed { x: 30, y: 31, z: 32 } }, e: UnpackedInPacked { a: 33, b: Unpacked { x: 34, y: 35, z: 36 }, c: Unpacked { x: 37, y: 38, z: 39 }, d: 40 }, f: PackedInPackedWithDrop { a: 41, b: Packed { x: 42, y: 43, z: 44 }, c: 45, d: Packed { x: 46, y: 47, z: 48 } } }
|
||||
// lldbr-check:(packed_struct_with_destructor::DeeplyNested) deeplyNested = DeeplyNested { a: PackedInPacked { a: 1, b: Packed { x: 2, y: 3, z: 4 }, c: 5, d: Packed { x: 6, y: 7, z: 8 } }, b: UnpackedInPackedWithDrop { a: 9, b: Unpacked { x: 10, y: 11, z: 12 }, c: Unpacked { x: 13, y: 14, z: 15 }, d: 16 }, c: PackedInUnpacked { a: 17, b: Packed { x: 18, y: 19, z: 20 }, c: 21, d: Packed { x: 22, y: 23, z: 24 } }, d: PackedInUnpackedWithDrop { a: 25, b: Packed { x: 26, y: 27, z: 28 }, c: 29, d: Packed { x: 30, y: 31, z: 32 } }, e: UnpackedInPacked { a: 33, b: Unpacked { x: 34, y: 35, z: 36 }, c: Unpacked { x: 37, y: 38, z: 39 }, d: 40 }, f: PackedInPackedWithDrop { a: 41, b: Packed { x: 42, y: 43, z: 44 }, c: 45, d: Packed { x: 46, y: 47, z: 48 } } }
|
||||
// lldbg-check:[...]$7 = { a = { a = 1 b = { x = 2 y = 3 z = 4 } c = 5 d = { x = 6 y = 7 z = 8 } } b = { a = 9 b = { x = 10 y = 11 z = 12 } c = { x = 13 y = 14 z = 15 } d = 16 } c = { a = 17 b = { x = 18 y = 19 z = 20 } c = 21 d = { x = 22 y = 23 z = 24 } } d = { a = 25 b = { x = 26 y = 27 z = 28 } c = 29 d = { x = 30 y = 31 z = 32 } } e = { a = 33 b = { x = 34 y = 35 z = 36 } c = { x = 37 y = 38 z = 39 } d = 40 } f = { a = 41 b = { x = 42 y = 43 z = 44 } c = 45 d = { x = 46 y = 47 z = 48 } } }
|
||||
// lldbr-check:(packed_struct_with_destructor::DeeplyNested) deeplyNested = { a = { a = 1 b = { x = 2 y = 3 z = 4 } c = 5 d = { x = 6 y = 7 z = 8 } } b = { a = 9 b = { x = 10 y = 11 z = 12 } c = { x = 13 y = 14 z = 15 } d = 16 } c = { a = 17 b = { x = 18 y = 19 z = 20 } c = 21 d = { x = 22 y = 23 z = 24 } } d = { a = 25 b = { x = 26 y = 27 z = 28 } c = 29 d = { x = 30 y = 31 z = 32 } } e = { a = 33 b = { x = 34 y = 35 z = 36 } c = { x = 37 y = 38 z = 39 } d = 40 } f = { a = 41 b = { x = 42 y = 43 z = 44 } c = 45 d = { x = 46 y = 47 z = 48 } } }
|
||||
|
||||
|
||||
#![allow(unused_variables)]
|
||||
|
@ -36,20 +36,20 @@
|
||||
// lldb-command:run
|
||||
|
||||
// lldb-command:print packed
|
||||
// lldbg-check:[...]$0 = Packed { x: 123, y: 234, z: 345 }
|
||||
// lldbr-check:(packed_struct::Packed) packed = Packed { x: 123, y: 234, z: 345 }
|
||||
// lldbg-check:[...]$0 = { x = 123 y = 234 z = 345 }
|
||||
// lldbr-check:(packed_struct::Packed) packed = { x = 123 y = 234 z = 345 }
|
||||
|
||||
// lldb-command:print packedInPacked
|
||||
// lldbg-check:[...]$1 = PackedInPacked { a: 1111, b: Packed { x: 2222, y: 3333, z: 4444 }, c: 5555, d: Packed { x: 6666, y: 7777, z: 8888 } }
|
||||
// lldbr-check:(packed_struct::PackedInPacked) packedInPacked = PackedInPacked { a: 1111, b: Packed { x: 2222, y: 3333, z: 4444 }, c: 5555, d: Packed { x: 6666, y: 7777, z: 8888 } }
|
||||
// lldbg-check:[...]$1 = { a = 1111 b = { x = 2222 y = 3333 z = 4444 } c = 5555 d = { x = 6666 y = 7777 z = 8888 } }
|
||||
// lldbr-check:(packed_struct::PackedInPacked) packedInPacked = { a = 1111 b = { x = 2222 y = 3333 z = 4444 } c = 5555 d = { x = 6666 y = 7777 z = 8888 } }
|
||||
|
||||
// lldb-command:print packedInUnpacked
|
||||
// lldbg-check:[...]$2 = PackedInUnpacked { a: -1111, b: Packed { x: -2222, y: -3333, z: -4444 }, c: -5555, d: Packed { x: -6666, y: -7777, z: -8888 } }
|
||||
// lldbr-check:(packed_struct::PackedInUnpacked) packedInUnpacked = PackedInUnpacked { a: -1111, b: Packed { x: -2222, y: -3333, z: -4444 }, c: -5555, d: Packed { x: -6666, y: -7777, z: -8888 } }
|
||||
// lldbg-check:[...]$2 = { a = -1111 b = { x = -2222 y = -3333 z = -4444 } c = -5555 d = { x = -6666 y = -7777 z = -8888 } }
|
||||
// lldbr-check:(packed_struct::PackedInUnpacked) packedInUnpacked = { a = -1111 b = { x = -2222 y = -3333 z = -4444 } c = -5555 d = { x = -6666 y = -7777 z = -8888 } }
|
||||
|
||||
// lldb-command:print unpackedInPacked
|
||||
// lldbg-check:[...]$3 = UnpackedInPacked { a: 987, b: Unpacked { x: 876, y: 765, z: 654, w: 543 }, c: Unpacked { x: 432, y: 321, z: 210, w: 109 }, d: -98 }
|
||||
// lldbr-check:(packed_struct::UnpackedInPacked) unpackedInPacked = UnpackedInPacked { a: 987, b: Unpacked { x: 876, y: 765, z: 654, w: 543 }, c: Unpacked { x: 432, y: 321, z: 210, w: 109 }, d: -98 }
|
||||
// lldbg-check:[...]$3 = { a = 987 b = { x = 876 y = 765 z = 654 w = 543 } c = { x = 432 y = 321 z = 210 w = 109 } d = -98 }
|
||||
// lldbr-check:(packed_struct::UnpackedInPacked) unpackedInPacked = { a = 987 b = { x = 876 y = 765 z = 654 w = 543 } c = { x = 432 y = 321 z = 210 w = 109 } d = -98 }
|
||||
|
||||
// lldb-command:print sizeof(packed)
|
||||
// lldbg-check:[...]$4 = 14
|
||||
|
@ -2,7 +2,7 @@
|
||||
// ignore-freebsd: gdb package too new
|
||||
// ignore-android: FIXME(#10381)
|
||||
// compile-flags:-g
|
||||
// min-gdb-version 7.7
|
||||
// min-gdb-version 8.1
|
||||
// min-lldb-version: 310
|
||||
|
||||
// === GDB TESTS ===================================================================================
|
||||
@ -10,11 +10,10 @@
|
||||
// gdb-command: run
|
||||
|
||||
// gdb-command: print vec
|
||||
// gdb-check:$1 = Vec<u8>(len: 1000000000, cap: 1000000000) = {[...]...}
|
||||
// gdb-check:$1 = Vec(size=1000000000) = {[...]...}
|
||||
|
||||
// gdb-command: print slice
|
||||
// gdb-check:$2 = &[u8](len: 1000000000) = {[...]...}
|
||||
|
||||
// gdb-check:$2 = &[u8] {data_ptr: [...]"\000", length: 1000000000}
|
||||
|
||||
#![allow(unused_variables)]
|
||||
|
||||
|
@ -15,38 +15,76 @@
|
||||
// gdb-command: run
|
||||
|
||||
// gdb-command: print btree_set
|
||||
// gdb-check:$1 = BTreeSet<i32>(len: 15) = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14}
|
||||
// gdb-check:$1 = BTreeSet(size=15) = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14}
|
||||
|
||||
// gdb-command: print empty_btree_set
|
||||
// gdb-check:$2 = BTreeSet<i32>(len: 0)
|
||||
// gdb-check:$2 = BTreeSet(size=0)
|
||||
|
||||
// gdb-command: print btree_map
|
||||
// gdb-check:$3 = BTreeMap<i32, i32>(len: 15) = {[0] = 0, [1] = 1, [2] = 2, [3] = 3, [4] = 4, [5] = 5, [6] = 6, [7] = 7, [8] = 8, [9] = 9, [10] = 10, [11] = 11, [12] = 12, [13] = 13, [14] = 14}
|
||||
// gdb-check:$3 = BTreeMap(size=15) = {[0] = 0, [1] = 1, [2] = 2, [3] = 3, [4] = 4, [5] = 5, [6] = 6, [7] = 7, [8] = 8, [9] = 9, [10] = 10, [11] = 11, [12] = 12, [13] = 13, [14] = 14}
|
||||
|
||||
// gdb-command: print empty_btree_map
|
||||
// gdb-check:$4 = BTreeMap<i32, u32>(len: 0)
|
||||
// gdb-check:$4 = BTreeMap(size=0)
|
||||
|
||||
// gdb-command: print option_btree_map
|
||||
// gdb-check:$5 = BTreeMap<bool, core::option::Option<bool>>(len: 2) = {[false] = [...], [true] = [...]}
|
||||
// gdb-check:$5 = BTreeMap(size=2) = {[false] = [...], [true] = [...]}
|
||||
// (abbreviated because both values vary wildly over gdb versions and/or linux distributions)
|
||||
|
||||
// gdb-command: print nasty_btree_map
|
||||
// gdb-check:$6 = BTreeMap<i32, pretty_std_collections::MyLeafNode>(len: 15) = {[0] = pretty_std_collections::MyLeafNode (0), [...]}
|
||||
// gdb-check:$6 = BTreeMap(size=15) = {[0] = pretty_std_collections::MyLeafNode (0), [...]}
|
||||
// (abbreviated because it's boring but we need enough elements to include internal nodes)
|
||||
|
||||
// gdb-command: print vec_deque
|
||||
// gdb-check:$7 = VecDeque<i32>(len: 3, cap: 8) = {5, 3, 7}
|
||||
// gdb-check:$7 = VecDeque(size=3) = {5, 3, 7}
|
||||
|
||||
// gdb-command: print vec_deque2
|
||||
// gdb-check:$8 = VecDeque<i32>(len: 7, cap: 8) = {2, 3, 4, 5, 6, 7, 8}
|
||||
// gdb-check:$8 = VecDeque(size=7) = {2, 3, 4, 5, 6, 7, 8}
|
||||
|
||||
// gdb-command: print hash_map
|
||||
// gdb-check:$9 = HashMap(size=4) = {[1] = 10, [2] = 20, [3] = 30, [4] = 40}
|
||||
|
||||
// gdb-command: print hash_set
|
||||
// gdb-check:$10 = HashSet(size=4) = {1, 2, 3, 4}
|
||||
|
||||
// === LLDB TESTS ==================================================================================
|
||||
|
||||
// lldb-command:run
|
||||
|
||||
// lldb-command:print vec_deque
|
||||
// lldbg-check:[...]$0 = size=3 { [0] = 5 [1] = 3 [2] = 7 }
|
||||
// lldbr-check:(alloc::collections::vec_deque::VecDeque<i32>) vec_deque = size=3 = { [0] = 5 [1] = 3 [2] = 7 }
|
||||
|
||||
// lldb-command:print vec_deque2
|
||||
// lldbg-check:[...]$1 = size=7 { [0] = 2 [1] = 3 [2] = 4 [3] = 5 [4] = 6 [5] = 7 [6] = 8 }
|
||||
// lldbr-check:(alloc::collections::vec_deque::VecDeque<i32>) vec_deque2 = size=7 = { [0] = 2 [1] = 3 [2] = 4 [3] = 5 [4] = 6 [5] = 7 [6] = 8 }
|
||||
|
||||
// lldb-command:print hash_map
|
||||
// lldbg-check:[...]$2 = size=4 { [0] = { 0 = 1 1 = 10 } [1] = { 0 = 2 1 = 20 } [2] = { 0 = 3 1 = 30 } [3] = { 0 = 4 1 = 40 } }
|
||||
// lldbr-check:(std::collections::hash::map::HashMap<u64, u64, [...]>) hash_map = size=4 size=4 { [0] = { 0 = 1 1 = 10 } [1] = { 0 = 2 1 = 20 } [2] = { 0 = 3 1 = 30 } [3] = { 0 = 4 1 = 40 } }
|
||||
|
||||
// lldb-command:print hash_set
|
||||
// lldbg-check:[...]$3 = size=4 { [0] = 1 [1] = 2 [2] = 3 [3] = 4 }
|
||||
// lldbr-check:(std::collections::hash::set::HashSet<u64, [...]>) hash_set = size=4 { [0] = 1 [1] = 2 [2] = 3 [3] = 4 }
|
||||
|
||||
#![allow(unused_variables)]
|
||||
use std::collections::BTreeMap;
|
||||
use std::collections::BTreeSet;
|
||||
use std::collections::VecDeque;
|
||||
use std::collections::HashMap;
|
||||
use std::collections::HashSet;
|
||||
use std::hash::{BuildHasherDefault, Hasher};
|
||||
|
||||
struct MyLeafNode(i32); // helps to ensure we don't blindly replace substring "LeafNode"
|
||||
|
||||
#[derive(Default)]
|
||||
struct SimpleHasher { hash: u64 }
|
||||
|
||||
impl Hasher for SimpleHasher {
|
||||
fn finish(&self) -> u64 { self.hash }
|
||||
fn write(&mut self, bytes: &[u8]) {}
|
||||
fn write_u64(&mut self, i: u64) { self.hash = i }
|
||||
}
|
||||
|
||||
fn main() {
|
||||
// BTreeSet
|
||||
let mut btree_set = BTreeSet::new();
|
||||
@ -87,6 +125,18 @@ fn main() {
|
||||
vec_deque2.pop_front();
|
||||
vec_deque2.push_back(8);
|
||||
|
||||
// HashMap
|
||||
let mut hash_map = HashMap::<u64, u64, BuildHasherDefault<SimpleHasher>>::default();
|
||||
for i in 1..5 {
|
||||
hash_map.insert(i, i * 10);
|
||||
}
|
||||
|
||||
// HashSet
|
||||
let mut hash_set = HashSet::<u64, BuildHasherDefault<SimpleHasher>>::default();
|
||||
for i in 1..5 {
|
||||
hash_set.insert(i);
|
||||
}
|
||||
|
||||
zzz(); // #break
|
||||
}
|
||||
|
||||
|
@ -61,6 +61,9 @@
|
||||
// lldb-command: print none
|
||||
// lldb-check:[...]$5 = None
|
||||
|
||||
// lldb-command: print os_string
|
||||
// lldb-check:[...]$6 = "IAMA OS string 😃"[...]
|
||||
|
||||
|
||||
// === CDB TESTS ==================================================================================
|
||||
|
||||
|
@ -2,7 +2,7 @@
|
||||
// ignore-freebsd: gdb package too new
|
||||
// ignore-android: FIXME(#10381)
|
||||
// compile-flags:-g
|
||||
// min-gdb-version 7.7
|
||||
// min-gdb-version 8.1
|
||||
// min-lldb-version: 310
|
||||
|
||||
// === GDB TESTS ===================================================================================
|
||||
@ -10,7 +10,7 @@
|
||||
// gdb-command: run
|
||||
|
||||
// gdb-command: print vec
|
||||
// gdb-check:$1 = Vec<i32>(len: [...], cap: [...])[...]
|
||||
// gdb-check:$1 = Vec(size=[...])[...]
|
||||
|
||||
|
||||
#![allow(unused_variables)]
|
||||
|
37
src/test/debuginfo/rc_arc.rs
Normal file
37
src/test/debuginfo/rc_arc.rs
Normal file
@ -0,0 +1,37 @@
|
||||
// compile-flags:-g
|
||||
|
||||
// min-gdb-version: 8.1
|
||||
|
||||
// === GDB TESTS ==================================================================================
|
||||
|
||||
// gdb-command:run
|
||||
|
||||
// gdb-command:print r
|
||||
// gdb-check:[...]$1 = Rc(strong=2, weak=1) = {value = 42, strong = 2, weak = 1}
|
||||
// gdb-command:print a
|
||||
// gdb-check:[...]$2 = Arc(strong=2, weak=1) = {value = 42, strong = 2, weak = 1}
|
||||
|
||||
|
||||
// === LLDB TESTS ==================================================================================
|
||||
|
||||
// lldb-command:run
|
||||
|
||||
// lldb-command:print r
|
||||
// lldb-check:[...]$0 = strong=2, weak=1 { value = 42 }
|
||||
// lldb-command:print a
|
||||
// lldb-check:[...]$1 = strong=2, weak=1 { data = 42 }
|
||||
|
||||
use std::rc::Rc;
|
||||
use std::sync::Arc;
|
||||
|
||||
fn main() {
|
||||
let r = Rc::new(42);
|
||||
let r1 = Rc::clone(&r);
|
||||
let w1 = Rc::downgrade(&r);
|
||||
|
||||
let a = Arc::new(42);
|
||||
let a1 = Arc::clone(&a);
|
||||
let w2 = Arc::downgrade(&a);
|
||||
|
||||
print!(""); // #break
|
||||
}
|
@ -63,7 +63,7 @@
|
||||
|
||||
// STACK BY REF
|
||||
// lldb-command:print *self
|
||||
// lldbg-check:[...]$0 = Struct { x: 100 }
|
||||
// lldbg-check:[...]$0 = { x = 100 }
|
||||
// lldbr-check:(self_in_default_method::Struct) *self = Struct { x: 100 }
|
||||
// lldb-command:print arg1
|
||||
// lldbg-check:[...]$1 = -1
|
||||
@ -75,7 +75,7 @@
|
||||
|
||||
// STACK BY VAL
|
||||
// lldb-command:print self
|
||||
// lldbg-check:[...]$3 = Struct { x: 100 }
|
||||
// lldbg-check:[...]$3 = { x = 100 }
|
||||
// lldbr-check:(self_in_default_method::Struct) self = Struct { x: 100 }
|
||||
// lldb-command:print arg1
|
||||
// lldbg-check:[...]$4 = -3
|
||||
@ -87,7 +87,7 @@
|
||||
|
||||
// OWNED BY REF
|
||||
// lldb-command:print *self
|
||||
// lldbg-check:[...]$6 = Struct { x: 200 }
|
||||
// lldbg-check:[...]$6 = { x = 200 }
|
||||
// lldbr-check:(self_in_default_method::Struct) *self = Struct { x: 200 }
|
||||
// lldb-command:print arg1
|
||||
// lldbg-check:[...]$7 = -5
|
||||
@ -99,7 +99,7 @@
|
||||
|
||||
// OWNED BY VAL
|
||||
// lldb-command:print self
|
||||
// lldbg-check:[...]$9 = Struct { x: 200 }
|
||||
// lldbg-check:[...]$9 = { x = 200 }
|
||||
// lldbr-check:(self_in_default_method::Struct) self = Struct { x: 200 }
|
||||
// lldb-command:print arg1
|
||||
// lldbg-check:[...]$10 = -7
|
||||
@ -111,7 +111,7 @@
|
||||
|
||||
// OWNED MOVED
|
||||
// lldb-command:print *self
|
||||
// lldbg-check:[...]$12 = Struct { x: 200 }
|
||||
// lldbg-check:[...]$12 = { x = 200 }
|
||||
// lldbr-check:(self_in_default_method::Struct) *self = Struct { x: 200 }
|
||||
// lldb-command:print arg1
|
||||
// lldbg-check:[...]$13 = -9
|
||||
|
@ -63,7 +63,7 @@
|
||||
|
||||
// STACK BY REF
|
||||
// lldb-command:print *self
|
||||
// lldbg-check:[...]$0 = Struct { x: 987 }
|
||||
// lldbg-check:[...]$0 = { x = 987 }
|
||||
// lldbr-check:(self_in_generic_default_method::Struct) *self = Struct { x: 987 }
|
||||
// lldb-command:print arg1
|
||||
// lldbg-check:[...]$1 = -1
|
||||
@ -75,7 +75,7 @@
|
||||
|
||||
// STACK BY VAL
|
||||
// lldb-command:print self
|
||||
// lldbg-check:[...]$3 = Struct { x: 987 }
|
||||
// lldbg-check:[...]$3 = { x = 987 }
|
||||
// lldbr-check:(self_in_generic_default_method::Struct) self = Struct { x: 987 }
|
||||
// lldb-command:print arg1
|
||||
// lldbg-check:[...]$4 = -3
|
||||
@ -87,7 +87,7 @@
|
||||
|
||||
// OWNED BY REF
|
||||
// lldb-command:print *self
|
||||
// lldbg-check:[...]$6 = Struct { x: 879 }
|
||||
// lldbg-check:[...]$6 = { x = 879 }
|
||||
// lldbr-check:(self_in_generic_default_method::Struct) *self = Struct { x: 879 }
|
||||
// lldb-command:print arg1
|
||||
// lldbg-check:[...]$7 = -5
|
||||
@ -99,7 +99,7 @@
|
||||
|
||||
// OWNED BY VAL
|
||||
// lldb-command:print self
|
||||
// lldbg-check:[...]$9 = Struct { x: 879 }
|
||||
// lldbg-check:[...]$9 = { x = 879 }
|
||||
// lldbr-check:(self_in_generic_default_method::Struct) self = Struct { x: 879 }
|
||||
// lldb-command:print arg1
|
||||
// lldbg-check:[...]$10 = -7
|
||||
@ -111,7 +111,7 @@
|
||||
|
||||
// OWNED MOVED
|
||||
// lldb-command:print *self
|
||||
// lldbg-check:[...]$12 = Struct { x: 879 }
|
||||
// lldbg-check:[...]$12 = { x = 879 }
|
||||
// lldbr-check:(self_in_generic_default_method::Struct) *self = Struct { x: 879 }
|
||||
// lldb-command:print arg1
|
||||
// lldbg-check:[...]$13 = -9
|
||||
|
@ -100,28 +100,28 @@
|
||||
// lldb-command:run
|
||||
|
||||
// lldb-command:print no_padding16
|
||||
// lldbg-check:[...]$0 = NoPadding16 { x: 10000, y: -10001 }
|
||||
// lldbr-check:(simple_struct::NoPadding16) no_padding16 = NoPadding16 { x: 10000, y: -10001 }
|
||||
// lldbg-check:[...]$0 = { x = 10000 y = -10001 }
|
||||
// lldbr-check:(simple_struct::NoPadding16) no_padding16 = { x = 10000 y = -10001 }
|
||||
|
||||
// lldb-command:print no_padding32
|
||||
// lldbg-check:[...]$1 = NoPadding32 { x: -10002, y: -10003.5, z: 10004 }
|
||||
// lldbr-check:(simple_struct::NoPadding32) no_padding32 = NoPadding32 { x: -10002, y: -10003.5, z: 10004 }
|
||||
// lldbg-check:[...]$1 = { x = -10002 y = -10003.5 z = 10004 }
|
||||
// lldbr-check:(simple_struct::NoPadding32) no_padding32 = { x = -10002 y = -10003.5 z = 10004 }
|
||||
|
||||
// lldb-command:print no_padding64
|
||||
// lldbg-check:[...]$2 = NoPadding64 { x: -10005.5, y: 10006, z: 10007 }
|
||||
// lldbr-check:(simple_struct::NoPadding64) no_padding64 = NoPadding64 { x: -10005.5, y: 10006, z: 10007 }
|
||||
// lldbg-check:[...]$2 = { x = -10005.5 y = 10006 z = 10007 }
|
||||
// lldbr-check:(simple_struct::NoPadding64) no_padding64 = { x = -10005.5 y = 10006 z = 10007 }
|
||||
|
||||
// lldb-command:print no_padding163264
|
||||
// lldbg-check:[...]$3 = NoPadding163264 { a: -10008, b: 10009, c: 10010, d: 10011 }
|
||||
// lldbr-check:(simple_struct::NoPadding163264) no_padding163264 = NoPadding163264 { a: -10008, b: 10009, c: 10010, d: 10011 }
|
||||
// lldbg-check:[...]$3 = { a = -10008 b = 10009 c = 10010 d = 10011 }
|
||||
// lldbr-check:(simple_struct::NoPadding163264) no_padding163264 = { a = -10008 b = 10009 c = 10010 d = 10011 }
|
||||
|
||||
// lldb-command:print internal_padding
|
||||
// lldbg-check:[...]$4 = InternalPadding { x: 10012, y: -10013 }
|
||||
// lldbr-check:(simple_struct::InternalPadding) internal_padding = InternalPadding { x: 10012, y: -10013 }
|
||||
// lldbg-check:[...]$4 = { x = 10012 y = -10013 }
|
||||
// lldbr-check:(simple_struct::InternalPadding) internal_padding = { x = 10012 y = -10013 }
|
||||
|
||||
// lldb-command:print padding_at_end
|
||||
// lldbg-check:[...]$5 = PaddingAtEnd { x: -10014, y: 10015 }
|
||||
// lldbr-check:(simple_struct::PaddingAtEnd) padding_at_end = PaddingAtEnd { x: -10014, y: 10015 }
|
||||
// lldbg-check:[...]$5 = { x = -10014 y = 10015 }
|
||||
// lldbr-check:(simple_struct::PaddingAtEnd) padding_at_end = { x = -10014 y = 10015 }
|
||||
|
||||
#![allow(unused_variables)]
|
||||
#![allow(dead_code)]
|
||||
|
@ -100,28 +100,28 @@
|
||||
// lldb-command:run
|
||||
|
||||
// lldb-command:print/d noPadding8
|
||||
// lldbg-check:[...]$0 = (-100, 100)
|
||||
// lldbr-check:((i8, u8)) noPadding8 = { = -100 -100 = 100 100 }
|
||||
// lldbg-check:[...]$0 = { 0 = -100 1 = 100 }
|
||||
// lldbr-check:((i8, u8)) noPadding8 = { 0 = -100 1 = 100 }
|
||||
// lldb-command:print noPadding16
|
||||
// lldbg-check:[...]$1 = (0, 1, 2)
|
||||
// lldbr-check:((i16, i16, u16)) noPadding16 = { = 0 = 1 = 2 }
|
||||
// lldbg-check:[...]$1 = { 0 = 0 1 = 1 2 = 2 }
|
||||
// lldbr-check:((i16, i16, u16)) noPadding16 = { 0 = 0 1 = 1 2 = 2 }
|
||||
// lldb-command:print noPadding32
|
||||
// lldbg-check:[...]$2 = (3, 4.5, 5)
|
||||
// lldbr-check:((i32, f32, u32)) noPadding32 = { = 3 = 4.5 = 5 }
|
||||
// lldbg-check:[...]$2 = { 0 = 3 1 = 4.5 2 = 5 }
|
||||
// lldbr-check:((i32, f32, u32)) noPadding32 = { 0 = 3 1 = 4.5 2 = 5 }
|
||||
// lldb-command:print noPadding64
|
||||
// lldbg-check:[...]$3 = (6, 7.5, 8)
|
||||
// lldbr-check:((i64, f64, u64)) noPadding64 = { = 6 = 7.5 = 8 }
|
||||
// lldbg-check:[...]$3 = { 0 = 6 1 = 7.5 2 = 8 }
|
||||
// lldbr-check:((i64, f64, u64)) noPadding64 = { 0 = 6 1 = 7.5 2 = 8 }
|
||||
|
||||
// lldb-command:print internalPadding1
|
||||
// lldbg-check:[...]$4 = (9, 10)
|
||||
// lldbr-check:((i16, i32)) internalPadding1 = { = 9 = 10 }
|
||||
// lldbg-check:[...]$4 = { 0 = 9 1 = 10 }
|
||||
// lldbr-check:((i16, i32)) internalPadding1 = { 0 = 9 1 = 10 }
|
||||
// lldb-command:print internalPadding2
|
||||
// lldbg-check:[...]$5 = (11, 12, 13, 14)
|
||||
// lldbr-check:((i16, i32, u32, u64)) internalPadding2 = { = 11 = 12 = 13 = 14 }
|
||||
// lldbg-check:[...]$5 = { 0 = 11 1 = 12 2 = 13 3 = 14 }
|
||||
// lldbr-check:((i16, i32, u32, u64)) internalPadding2 = { 0 = 11 1 = 12 2 = 13 3 = 14 }
|
||||
|
||||
// lldb-command:print paddingAtEnd
|
||||
// lldbg-check:[...]$6 = (15, 16)
|
||||
// lldbr-check:((i32, i16)) paddingAtEnd = { = 15 = 16 }
|
||||
// lldbg-check:[...]$6 = { 0 = 15 1 = 16 }
|
||||
// lldbr-check:((i32, i16)) paddingAtEnd = { 0 = 15 1 = 16 }
|
||||
|
||||
#![allow(unused_variables)]
|
||||
#![allow(dead_code)]
|
||||
|
@ -25,36 +25,36 @@
|
||||
// lldb-command:run
|
||||
|
||||
// lldb-command:print three_simple_structs
|
||||
// lldbg-check:[...]$0 = ThreeSimpleStructs { x: Simple { x: 1 }, y: Simple { x: 2 }, z: Simple { x: 3 } }
|
||||
// lldbr-check:(struct_in_struct::ThreeSimpleStructs) three_simple_structs = ThreeSimpleStructs { x: Simple { x: 1 }, y: Simple { x: 2 }, z: Simple { x: 3 } }
|
||||
// lldbg-check:[...]$0 = { x = { x = 1 } y = { x = 2 } z = { x = 3 } }
|
||||
// lldbr-check:(struct_in_struct::ThreeSimpleStructs) three_simple_structs = { x = { x = 1 } y = { x = 2 } z = { x = 3 } }
|
||||
|
||||
// lldb-command:print internal_padding_parent
|
||||
// lldbg-check:[...]$1 = InternalPaddingParent { x: InternalPadding { x: 4, y: 5 }, y: InternalPadding { x: 6, y: 7 }, z: InternalPadding { x: 8, y: 9 } }
|
||||
// lldbr-check:(struct_in_struct::InternalPaddingParent) internal_padding_parent = InternalPaddingParent { x: InternalPadding { x: 4, y: 5 }, y: InternalPadding { x: 6, y: 7 }, z: InternalPadding { x: 8, y: 9 } }
|
||||
// lldbg-check:[...]$1 = { x = { x = 4 y = 5 } y = { x = 6 y = 7 } z = { x = 8 y = 9 } }
|
||||
// lldbr-check:(struct_in_struct::InternalPaddingParent) internal_padding_parent = { x = { x = 4 y = 5 } y = { x = 6 y = 7 } z = { x = 8 y = 9 } }
|
||||
|
||||
// lldb-command:print padding_at_end_parent
|
||||
// lldbg-check:[...]$2 = PaddingAtEndParent { x: PaddingAtEnd { x: 10, y: 11 }, y: PaddingAtEnd { x: 12, y: 13 }, z: PaddingAtEnd { x: 14, y: 15 } }
|
||||
// lldbr-check:(struct_in_struct::PaddingAtEndParent) padding_at_end_parent = PaddingAtEndParent { x: PaddingAtEnd { x: 10, y: 11 }, y: PaddingAtEnd { x: 12, y: 13 }, z: PaddingAtEnd { x: 14, y: 15 } }
|
||||
// lldbg-check:[...]$2 = { x = { x = 10 y = 11 } y = { x = 12 y = 13 } z = { x = 14 y = 15 } }
|
||||
// lldbr-check:(struct_in_struct::PaddingAtEndParent) padding_at_end_parent = { x = { x = 10 y = 11 } y = { x = 12 y = 13 } z = { x = 14 y = 15 } }
|
||||
|
||||
// lldb-command:print mixed
|
||||
// lldbg-check:[...]$3 = Mixed { x: PaddingAtEnd { x: 16, y: 17 }, y: InternalPadding { x: 18, y: 19 }, z: Simple { x: 20 }, w: 21 }
|
||||
// lldbr-check:(struct_in_struct::Mixed) mixed = Mixed { x: PaddingAtEnd { x: 16, y: 17 }, y: InternalPadding { x: 18, y: 19 }, z: Simple { x: 20 }, w: 21 }
|
||||
// lldbg-check:[...]$3 = { x = { x = 16 y = 17 } y = { x = 18 y = 19 } z = { x = 20 } w = 21 }
|
||||
// lldbr-check:(struct_in_struct::Mixed) mixed = { x = { x = 16 y = 17 } y = { x = 18 y = 19 } z = { x = 20 } w = 21 }
|
||||
|
||||
// lldb-command:print bag
|
||||
// lldbg-check:[...]$4 = Bag { x: Simple { x: 22 } }
|
||||
// lldbr-check:(struct_in_struct::Bag) bag = Bag { x: Simple { x: 22 } }
|
||||
// lldbg-check:[...]$4 = { x = { x = 22 } }
|
||||
// lldbr-check:(struct_in_struct::Bag) bag = { x = { x = 22 } }
|
||||
|
||||
// lldb-command:print bag_in_bag
|
||||
// lldbg-check:[...]$5 = BagInBag { x: Bag { x: Simple { x: 23 } } }
|
||||
// lldbr-check:(struct_in_struct::BagInBag) bag_in_bag = BagInBag { x: Bag { x: Simple { x: 23 } } }
|
||||
// lldbg-check:[...]$5 = { x = { x = { x = 23 } } }
|
||||
// lldbr-check:(struct_in_struct::BagInBag) bag_in_bag = { x = { x = { x = 23 } } }
|
||||
|
||||
// lldb-command:print tjo
|
||||
// lldbg-check:[...]$6 = ThatsJustOverkill { x: BagInBag { x: Bag { x: Simple { x: 24 } } } }
|
||||
// lldbr-check:(struct_in_struct::ThatsJustOverkill) tjo = ThatsJustOverkill { x: BagInBag { x: Bag { x: Simple { x: 24 } } } }
|
||||
// lldbg-check:[...]$6 = { x = { x = { x = { x = 24 } } } }
|
||||
// lldbr-check:(struct_in_struct::ThatsJustOverkill) tjo = { x = { x = { x = { x = 24 } } } }
|
||||
|
||||
// lldb-command:print tree
|
||||
// lldbg-check:[...]$7 = Tree { x: Simple { x: 25 }, y: InternalPaddingParent { x: InternalPadding { x: 26, y: 27 }, y: InternalPadding { x: 28, y: 29 }, z: InternalPadding { x: 30, y: 31 } }, z: BagInBag { x: Bag { x: Simple { x: 32 } } } }
|
||||
// lldbr-check:(struct_in_struct::Tree) tree = Tree { x: Simple { x: 25 }, y: InternalPaddingParent { x: InternalPadding { x: 26, y: 27 }, y: InternalPadding { x: 28, y: 29 }, z: InternalPadding { x: 30, y: 31 } }, z: BagInBag { x: Bag { x: Simple { x: 32 } } } }
|
||||
// lldbg-check:[...]$7 = { x = { x = 25 } y = { x = { x = 26 y = 27 } y = { x = 28 y = 29 } z = { x = 30 y = 31 } } z = { x = { x = { x = 32 } } } }
|
||||
// lldbr-check:(struct_in_struct::Tree) tree = { x = { x = 25 } y = { x = { x = 26 y = 27 } y = { x = 28 y = 29 } z = { x = 30 y = 31 } } z = { x = { x = { x = 32 } } } }
|
||||
|
||||
#![allow(unused_variables)]
|
||||
#![feature(omit_gdb_pretty_printer_section)]
|
||||
|
@ -28,20 +28,20 @@
|
||||
|
||||
// lldb-command:run
|
||||
// lldb-command:print simple
|
||||
// lldbg-check:[...]$0 = WithDestructor { x: 10, y: 20 }
|
||||
// lldbr-check:(struct_with_destructor::WithDestructor) simple = WithDestructor { x: 10, y: 20 }
|
||||
// lldbg-check:[...]$0 = { x = 10 y = 20 }
|
||||
// lldbr-check:(struct_with_destructor::WithDestructor) simple = { x = 10 y = 20 }
|
||||
|
||||
// lldb-command:print noDestructor
|
||||
// lldbg-check:[...]$1 = NoDestructorGuarded { a: NoDestructor { x: 10, y: 20 }, guard: -1 }
|
||||
// lldbr-check:(struct_with_destructor::NoDestructorGuarded) noDestructor = NoDestructorGuarded { a: NoDestructor { x: 10, y: 20 }, guard: -1 }
|
||||
// lldbg-check:[...]$1 = { a = { x = 10 y = 20 } guard = -1 }
|
||||
// lldbr-check:(struct_with_destructor::NoDestructorGuarded) noDestructor = { a = { x = 10 y = 20 } guard = -1 }
|
||||
|
||||
// lldb-command:print withDestructor
|
||||
// lldbg-check:[...]$2 = WithDestructorGuarded { a: WithDestructor { x: 10, y: 20 }, guard: -1 }
|
||||
// lldbr-check:(struct_with_destructor::WithDestructorGuarded) withDestructor = WithDestructorGuarded { a: WithDestructor { x: 10, y: 20 }, guard: -1 }
|
||||
// lldbg-check:[...]$2 = { a = { x = 10 y = 20 } guard = -1 }
|
||||
// lldbr-check:(struct_with_destructor::WithDestructorGuarded) withDestructor = { a = { x = 10 y = 20 } guard = -1 }
|
||||
|
||||
// lldb-command:print nested
|
||||
// lldbg-check:[...]$3 = NestedOuter { a: NestedInner { a: WithDestructor { x: 7890, y: 9870 } } }
|
||||
// lldbr-check:(struct_with_destructor::NestedOuter) nested = NestedOuter { a: NestedInner { a: WithDestructor { x: 7890, y: 9870 } } }
|
||||
// lldbg-check:[...]$3 = { a = { a = { x = 7890 y = 9870 } } }
|
||||
// lldbr-check:(struct_with_destructor::NestedOuter) nested = { a = { a = { x = 7890 y = 9870 } } }
|
||||
|
||||
#![allow(unused_variables)]
|
||||
#![feature(omit_gdb_pretty_printer_section)]
|
||||
|
@ -36,28 +36,28 @@
|
||||
// lldb-command:run
|
||||
|
||||
// lldb-command:print no_padding1
|
||||
// lldbg-check:[...]$0 = ((0, 1), 2, 3)
|
||||
// lldbr-check:(((u32, u32), u32, u32)) no_padding1 = { = { = 0 = 1 } = 2 = 3 }
|
||||
// lldbg-check:[...]$0 = { 0 = { 0 = 0 1 = 1 } 1 = 2 2 = 3 }
|
||||
// lldbr-check:(((u32, u32), u32, u32)) no_padding1 = { 0 = { 0 = 0 1 = 1 } 1 = 2 2 = 3 }
|
||||
// lldb-command:print no_padding2
|
||||
// lldbg-check:[...]$1 = (4, (5, 6), 7)
|
||||
// lldbr-check:((u32, (u32, u32), u32)) no_padding2 = { = 4 = { = 5 = 6 } = 7 }
|
||||
// lldbg-check:[...]$1 = { 0 = 4 1 = { 0 = 5 1 = 6 } 2 = 7 }
|
||||
// lldbr-check:((u32, (u32, u32), u32)) no_padding2 = { 0 = 4 1 = { 0 = 5 1 = 6 } 2 = 7 }
|
||||
// lldb-command:print no_padding3
|
||||
// lldbg-check:[...]$2 = (8, 9, (10, 11))
|
||||
// lldbr-check:((u32, u32, (u32, u32))) no_padding3 = { = 8 = 9 = { = 10 = 11 } }
|
||||
// lldbg-check:[...]$2 = { 0 = 8 1 = 9 2 = { 0 = 10 1 = 11 } }
|
||||
// lldbr-check:((u32, u32, (u32, u32))) no_padding3 = { 0 = 8 1 = 9 2 = { 0 = 10 1 = 11 } }
|
||||
|
||||
// lldb-command:print internal_padding1
|
||||
// lldbg-check:[...]$3 = (12, (13, 14))
|
||||
// lldbr-check:((i16, (i32, i32))) internal_padding1 = { = 12 = { = 13 = 14 } }
|
||||
// lldbg-check:[...]$3 = { 0 = 12 1 = { 0 = 13 1 = 14 } }
|
||||
// lldbr-check:((i16, (i32, i32))) internal_padding1 = { 0 = 12 1 = { 0 = 13 1 = 14 } }
|
||||
// lldb-command:print internal_padding2
|
||||
// lldbg-check:[...]$4 = (15, (16, 17))
|
||||
// lldbr-check:((i16, (i16, i32))) internal_padding2 = { = 15 = { = 16 = 17 } }
|
||||
// lldbg-check:[...]$4 = { 0 = 15 1 = { 0 = 16 1 = 17 } }
|
||||
// lldbr-check:((i16, (i16, i32))) internal_padding2 = { 0 = 15 1 = { 0 = 16 1 = 17 } }
|
||||
|
||||
// lldb-command:print padding_at_end1
|
||||
// lldbg-check:[...]$5 = (18, (19, 20))
|
||||
// lldbr-check:((i32, (i32, i16))) padding_at_end1 = { = 18 = { = 19 = 20 } }
|
||||
// lldbg-check:[...]$5 = { 0 = 18 1 = { 0 = 19 1 = 20 } }
|
||||
// lldbr-check:((i32, (i32, i16))) padding_at_end1 = { 0 = 18 1 = { 0 = 19 1 = 20 } }
|
||||
// lldb-command:print padding_at_end2
|
||||
// lldbg-check:[...]$6 = ((21, 22), 23)
|
||||
// lldbr-check:(((i32, i16), i32)) padding_at_end2 = { = { = 21 = 22 } = 23 }
|
||||
// lldbg-check:[...]$6 = { 0 = { 0 = 21 1 = 22 } 1 = 23 }
|
||||
// lldbr-check:(((i32, i16), i32)) padding_at_end2 = { 0 = { 0 = 21 1 = 22 } 1 = 23 }
|
||||
|
||||
#![allow(unused_variables)]
|
||||
#![feature(omit_gdb_pretty_printer_section)]
|
||||
|
@ -38,28 +38,28 @@
|
||||
// lldb-command:run
|
||||
|
||||
// lldb-command:print no_padding16
|
||||
// lldbg-check:[...]$0 = NoPadding16(10000, -10001)
|
||||
// lldbr-check:(tuple_struct::NoPadding16) no_padding16 = { = 10000 = -10001 }
|
||||
// lldbg-check:[...]$0 = { 0 = 10000 1 = -10001 }
|
||||
// lldbr-check:(tuple_struct::NoPadding16) no_padding16 = { 0 = 10000 1 = -10001 }
|
||||
|
||||
// lldb-command:print no_padding32
|
||||
// lldbg-check:[...]$1 = NoPadding32(-10002, -10003.5, 10004)
|
||||
// lldbr-check:(tuple_struct::NoPadding32) no_padding32 = { = -10002 = -10003.5 = 10004 }
|
||||
// lldbg-check:[...]$1 = { 0 = -10002 1 = -10003.5 2 = 10004 }
|
||||
// lldbr-check:(tuple_struct::NoPadding32) no_padding32 = { 0 = -10002 1 = -10003.5 2 = 10004 }
|
||||
|
||||
// lldb-command:print no_padding64
|
||||
// lldbg-check:[...]$2 = NoPadding64(-10005.5, 10006, 10007)
|
||||
// lldbr-check:(tuple_struct::NoPadding64) no_padding64 = { = -10005.5 = 10006 = 10007 }
|
||||
// lldbg-check:[...]$2 = { 0 = -10005.5 1 = 10006 2 = 10007 }
|
||||
// lldbr-check:(tuple_struct::NoPadding64) no_padding64 = { 0 = -10005.5 1 = 10006 2 = 10007 }
|
||||
|
||||
// lldb-command:print no_padding163264
|
||||
// lldbg-check:[...]$3 = NoPadding163264(-10008, 10009, 10010, 10011)
|
||||
// lldbr-check:(tuple_struct::NoPadding163264) no_padding163264 = { = -10008 = 10009 = 10010 = 10011 }
|
||||
// lldbg-check:[...]$3 = { 0 = -10008 1 = 10009 2 = 10010 3 = 10011 }
|
||||
// lldbr-check:(tuple_struct::NoPadding163264) no_padding163264 = { 0 = -10008 1 = 10009 2 = 10010 3 = 10011 }
|
||||
|
||||
// lldb-command:print internal_padding
|
||||
// lldbg-check:[...]$4 = InternalPadding(10012, -10013)
|
||||
// lldbr-check:(tuple_struct::InternalPadding) internal_padding = { = 10012 = -10013 }
|
||||
// lldbg-check:[...]$4 = { 0 = 10012 1 = -10013 }
|
||||
// lldbr-check:(tuple_struct::InternalPadding) internal_padding = { 0 = 10012 1 = -10013 }
|
||||
|
||||
// lldb-command:print padding_at_end
|
||||
// lldbg-check:[...]$5 = PaddingAtEnd(-10014, 10015)
|
||||
// lldbr-check:(tuple_struct::PaddingAtEnd) padding_at_end = { = -10014 = 10015 }
|
||||
// lldbg-check:[...]$5 = { 0 = -10014 1 = 10015 }
|
||||
// lldbr-check:(tuple_struct::PaddingAtEnd) padding_at_end = { 0 = -10014 1 = 10015 }
|
||||
|
||||
// This test case mainly makes sure that no field names are generated for tuple structs (as opposed
|
||||
// to all fields having the name "<unnamed_field>"). Otherwise they are handled the same a normal
|
||||
|
@ -19,13 +19,13 @@
|
||||
|
||||
// lldb-command:run
|
||||
// lldb-command:print u
|
||||
// lldbg-check:[...]$0 = U { a: ('\x02', '\x02'), b: 514 }
|
||||
// lldbr-check:(union_smoke::U) u = { a = { = 2 = 2 } b = 514 }
|
||||
// lldbg-check:[...]$0 = { a = { 0 = '\x02' 1 = '\x02' } b = 514 }
|
||||
// lldbr-check:(union_smoke::U) u = { a = { 0 = '\x02' 1 = '\x02' } b = 514 }
|
||||
|
||||
// Don't test this with rust-enabled lldb for now; see
|
||||
// https://github.com/rust-lang-nursery/lldb/issues/18
|
||||
// lldbg-command:print union_smoke::SU
|
||||
// lldbg-check:[...]$1 = U { a: ('\x01', '\x01'), b: 257 }
|
||||
// lldbg-check:[...]$1 = { a = { 0 = '\x01' 1 = '\x01' } b = 257 }
|
||||
|
||||
#![allow(unused)]
|
||||
#![feature(omit_gdb_pretty_printer_section)]
|
||||
|
@ -50,11 +50,11 @@
|
||||
// lldbg-check:[...]$1 = 2
|
||||
// lldbr-check:(isize) constant = 2
|
||||
// lldb-command:print a_struct
|
||||
// lldbg-check:[...]$2 = Struct { a: -3, b: 4.5, c: 5 }
|
||||
// lldbr-check:(var_captured_in_nested_closure::Struct) a_struct = Struct { a: -3, b: 4.5, c: 5 }
|
||||
// lldbg-check:[...]$2 = { a = -3 b = 4.5 c = 5 }
|
||||
// lldbr-check:(var_captured_in_nested_closure::Struct) a_struct = { a = -3 b = 4.5 c = 5 }
|
||||
// lldb-command:print *struct_ref
|
||||
// lldbg-check:[...]$3 = Struct { a: -3, b: 4.5, c: 5 }
|
||||
// lldbr-check:(var_captured_in_nested_closure::Struct) *struct_ref = Struct { a: -3, b: 4.5, c: 5 }
|
||||
// lldbg-check:[...]$3 = { a = -3 b = 4.5 c = 5 }
|
||||
// lldbr-check:(var_captured_in_nested_closure::Struct) *struct_ref = { a = -3 b = 4.5 c = 5 }
|
||||
// lldb-command:print *owned
|
||||
// lldbg-check:[...]$4 = 6
|
||||
// lldbr-check:(isize) *owned = 6
|
||||
@ -70,11 +70,11 @@
|
||||
// lldbg-check:[...]$7 = 2
|
||||
// lldbr-check:(isize) constant = 2
|
||||
// lldb-command:print a_struct
|
||||
// lldbg-check:[...]$8 = Struct { a: -3, b: 4.5, c: 5 }
|
||||
// lldbr-check:(var_captured_in_nested_closure::Struct) a_struct = Struct { a: -3, b: 4.5, c: 5 }
|
||||
// lldbg-check:[...]$8 = { a = -3 b = 4.5 c = 5 }
|
||||
// lldbr-check:(var_captured_in_nested_closure::Struct) a_struct = { a = -3 b = 4.5 c = 5 }
|
||||
// lldb-command:print *struct_ref
|
||||
// lldbg-check:[...]$9 = Struct { a: -3, b: 4.5, c: 5 }
|
||||
// lldbr-check:(var_captured_in_nested_closure::Struct) *struct_ref = Struct { a: -3, b: 4.5, c: 5 }
|
||||
// lldbg-check:[...]$9 = { a = -3 b = 4.5 c = 5 }
|
||||
// lldbr-check:(var_captured_in_nested_closure::Struct) *struct_ref = { a = -3 b = 4.5 c = 5 }
|
||||
// lldb-command:print *owned
|
||||
// lldbg-check:[...]$10 = 6
|
||||
// lldbr-check:(isize) *owned = 6
|
||||
|
@ -27,8 +27,8 @@
|
||||
// lldbg-check:[...]$0 = 1
|
||||
// lldbr-check:(isize) constant = 1
|
||||
// lldb-command:print a_struct
|
||||
// lldbg-check:[...]$1 = Struct { a: -2, b: 3.5, c: 4 }
|
||||
// lldbr-check:(var_captured_in_sendable_closure::Struct) a_struct = Struct { a: -2, b: 3.5, c: 4 }
|
||||
// lldbg-check:[...]$1 = { a = -2 b = 3.5 c = 4 }
|
||||
// lldbr-check:(var_captured_in_sendable_closure::Struct) a_struct = { a = -2 b = 3.5 c = 4 }
|
||||
// lldb-command:print *owned
|
||||
// lldbg-check:[...]$2 = 5
|
||||
// lldbr-check:(isize) *owned = 5
|
||||
|
@ -46,11 +46,11 @@
|
||||
// lldbg-check:[...]$1 = 2
|
||||
// lldbr-check:(isize) constant = 2
|
||||
// lldb-command:print a_struct
|
||||
// lldbg-check:[...]$2 = Struct { a: -3, b: 4.5, c: 5 }
|
||||
// lldbr-check:(var_captured_in_stack_closure::Struct) a_struct = Struct { a: -3, b: 4.5, c: 5 }
|
||||
// lldbg-check:[...]$2 = { a = -3 b = 4.5 c = 5 }
|
||||
// lldbr-check:(var_captured_in_stack_closure::Struct) a_struct = { a = -3 b = 4.5 c = 5 }
|
||||
// lldb-command:print *struct_ref
|
||||
// lldbg-check:[...]$3 = Struct { a: -3, b: 4.5, c: 5 }
|
||||
// lldbr-check:(var_captured_in_stack_closure::Struct) *struct_ref = Struct { a: -3, b: 4.5, c: 5 }
|
||||
// lldbg-check:[...]$3 = { a = -3 b = 4.5 c = 5 }
|
||||
// lldbr-check:(var_captured_in_stack_closure::Struct) *struct_ref = { a = -3 b = 4.5 c = 5 }
|
||||
// lldb-command:print *owned
|
||||
// lldbg-check:[...]$4 = 6
|
||||
// lldbr-check:(isize) *owned = 6
|
||||
@ -64,11 +64,11 @@
|
||||
// lldbg-check:[...]$6 = 2
|
||||
// lldbr-check:(isize) constant = 2
|
||||
// lldb-command:print a_struct
|
||||
// lldbg-check:[...]$7 = Struct { a: -3, b: 4.5, c: 5 }
|
||||
// lldbr-check:(var_captured_in_stack_closure::Struct) a_struct = Struct { a: -3, b: 4.5, c: 5 }
|
||||
// lldbg-check:[...]$7 = { a = -3 b = 4.5 c = 5 }
|
||||
// lldbr-check:(var_captured_in_stack_closure::Struct) a_struct = { a = -3 b = 4.5 c = 5 }
|
||||
// lldb-command:print *struct_ref
|
||||
// lldbg-check:[...]$8 = Struct { a: -3, b: 4.5, c: 5 }
|
||||
// lldbr-check:(var_captured_in_stack_closure::Struct) *struct_ref = Struct { a: -3, b: 4.5, c: 5 }
|
||||
// lldbg-check:[...]$8 = { a = -3 b = 4.5 c = 5 }
|
||||
// lldbr-check:(var_captured_in_stack_closure::Struct) *struct_ref = { a = -3 b = 4.5 c = 5 }
|
||||
// lldb-command:print *owned
|
||||
// lldbg-check:[...]$9 = 6
|
||||
// lldbr-check:(isize) *owned = 6
|
||||
|
@ -72,28 +72,28 @@
|
||||
// lldb-command:run
|
||||
|
||||
// lldb-command:print empty
|
||||
// lldbg-check:[...]$0 = &[]
|
||||
// lldbr-check:(&[i64]) empty = &[]
|
||||
// lldbg-check:[...]$0 = size=0
|
||||
// lldbr-check:(&[i64]) empty = size=0
|
||||
|
||||
// lldb-command:print singleton
|
||||
// lldbg-check:[...]$1 = &[1]
|
||||
// lldbg-check:[...]$1 = size=1 { [0] = 1 }
|
||||
// lldbr-check:(&[i64]) singleton = &[1]
|
||||
|
||||
// lldb-command:print multiple
|
||||
// lldbg-check:[...]$2 = &[2, 3, 4, 5]
|
||||
// lldbr-check:(&[i64]) multiple = &[2, 3, 4, 5]
|
||||
// lldbg-check:[...]$2 = size=4 { [0] = 2 [1] = 3 [2] = 4 [3] = 5 }
|
||||
// lldbr-check:(&[i64]) multiple = size=4 { [0] = 2 [1] = 3 [2] = 4 [3] = 5 }
|
||||
|
||||
// lldb-command:print slice_of_slice
|
||||
// lldbg-check:[...]$3 = &[3, 4]
|
||||
// lldbr-check:(&[i64]) slice_of_slice = &[3, 4]
|
||||
// lldbg-check:[...]$3 = size=2 { [0] = 3 [1] = 4 }
|
||||
// lldbr-check:(&[i64]) slice_of_slice = size=2 { [0] = 3 [1] = 4 }
|
||||
|
||||
// lldb-command:print padded_tuple
|
||||
// lldbg-check:[...]$4 = &[(6, 7), (8, 9)]
|
||||
// lldbr-check:(&[(i32, i16)]) padded_tuple = { data_ptr = *[...] length = 2 }
|
||||
// lldbg-check:[...]$4 = size=2 { [0] = { 0 = 6 1 = 7 } [1] = { 0 = 8 1 = 9 } }
|
||||
// lldbr-check:(&[(i32, i16)]) padded_tuple = size=2 { [0] = { 0 = 6 1 = 7 } [1] = { 0 = 8 1 = 9 } }
|
||||
|
||||
// lldb-command:print padded_struct
|
||||
// lldbg-check:[...]$5 = &[AStruct { x: 10, y: 11, z: 12 }, AStruct { x: 13, y: 14, z: 15 }]
|
||||
// lldbr-check:(&[vec_slices::AStruct]) padded_struct = &[AStruct { x: 10, y: 11, z: 12 }, AStruct { x: 13, y: 14, z: 15 }]
|
||||
// lldbg-check:[...]$5 = size=2 { [0] = { x = 10 y = 11 z = 12 } [1] = { x = 13 y = 14 z = 15 } }
|
||||
// lldbr-check:(&[vec_slices::AStruct]) padded_struct = size=2 { [0] = { x = 10 y = 11 z = 12 } [1] = { x = 13 y = 14 z = 15 } }
|
||||
|
||||
#![allow(dead_code, unused_variables)]
|
||||
#![feature(omit_gdb_pretty_printer_section)]
|
||||
|
@ -18,8 +18,8 @@
|
||||
|
||||
// lldb-command:run
|
||||
// lldb-command:print a
|
||||
// lldbg-check:[...]$0 = [1, 2, 3]
|
||||
// lldbr-check:([i32; 3]) a = [1, 2, 3]
|
||||
// lldbg-check:[...]$0 = { [0] = 1 [1] = 2 [2] = 3 }
|
||||
// lldbr-check:([i32; 3]) a = { [0] = 1 [1] = 2 [2] = 3 }
|
||||
|
||||
#![allow(unused_variables)]
|
||||
#![feature(omit_gdb_pretty_printer_section)]
|
||||
|
@ -464,11 +464,13 @@ fn common_inputs_stamp(config: &Config) -> Stamp {
|
||||
|
||||
// Relevant pretty printer files
|
||||
let pretty_printer_files = [
|
||||
"src/etc/debugger_pretty_printers_common.py",
|
||||
"src/etc/rust_types.py",
|
||||
"src/etc/gdb_load_rust_pretty_printers.py",
|
||||
"src/etc/gdb_rust_pretty_printing.py",
|
||||
"src/etc/gdb_lookup.py",
|
||||
"src/etc/gdb_providers.py",
|
||||
"src/etc/lldb_batchmode.py",
|
||||
"src/etc/lldb_rust_formatters.py",
|
||||
"src/etc/lldb_lookup.py",
|
||||
"src/etc/lldb_providers.py",
|
||||
];
|
||||
for file in &pretty_printer_files {
|
||||
let path = rust_src_dir.join(file);
|
||||
|
@ -1079,15 +1079,38 @@ impl<'test> TestCx<'test> {
|
||||
// Switch LLDB into "Rust mode"
|
||||
let rust_src_root =
|
||||
self.config.find_rust_src_root().expect("Could not find Rust source root");
|
||||
let rust_pp_module_rel_path = Path::new("./src/etc/lldb_rust_formatters.py");
|
||||
let rust_pp_module_rel_path = Path::new("./src/etc/lldb_lookup.py");
|
||||
let rust_pp_module_abs_path =
|
||||
rust_src_root.join(rust_pp_module_rel_path).to_str().unwrap().to_owned();
|
||||
|
||||
let rust_type_regexes = vec![
|
||||
"^(alloc::([a-z_]+::)+)String$",
|
||||
"^&str$",
|
||||
"^&\\[.+\\]$",
|
||||
"^(std::ffi::([a-z_]+::)+)OsString$",
|
||||
"^(alloc::([a-z_]+::)+)Vec<.+>$",
|
||||
"^(alloc::([a-z_]+::)+)VecDeque<.+>$",
|
||||
"^(alloc::([a-z_]+::)+)BTreeSet<.+>$",
|
||||
"^(alloc::([a-z_]+::)+)BTreeMap<.+>$",
|
||||
"^(std::collections::([a-z_]+::)+)HashMap<.+>$",
|
||||
"^(std::collections::([a-z_]+::)+)HashSet<.+>$",
|
||||
"^(alloc::([a-z_]+::)+)Rc<.+>$",
|
||||
"^(alloc::([a-z_]+::)+)Arc<.+>$",
|
||||
"^(core::([a-z_]+::)+)Cell<.+>$",
|
||||
"^(core::([a-z_]+::)+)Ref<.+>$",
|
||||
"^(core::([a-z_]+::)+)RefMut<.+>$",
|
||||
"^(core::([a-z_]+::)+)RefCell<.+>$",
|
||||
];
|
||||
|
||||
script_str
|
||||
.push_str(&format!("command script import {}\n", &rust_pp_module_abs_path[..])[..]);
|
||||
script_str.push_str("type summary add --no-value ");
|
||||
script_str.push_str("--python-function lldb_rust_formatters.print_val ");
|
||||
script_str.push_str("-x \".*\" --category Rust\n");
|
||||
script_str.push_str("type synthetic add -l lldb_lookup.synthetic_lookup -x '.*' ");
|
||||
script_str.push_str("--category Rust\n");
|
||||
for type_regex in rust_type_regexes {
|
||||
script_str.push_str("type summary add -F lldb_lookup.summary_lookup -e -x -h ");
|
||||
script_str.push_str(&format!("'{}' ", type_regex));
|
||||
script_str.push_str("--category Rust\n");
|
||||
}
|
||||
script_str.push_str("type category enable Rust\n");
|
||||
|
||||
// Set breakpoints on every line that contains the string "#break"
|
||||
|
Loading…
Reference in New Issue
Block a user