hc
2023-11-06 15ade055295d13f95d49e3d99b09f3bbfb4a43e7
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<!-- Copyright (C) 1988-2021 Free Software Foundation, Inc.
 
Permission is granted to copy, distribute and/or modify this document
under the terms of the GNU Free Documentation License, Version 1.3 or
any later version published by the Free Software Foundation; with the
Invariant Sections being "Free Software" and "Free Software Needs
Free Documentation", with the Front-Cover Texts being "A GNU Manual,"
and with the Back-Cover Texts as in (a) below.
 
(a) The FSF's Back-Cover Text is: "You are free to copy and modify
this GNU Manual.  Buying copies from GNU Press supports the FSF in
developing GNU and promoting software freedom." -->
<!-- Created by GNU Texinfo 5.1, http://www.gnu.org/software/texinfo/ -->
<head>
<title>Debugging with GDB: Frame Decorator API</title>
 
<meta name="description" content="Debugging with GDB: Frame Decorator API">
<meta name="keywords" content="Debugging with GDB: Frame Decorator API">
<meta name="resource-type" content="document">
<meta name="distribution" content="global">
<meta name="Generator" content="makeinfo">
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
<link href="index.html#Top" rel="start" title="Top">
<link href="Concept-Index.html#Concept-Index" rel="index" title="Concept Index">
<link href="index.html#SEC_Contents" rel="contents" title="Table of Contents">
<link href="Python-API.html#Python-API" rel="up" title="Python API">
<link href="Writing-a-Frame-Filter.html#Writing-a-Frame-Filter" rel="next" title="Writing a Frame Filter">
<link href="Frame-Filter-API.html#Frame-Filter-API" rel="previous" title="Frame Filter API">
<style type="text/css">
<!--
a.summary-letter {text-decoration: none}
blockquote.smallquotation {font-size: smaller}
div.display {margin-left: 3.2em}
div.example {margin-left: 3.2em}
div.indentedblock {margin-left: 3.2em}
div.lisp {margin-left: 3.2em}
div.smalldisplay {margin-left: 3.2em}
div.smallexample {margin-left: 3.2em}
div.smallindentedblock {margin-left: 3.2em; font-size: smaller}
div.smalllisp {margin-left: 3.2em}
kbd {font-style:oblique}
pre.display {font-family: inherit}
pre.format {font-family: inherit}
pre.menu-comment {font-family: serif}
pre.menu-preformatted {font-family: serif}
pre.smalldisplay {font-family: inherit; font-size: smaller}
pre.smallexample {font-size: smaller}
pre.smallformat {font-family: inherit; font-size: smaller}
pre.smalllisp {font-size: smaller}
span.nocodebreak {white-space:nowrap}
span.nolinebreak {white-space:nowrap}
span.roman {font-family:serif; font-weight:normal}
span.sansserif {font-family:sans-serif; font-weight:normal}
ul.no-bullet {list-style: none}
-->
</style>
 
 
</head>
 
<body lang="en" bgcolor="#FFFFFF" text="#000000" link="#0000FF" vlink="#800080" alink="#FF0000">
<a name="Frame-Decorator-API"></a>
<div class="header">
<p>
Next: <a href="Writing-a-Frame-Filter.html#Writing-a-Frame-Filter" accesskey="n" rel="next">Writing a Frame Filter</a>, Previous: <a href="Frame-Filter-API.html#Frame-Filter-API" accesskey="p" rel="previous">Frame Filter API</a>, Up: <a href="Python-API.html#Python-API" accesskey="u" rel="up">Python API</a> &nbsp; [<a href="index.html#SEC_Contents" title="Table of contents" rel="contents">Contents</a>][<a href="Concept-Index.html#Concept-Index" title="Index" rel="index">Index</a>]</p>
</div>
<hr>
<a name="Decorating-Frames"></a>
<h4 class="subsubsection">23.2.2.10 Decorating Frames</h4>
<a name="index-frame-decorator-api"></a>
 
