1
1
import gdb
2
2
3
3
4
+ def deconstruct_dstring (val ):
5
+ # ideally, we want to access the memory where the string
6
+ # is stored directly instead of calling a function. However,
7
+ # this is simpler.
8
+ try :
9
+ raw_address = str (val .address )
10
+
11
+ # If it's ::empty, we know it's empty without going further.
12
+ if "::empty" in raw_address :
13
+ return - 1 , ""
14
+
15
+ # Split the address on the first space, return that value
16
+ # Addresses are usually {address} {optional type_name}
17
+ typed_pointer = "((const {} *){})" .format (val .type , raw_address .split (None , 1 )[0 ])
18
+
19
+ string_no = val ["no" ]
20
+
21
+ # Check that the pointer is not null.
22
+ null_ptr = gdb .parse_and_eval ("{} == 0" .format (typed_pointer ))
23
+ if null_ptr .is_optimized_out :
24
+ return - 1 , "{}: <Ptr optimized out>" .format (string_no )
25
+ if null_ptr :
26
+ return - 1 , ""
27
+
28
+ table_len = gdb .parse_and_eval ("get_string_container().string_vector.size()" )
29
+ if table_len .is_optimized_out :
30
+ return - 1 , "{}: <Table len optimized out>" .format (string_no )
31
+ if string_no >= table_len :
32
+ return - 1 , "{} index ({}) out of range" .format (val .type , string_no )
33
+
34
+ value = gdb .parse_and_eval ("{}->c_str()" .format (typed_pointer ))
35
+ if value .is_optimized_out :
36
+ return - 1 , "{}: <Optimized out>" .format (string_no )
37
+ return string_no , value .string ().replace ("\0 " , "" )
38
+ except :
39
+ return - 1 , ""
40
+
4
41
# Class for pretty-printing dstringt
5
42
class DStringPrettyPrinter :
6
43
"Print a dstringt"
@@ -9,44 +46,87 @@ def __init__(self, val):
9
46
self .val = val
10
47
11
48
def to_string (self ):
12
- # ideally, we want to access the memory where the string
13
- # is stored directly instead of calling a function. However,
14
- # this is simpler.
49
+ string_no , value = deconstruct_dstring (self .val )
50
+ if string_no == - 1 :
51
+ return value
52
+ return "{}: \" {}\" " .format (string_no , value .replace ("\" " , "\\ \" " ))
53
+
54
+ def display_hint (self ):
55
+ return None
56
+
57
+
58
+ def find_type (type , name ):
59
+ type = type .strip_typedefs ()
60
+ while True :
61
+ # Strip cv-qualifiers.
62
+ search = "%s::%s" % (type .unqualified (), name )
15
63
try :
16
- raw_address = str (self .val .address )
64
+ return gdb .lookup_type (search )
65
+ except RuntimeError :
66
+ pass
67
+ # The type was not found, so try the superclass.
68
+ # We only need to check the first superclass.
69
+ type = type .fields ()[0 ].type
70
+
17
71
18
- # If it's ::empty, we know it's empty without going further.
19
- if "::empty" in raw_address :
20
- return ""
21
-
22
- # Split the address on the first space, return that value
23
- # Addresses are usually {address} {optional type_name}
24
- typed_pointer = "((const {} *){})" .format (self .val .type , raw_address .split (None , 1 )[0 ])
25
-
26
- string_no = self .val ["no" ]
27
-
28
- # Check that the pointer is not null.
29
- null_ptr = gdb .parse_and_eval ("{} == 0" .format (typed_pointer ))
30
- if null_ptr .is_optimized_out :
31
- return "{}: <Ptr optimized out>" .format (string_no )
32
- if null_ptr :
33
- return ""
34
-
35
- table_len = gdb .parse_and_eval ("get_string_container().string_vector.size()" )
36
- if table_len .is_optimized_out :
37
- return "{}: <Table len optimized out>" .format (string_no )
38
- if string_no >= table_len :
39
- return "{} index ({}) out of range" .format (self .val .type , string_no )
40
-
41
- value = gdb .parse_and_eval ("{}->c_str()" .format (typed_pointer ))
42
- if value .is_optimized_out :
43
- return "{}: <Optimized out>" .format (string_no )
44
- return "{}: \" {}\" " .format (string_no , value .string ().replace ("\0 " , "" ).replace ("\" " , "\\ \" " ))
72
+ class IrepPrettyPrinter :
73
+ "Print an irept"
74
+
75
+ def __init__ (self , val ):
76
+ self .val = val ["data" ].referenced_value ()
77
+
78
+ def to_string (self ):
79
+ try :
80
+ return "\" {}\" " .format (deconstruct_dstring (self .val ["data" ])[1 ].replace ("\" " , "\\ \" " ))
45
81
except :
46
- return ""
82
+ return "Exception pretty printing irept"
83
+
84
+ def children (self ):
85
+ sub = self .val ["sub" ]
86
+ count = 0
87
+ item = sub ["_M_impl" ]["_M_start" ]
88
+ finish = sub ["_M_impl" ]["_M_finish" ]
89
+ while item != finish :
90
+ yield "sub %d key" % count , "sub[%d]" % count
91
+ yield "sub %d value" % count , item .dereference ()
92
+ count += 1
93
+ item += 1
94
+
95
+ named_sub = self .val ["named_sub" ]
96
+ size = named_sub ["_M_t" ]["_M_impl" ]["_M_node_count" ]
97
+ node = named_sub ["_M_t" ]["_M_impl" ]["_M_header" ]["_M_left" ]
98
+ count = 0
99
+ while count != size :
100
+ rep_type = find_type (named_sub .type , "_Rep_type" )
101
+ link_type = find_type (rep_type , "_Link_type" )
102
+ node_type = link_type .strip_typedefs ()
103
+ current = node .cast (node_type ).dereference ()
104
+ addr_type = current .type .template_argument (0 ).pointer ()
105
+ result = current ["_M_storage" ]["_M_storage" ].address .cast (addr_type ).dereference ()
106
+ yield "named_sub %d key" % count , "named_sub[\" %s\" ]" % deconstruct_dstring (result ["first" ])[1 ].replace ("\" " , "\\ \" " )
107
+ yield "named_sub %d value" % count , result ["second" ]
108
+ count += 1
109
+ if count < size :
110
+ # Get the next node
111
+ right = node .dereference ()["_M_right" ]
112
+ if right :
113
+ node = right
114
+ while True :
115
+ left = node .dereference ()["_M_left" ]
116
+ if not left :
117
+ break
118
+ node = left
119
+ else :
120
+ parent = node .dereference ()["_M_parent" ]
121
+ while node == parent .dereference ()["_M_right" ]:
122
+ node = parent
123
+ parent = parent .dereference ()["_M_parent" ]
124
+ # Not sure what this checks
125
+ if node .dereference ()["_M_right" ] != parent :
126
+ node = parent
47
127
48
128
def display_hint (self ):
49
- return None
129
+ return "map"
50
130
51
131
52
132
class InstructionPrettyPrinter :
0 commit comments