<!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 Filter API</title>
|
|
<meta name="description" content="Debugging with GDB: Frame Filter API">
|
<meta name="keywords" content="Debugging with GDB: Frame Filter 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="Frame-Decorator-API.html#Frame-Decorator-API" rel="next" title="Frame Decorator API">
|
<link href="Type-Printing-API.html#Type-Printing-API" rel="previous" title="Type Printing 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-Filter-API"></a>
|
<div class="header">
|
<p>
|
Next: <a href="Frame-Decorator-API.html#Frame-Decorator-API" accesskey="n" rel="next">Frame Decorator API</a>, Previous: <a href="Type-Printing-API.html#Type-Printing-API" accesskey="p" rel="previous">Type Printing API</a>, Up: <a href="Python-API.html#Python-API" accesskey="u" rel="up">Python API</a> [<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="Filtering-Frames"></a>
|
<h4 class="subsubsection">23.2.2.9 Filtering Frames</h4>
|
<a name="index-frame-filters-api"></a>
|
|
<p>Frame filters are Python objects that manipulate the visibility of a
|
frame or frames when a backtrace (see <a href="Backtrace.html#Backtrace">Backtrace</a>) is printed by
|
<small>GDB</small>.
|
</p>
|
<p>Only commands that print a backtrace, or, in the case of <small>GDB/MI</small>
|
commands (see <a href="GDB_002fMI.html#GDB_002fMI">GDB/MI</a>), those that return a collection of frames
|
are affected. The commands that work with frame filters are:
|
</p>
|
<p><code>backtrace</code> (see <a href="Backtrace.html#backtrace_002dcommand">The backtrace command</a>),
|
<code>-stack-list-frames</code>
|
(see <a href="GDB_002fMI-Stack-Manipulation.html#g_t_002dstack_002dlist_002dframes">The -stack-list-frames command</a>),
|
<code>-stack-list-variables</code> (see <a href="GDB_002fMI-Stack-Manipulation.html#g_t_002dstack_002dlist_002dvariables">The
|
-stack-list-variables command</a>), <code>-stack-list-arguments</code>
|
see <a href="GDB_002fMI-Stack-Manipulation.html#g_t_002dstack_002dlist_002darguments">The -stack-list-arguments command</a>) and
|
<code>-stack-list-locals</code> (see <a href="GDB_002fMI-Stack-Manipulation.html#g_t_002dstack_002dlist_002dlocals">The
|
-stack-list-locals command</a>).
|
</p>
|
<p>A frame filter works by taking an iterator as an argument, applying
|
actions to the contents of that iterator, and returning another
|
iterator (or, possibly, the same iterator it was provided in the case
|
where the filter does not perform any operations). Typically, frame
|
filters utilize tools such as the Python’s <code>itertools</code> module to
|
work with and create new iterators from the source iterator.
|
Regardless of how a filter chooses to apply actions, it must not alter
|
the underlying <small>GDB</small> frame or frames, or attempt to alter the
|
call-stack within <small>GDB</small>. This preserves data integrity within
|
<small>GDB</small>. Frame filters are executed on a priority basis and care
|
should be taken that some frame filters may have been executed before,
|
and that some frame filters will be executed after.
|
</p>
|
<p>An important consideration when designing frame filters, and well
|
worth reflecting upon, is that frame filters should avoid unwinding
|
the call stack if possible. Some stacks can run very deep, into the
|
tens of thousands in some cases. To search every frame when a frame
|
filter executes may be too expensive at that step. The frame filter
|
cannot know how many frames it has to iterate over, and it may have to
|
iterate through them all. This ends up duplicating effort as
|
<small>GDB</small> performs this iteration when it prints the frames. If
|
the filter can defer unwinding frames until frame decorators are
|
executed, after the last filter has executed, it should. See <a href="Frame-Decorator-API.html#Frame-Decorator-API">Frame Decorator API</a>, for more information on decorators. Also, there are
|
examples for both frame decorators and filters in later chapters.
|
See <a href="Writing-a-Frame-Filter.html#Writing-a-Frame-Filter">Writing a Frame Filter</a>, for more information.
|
</p>
|
<p>The Python dictionary <code>gdb.frame_filters</code> contains key/object
|
pairings that comprise a frame filter. Frame filters in this
|
dictionary are called <code>global</code> frame filters, and they are
|
available when debugging all inferiors. These frame filters must
|
register with the dictionary directly. In addition to the
|
<code>global</code> dictionary, there are other dictionaries that are loaded
|
with different inferiors via auto-loading (see <a href="Python-Auto_002dloading.html#Python-Auto_002dloading">Python Auto-loading</a>). The two other areas where frame filter dictionaries
|
can be found are: <code>gdb.Progspace</code> which contains a
|
<code>frame_filters</code> dictionary attribute, and each <code>gdb.Objfile</code>
|
object which also contains a <code>frame_filters</code> dictionary
|
attribute.
|
</p>
|
<p>When a command is executed from <small>GDB</small> that is compatible with
|
frame filters, <small>GDB</small> combines the <code>global</code>,
|
<code>gdb.Progspace</code> and all <code>gdb.Objfile</code> dictionaries currently
|
loaded. All of the <code>gdb.Objfile</code> dictionaries are combined, as
|
several frames, and thus several object files, might be in use.
|
<small>GDB</small> then prunes any frame filter whose <code>enabled</code>
|
attribute is <code>False</code>. This pruned list is then sorted according
|
to the <code>priority</code> attribute in each filter.
|
</p>
|
<p>Once the dictionaries are combined, pruned and sorted, <small>GDB</small>
|
creates an iterator which wraps each frame in the call stack in a
|
<code>FrameDecorator</code> object, and calls each filter in order. The
|
output from the previous filter will always be the input to the next
|
filter, and so on.
|
</p>
|
<p>Frame filters have a mandatory interface which each frame filter must
|
implement, defined here:
|
</p>
|
<dl>
|
<dt><a name="index-FrameFilter_002efilter"></a>Function: <strong>FrameFilter.filter</strong> <em>(iterator)</em></dt>
|
<dd><p><small>GDB</small> will call this method on a frame filter when it has
|
reached the order in the priority list for that filter.
|
</p>
|
<p>For example, if there are four frame filters:
|
</p>
|
<div class="smallexample">
|
<pre class="smallexample">Name Priority
|
|
Filter1 5
|
Filter2 10
|
Filter3 100
|
Filter4 1
|
</pre></div>
|
|
<p>The order that the frame filters will be called is:
|
</p>
|
<div class="smallexample">
|
<pre class="smallexample">Filter3 -> Filter2 -> Filter1 -> Filter4
|
</pre></div>
|
|
<p>Note that the output from <code>Filter3</code> is passed to the input of
|
<code>Filter2</code>, and so on.
|
</p>
|
<p>This <code>filter</code> method is passed a Python iterator. This iterator
|
contains a sequence of frame decorators that wrap each
|
<code>gdb.Frame</code>, or a frame decorator that wraps another frame
|
decorator. The first filter that is executed in the sequence of frame
|
filters will receive an iterator entirely comprised of default
|
<code>FrameDecorator</code> objects. However, after each frame filter is
|
executed, the previous frame filter may have wrapped some or all of
|
the frame decorators with their own frame decorator. As frame
|
decorators must also conform to a mandatory interface, these
|
decorators can be assumed to act in a uniform manner (see <a href="Frame-Decorator-API.html#Frame-Decorator-API">Frame Decorator API</a>).
|
</p>
|
<p>This method must return an object conforming to the Python iterator
|
protocol. Each item in the iterator must be an object conforming to
|
the frame decorator interface. If a frame filter does not wish to
|
perform any operations on this iterator, it should return that
|
iterator untouched.
|
</p>
|
<p>This method is not optional. If it does not exist, <small>GDB</small> will
|
raise and print an error.
|
</p></dd></dl>
|
|
<dl>
|
<dt><a name="index-FrameFilter_002ename"></a>Variable: <strong>FrameFilter.name</strong></dt>
|
<dd><p>The <code>name</code> attribute must be Python string which contains the
|
name of the filter displayed by <small>GDB</small> (see <a href="Frame-Filter-Management.html#Frame-Filter-Management">Frame Filter Management</a>). This attribute may contain any combination of letters
|
or numbers. Care should be taken to ensure that it is unique. This
|
attribute is mandatory.
|
</p></dd></dl>
|
|
<dl>
|
<dt><a name="index-FrameFilter_002eenabled"></a>Variable: <strong>FrameFilter.enabled</strong></dt>
|
<dd><p>The <code>enabled</code> attribute must be Python boolean. This attribute
|
indicates to <small>GDB</small> whether the frame filter is enabled, and
|
should be considered when frame filters are executed. If
|
<code>enabled</code> is <code>True</code>, then the frame filter will be executed
|
when any of the backtrace commands detailed earlier in this chapter
|
are executed. If <code>enabled</code> is <code>False</code>, then the frame
|
filter will not be executed. This attribute is mandatory.
|
</p></dd></dl>
|
|
<dl>
|
<dt><a name="index-FrameFilter_002epriority"></a>Variable: <strong>FrameFilter.priority</strong></dt>
|
<dd><p>The <code>priority</code> attribute must be Python integer. This attribute
|
controls the order of execution in relation to other frame filters.
|
There are no imposed limits on the range of <code>priority</code> other than
|
it must be a valid integer. The higher the <code>priority</code> attribute,
|
the sooner the frame filter will be executed in relation to other
|
frame filters. Although <code>priority</code> can be negative, it is
|
recommended practice to assume zero is the lowest priority that a
|
frame filter can be assigned. Frame filters that have the same
|
priority are executed in unsorted order in that priority slot. This
|
attribute is mandatory. 100 is a good default priority.
|
</p></dd></dl>
|
|
<hr>
|
<div class="header">
|
<p>
|
Next: <a href="Frame-Decorator-API.html#Frame-Decorator-API" accesskey="n" rel="next">Frame Decorator API</a>, Previous: <a href="Type-Printing-API.html#Type-Printing-API" accesskey="p" rel="previous">Type Printing API</a>, Up: <a href="Python-API.html#Python-API" accesskey="u" rel="up">Python API</a> [<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>
|