<p>Frame decorators are sister objects to frame filters (see <a href="Frame-Filter-API.html#Frame-Filter-API">Frame Filter API</a>).  Frame decorators are applied by a frame filter and can
only be used in conjunction with frame filters.
</p>
<p>The purpose of a frame decorator is to customize the printed content
of each <code>gdb.Frame</code> in commands where frame filters are executed.
This concept is called decorating a frame.  Frame decorators decorate
a <code>gdb.Frame</code> with Python code contained within each API call.
This separates the actual data contained in a <code>gdb.Frame</code> from
the decorated data produced by a frame decorator.  This abstraction is
necessary to maintain integrity of the data contained in each
<code>gdb.Frame</code>.
</p>
<p>Frame decorators have a mandatory interface, defined below.
</p>
<p><small>GDB</small> already contains a frame decorator called
<code>FrameDecorator</code>.  This contains substantial amounts of
boilerplate code to decorate the content of a <code>gdb.Frame</code>.  It is
recommended that other frame decorators inherit and extend this
object, and only to override the methods needed.
</p>
<a name="index-gdb_002eFrameDecorator"></a>
<p><code>FrameDecorator</code> is defined in the Python module
<code>gdb.FrameDecorator</code>, so your code can import it like:
</p><div class="smallexample">
<pre class="smallexample">from gdb.FrameDecorator import FrameDecorator
</pre></div>
 
<dl>
<dt><a name="index-FrameDecorator_002eelided"></a>Function: <strong>FrameDecorator.elided</strong> <em>(self)</em></dt>
<dd>
<p>The <code>elided</code> method groups frames together in a hierarchical
system.  An example would be an interpreter, where multiple low-level
frames make up a single call in the interpreted language.  In this
example, the frame filter would elide the low-level frames and present
a single high-level frame, representing the call in the interpreted
language, to the user.
</p>
<p>The <code>elided</code> function must return an iterable and this iterable
must contain the frames that are being elided wrapped in a suitable
frame decorator.  If no frames are being elided this function may
return an empty iterable, or <code>None</code>.  Elided frames are indented
from normal frames in a <code>CLI</code> backtrace, or in the case of
<code>GDB/MI</code>, are placed in the <code>children</code> field of the eliding
frame.
</p>
<p>It is the frame filter&rsquo;s task to also filter out the elided frames from
the source iterator.  This will avoid printing the frame twice.
</p></dd></dl>
 
<dl>
<dt><a name="index-FrameDecorator_002efunction"></a>Function: <strong>FrameDecorator.function</strong> <em>(self)</em></dt>
<dd>
<p>This method returns the name of the function in the frame that is to
be printed.
</p>
<p>This method must return a Python string describing the function, or
<code>None</code>.
</p>
<p>If this function returns <code>None</code>, <small>GDB</small> will not print any
data for this field.
</p></dd></dl>
 
<dl>
<dt><a name="index-FrameDecorator_002eaddress"></a>Function: <strong>FrameDecorator.address</strong> <em>(self)</em></dt>
<dd>
<p>This method returns the address of the frame that is to be printed.
</p>
<p>This method must return a Python numeric integer type of sufficient
size to describe the address of the frame, or <code>None</code>.
</p>
<p>If this function returns a <code>None</code>, <small>GDB</small> will not print
any data for this field.
</p></dd></dl>
 
<dl>
<dt><a name="index-FrameDecorator_002efilename"></a>Function: <strong>FrameDecorator.filename</strong> <em>(self)</em></dt>
<dd>
<p>This method returns the filename and path associated with this frame.
</p>
<p>This method must return a Python string containing the filename and
the path to the object file backing the frame, or <code>None</code>.
</p>
<p>If this function returns a <code>None</code>, <small>GDB</small> will not print
any data for this field.
</p></dd></dl>
 
<dl>
<dt><a name="index-FrameDecorator_002eline"></a>Function: <strong>FrameDecorator.line</strong> <em>(self):</em></dt>
<dd>
<p>This method returns the line number associated with the current
position within the function addressed by this frame.
</p>
<p>This method must return a Python integer type, or <code>None</code>.
</p>
<p>If this function returns a <code>None</code>, <small>GDB</small> will not print
any data for this field.
</p></dd></dl>
 
