debuginfo: Add GDB pretty printers for slices, Vec<>, and String.

This commit is contained in:
Michael Woerister 2015-03-12 17:05:44 +01:00
parent b2f09c1165
commit 90fc28d0f2
2 changed files with 148 additions and 1 deletions

View File

@ -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)

View 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() { () }