debuginfo: Add GDB pretty printers for slices, Vec<>, and String.
This commit is contained in:
parent
b2f09c1165
commit
90fc28d0f2
@ -27,9 +27,18 @@ def rust_pretty_printer_lookup_function(val):
|
||||
if type_code == gdb.TYPE_CODE_STRUCT:
|
||||
struct_kind = classify_struct(val.type)
|
||||
|
||||
if struct_kind == STRUCT_KIND_SLICE:
|
||||
return RustSlicePrinter(val)
|
||||
|
||||
if struct_kind == STRUCT_KIND_STR_SLICE:
|
||||
return RustStringSlicePrinter(val)
|
||||
|
||||
if struct_kind == STRUCT_KIND_STD_VEC:
|
||||
return RustStdVecPrinter(val)
|
||||
|
||||
if struct_kind == STRUCT_KIND_STD_STRING:
|
||||
return RustStdStringPrinter(val)
|
||||
|
||||
if struct_kind == STRUCT_KIND_TUPLE:
|
||||
return RustTuplePrinter(val)
|
||||
|
||||
@ -172,6 +181,28 @@ class RustTupleStructPrinter:
|
||||
def display_hint(self):
|
||||
return "array"
|
||||
|
||||
class RustSlicePrinter:
|
||||
def __init__(self, val):
|
||||
self.val = val
|
||||
|
||||
def display_hint(self):
|
||||
return "array"
|
||||
|
||||
def to_string(self):
|
||||
length = int(self.val["length"])
|
||||
return self.val.type.tag + ("(len: %i)" % length)
|
||||
|
||||
def children(self):
|
||||
cs = []
|
||||
length = int(self.val["length"])
|
||||
data_ptr = self.val["data_ptr"]
|
||||
assert data_ptr.type.code == gdb.TYPE_CODE_PTR
|
||||
pointee_type = data_ptr.type.target()
|
||||
|
||||
for index in range(0, length):
|
||||
cs.append((str(index), (data_ptr + index).dereference()))
|
||||
|
||||
return cs
|
||||
|
||||
class RustStringSlicePrinter:
|
||||
def __init__(self, val):
|
||||
@ -181,6 +212,35 @@ class RustStringSlicePrinter:
|
||||
slice_byte_len = self.val["length"]
|
||||
return '"%s"' % self.val["data_ptr"].string(encoding="utf-8", length=slice_byte_len)
|
||||
|
||||
class RustStdVecPrinter:
|
||||
def __init__(self, val):
|
||||
self.val = val
|
||||
|
||||
def display_hint(self):
|
||||
return "array"
|
||||
|
||||
def to_string(self):
|
||||
length = int(self.val["len"])
|
||||
cap = int(self.val["cap"])
|
||||
return self.val.type.tag + ("(len: %i, cap: %i)" % (length, cap))
|
||||
|
||||
def children(self):
|
||||
cs = []
|
||||
(length, data_ptr) = extract_length_and_data_ptr_from_std_vec(self.val)
|
||||
pointee_type = data_ptr.type.target()
|
||||
|
||||
for index in range(0, length):
|
||||
cs.append((str(index), (data_ptr + index).dereference()))
|
||||
return cs
|
||||
|
||||
class RustStdStringPrinter:
|
||||
def __init__(self, val):
|
||||
self.val = val
|
||||
|
||||
def to_string(self):
|
||||
(length, data_ptr) = extract_length_and_data_ptr_from_std_vec(self.val["vec"])
|
||||
return '"%s"' % data_ptr.string(encoding="utf-8", length=length)
|
||||
|
||||
|
||||
class RustCStyleEnumPrinter:
|
||||
def __init__(self, val):
|
||||
@ -204,19 +264,38 @@ STRUCT_KIND_TUPLE = 2
|
||||
STRUCT_KIND_TUPLE_VARIANT = 3
|
||||
STRUCT_KIND_STRUCT_VARIANT = 4
|
||||
STRUCT_KIND_CSTYLE_VARIANT = 5
|
||||
STRUCT_KIND_STR_SLICE = 6
|
||||
STRUCT_KIND_SLICE = 6
|
||||
STRUCT_KIND_STR_SLICE = 7
|
||||
STRUCT_KIND_STD_VEC = 8
|
||||
STRUCT_KIND_STD_STRING = 9
|
||||
|
||||
|
||||
def classify_struct(type):
|
||||
# print("\nclassify_struct: tag=%s\n" % type.tag)
|
||||
if type.tag == "&str":
|
||||
return STRUCT_KIND_STR_SLICE
|
||||
|
||||
if type.tag.startswith("&[") and type.tag.endswith("]"):
|
||||
return STRUCT_KIND_SLICE
|
||||
|
||||
fields = list(type.fields())
|
||||
field_count = len(fields)
|
||||
|
||||
if field_count == 0:
|
||||
return STRUCT_KIND_REGULAR_STRUCT
|
||||
|
||||
if (field_count == 3 and
|
||||
fields[0].name == "ptr" and
|
||||
fields[1].name == "len" and
|
||||
fields[2].name == "cap" and
|
||||
type.tag.startswith("Vec<")):
|
||||
return STRUCT_KIND_STD_VEC
|
||||
|
||||
if (field_count == 1 and
|
||||
fields[0].name == "vec" and
|
||||
type.tag == "String"):
|
||||
return STRUCT_KIND_STD_STRING
|
||||
|
||||
if fields[0].name == "RUST$ENUM$DISR":
|
||||
if field_count == 1:
|
||||
return STRUCT_KIND_CSTYLE_VARIANT
|
||||
@ -254,3 +333,11 @@ def get_field_at_index(val, index):
|
||||
return field
|
||||
i += 1
|
||||
return None
|
||||
|
||||
def extract_length_and_data_ptr_from_std_vec(vec_val):
|
||||
length = int(vec_val["len"])
|
||||
vec_ptr_val = vec_val["ptr"]
|
||||
unique_ptr_val = vec_ptr_val[first_field(vec_ptr_val)]
|
||||
data_ptr = unique_ptr_val[first_field(unique_ptr_val)]
|
||||
assert data_ptr.type.code == gdb.TYPE_CODE_PTR
|
||||
return (length, data_ptr)
|
60
src/test/debuginfo/gdb-pretty-std.rs
Normal file
60
src/test/debuginfo/gdb-pretty-std.rs
Normal file
@ -0,0 +1,60 @@
|
||||
// Copyright 2013-2015 The Rust Project Developers. See the COPYRIGHT
|
||||
// file at the top-level directory of this distribution and at
|
||||
// http://rust-lang.org/COPYRIGHT.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
|
||||
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
|
||||
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
|
||||
// option. This file may not be copied, modified, or distributed
|
||||
// except according to those terms.
|
||||
|
||||
// ignore-windows failing on win32 bot
|
||||
// ignore-freebsd: gdb package too new
|
||||
// ignore-tidy-linelength
|
||||
// ignore-lldb
|
||||
// ignore-android: FIXME(#10381)
|
||||
// compile-flags:-g
|
||||
// min-gdb-version 7.7
|
||||
|
||||
// gdb-command: run
|
||||
|
||||
// gdb-command: print slice
|
||||
// gdb-check:$1 = &[i32](len: 4) = {0, 1, 2, 3}
|
||||
|
||||
// gdb-command: print vec
|
||||
// gdb-check:$2 = Vec<u64>(len: 4, cap: [...]) = {4, 5, 6, 7}
|
||||
|
||||
// gdb-command: print str_slice
|
||||
// gdb-check:$3 = "IAMA string slice!"
|
||||
|
||||
// gdb-command: print string
|
||||
// gdb-check:$4 = "IAMA string!"
|
||||
|
||||
// gdb-command: print some
|
||||
// gdb-check:$5 = Some = {8}
|
||||
|
||||
// gdb-command: print none
|
||||
// gdb-check:$6 = None
|
||||
|
||||
fn main() {
|
||||
|
||||
// &[]
|
||||
let slice: &[i32] = &[0, 1, 2, 3];
|
||||
|
||||
// Vec
|
||||
let vec = vec![4u64, 5, 6, 7];
|
||||
|
||||
// &str
|
||||
let str_slice = "IAMA string slice!";
|
||||
|
||||
// String
|
||||
let string = "IAMA string!".to_string();
|
||||
|
||||
// Option
|
||||
let some = Some(8i16);
|
||||
let none: Option<i64> = None;
|
||||
|
||||
zzz(); // #break
|
||||
}
|
||||
|
||||
fn zzz() { () }
|
Loading…
Reference in New Issue
Block a user