<dl>
<dt><a name="index-FrameDecorator_002eframe_005fargs"></a>Function: <strong>FrameDecorator.frame_args</strong> <em>(self)</em></dt>
<dd><a name="frame_005fargs"></a>
<p>This method must return an iterable, or <code>None</code>.  Returning an
empty iterable, or <code>None</code> means frame arguments will not be
printed for this frame.  This iterable must contain objects that
implement two methods, described here.
</p>
<p>This object must implement a <code>argument</code> method which takes a
single <code>self</code> parameter and must return a <code>gdb.Symbol</code>
(see <a href="Symbols-In-Python.html#Symbols-In-Python">Symbols In Python</a>), or a Python string.  The object must also
implement a <code>value</code> method which takes a single <code>self</code>
parameter and must return a <code>gdb.Value</code> (see <a href="Values-From-Inferior.html#Values-From-Inferior">Values From Inferior</a>), a Python value, or <code>None</code>.  If the <code>value</code>
method returns <code>None</code>, and the <code>argument</code> method returns a
<code>gdb.Symbol</code>, <small>GDB</small> will look-up and print the value of
the <code>gdb.Symbol</code> automatically.
</p>
<p>A brief example:
</p>
<div class="smallexample">
<pre class="smallexample">class SymValueWrapper():
 
    def __init__(self, symbol, value):
        self.sym = symbol
        self.val = value
 
    def value(self):
        return self.val
 
    def symbol(self):
        return self.sym
 
class SomeFrameDecorator()
...
...
    def frame_args(self):
        args = []
        try:
            block = self.inferior_frame.block()
        except:
            return None
 
        # Iterate over all symbols in a block.  Only add
        # symbols that are arguments.
        for sym in block:
            if not sym.is_argument:
                continue
            args.append(SymValueWrapper(sym,None))
 
        # Add example synthetic argument.
        args.append(SymValueWrapper(``foo'', 42))
 
        return args
</pre></div>
</dd></dl>
 
<dl>
<dt><a name="index-FrameDecorator_002eframe_005flocals"></a>Function: <strong>FrameDecorator.frame_locals</strong> <em>(self)</em></dt>
<dd>
<p>This method must return an iterable or <code>None</code>.  Returning an
empty iterable, or <code>None</code> means frame local arguments will not be
printed for this frame.
</p>
<p>The object interface, the description of the various strategies for
reading frame locals, and the example are largely similar to those
described in the <code>frame_args</code> function, (see <a href="#frame_005fargs">The
frame filter frame_args function</a>).  Below is a modified example:
</p>
<div class="smallexample">
<pre class="smallexample">class SomeFrameDecorator()
...
...
    def frame_locals(self):
        vars = []
        try:
            block = self.inferior_frame.block()
        except:
            return None
 
        # Iterate over all symbols in a block.  Add all
        # symbols, except arguments.
        for sym in block:
            if sym.is_argument:
                continue
            vars.append(SymValueWrapper(sym,None))
 
        # Add an example of a synthetic local variable.
        vars.append(SymValueWrapper(``bar'', 99))
 
        return vars
</pre></div>
</dd></dl>
 
<dl>
<dt><a name="index-FrameDecorator_002einferior_005fframe"></a>Function: <strong>FrameDecorator.inferior_frame</strong> <em>(self):</em></dt>
<dd>
<p>This method must return the underlying <code>gdb.Frame</code> that this
frame decorator is decorating.  <small>GDB</small> requires the underlying
frame for internal frame information to determine how to print certain
values when printing a frame.
</p></dd></dl>
 
<hr>
<div class="header">
<p>
Next: <a href="Writing-a-Frame-Filter.html#Writing-a-Frame-Filter" accesskey="n" rel="next">Writing a Frame Filter</a>, Previous: <a href="Frame-Filter-API.html#Frame-Filter-API" accesskey="p" rel="previous">Frame Filter API</a>, Up: <a href="Python-API.html#Python-API" accesskey="u" rel="up">Python API</a> &nbsp; [<a href="index.html#SEC_Contents" title="Table of contents" rel="contents">Contents</a>][<a href="Concept-Index.html#Concept-Index" title="Index" rel="index">Index</a>]</p>
</div>
 
 
 
</body>
</html>