summaryrefslogtreecommitdiff
path: root/share/doc/gccint/Debugging-the-Analyzer.html
diff options
context:
space:
mode:
authoralk3pInjection <webmaster@raspii.tech>2024-02-04 16:16:35 +0800
committeralk3pInjection <webmaster@raspii.tech>2024-02-04 16:16:35 +0800
commitabdaadbcae30fe0c9a66c7516798279fdfd97750 (patch)
tree00a54a6e25601e43876d03c1a4a12a749d4a914c /share/doc/gccint/Debugging-the-Analyzer.html
Import stripped Arm GNU Toolchain 13.2.Rel1HEADumineko
https://developer.arm.com/downloads/-/arm-gnu-toolchain-downloads Change-Id: I7303388733328cd98ab9aa3c30236db67f2e9e9c
Diffstat (limited to 'share/doc/gccint/Debugging-the-Analyzer.html')
-rw-r--r--share/doc/gccint/Debugging-the-Analyzer.html349
1 files changed, 349 insertions, 0 deletions
diff --git a/share/doc/gccint/Debugging-the-Analyzer.html b/share/doc/gccint/Debugging-the-Analyzer.html
new file mode 100644
index 0000000..75734f4
--- /dev/null
+++ b/share/doc/gccint/Debugging-the-Analyzer.html
@@ -0,0 +1,349 @@
+<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
+<html>
+<!-- Copyright (C) 1988-2023 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 "Funding Free Software", the Front-Cover
+Texts being (a) (see below), and with the Back-Cover Texts being (b)
+(see below). A copy of the license is included in the section entitled
+"GNU Free Documentation License".
+
+(a) The FSF's Front-Cover Text is:
+
+A GNU Manual
+
+(b) The FSF's Back-Cover Text is:
+
+You have freedom to copy and modify this GNU Manual, like GNU
+ software. Copies published by the Free Software Foundation raise
+ funds for GNU development. -->
+<!-- Created by GNU Texinfo 5.1, http://www.gnu.org/software/texinfo/ -->
+<head>
+<title>GNU Compiler Collection (GCC) Internals: Debugging the Analyzer</title>
+
+<meta name="description" content="GNU Compiler Collection (GCC) Internals: Debugging the Analyzer">
+<meta name="keywords" content="GNU Compiler Collection (GCC) Internals: Debugging the Analyzer">
+<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="Option-Index.html#Option-Index" rel="index" title="Option Index">
+<link href="index.html#SEC_Contents" rel="contents" title="Table of Contents">
+<link href="Static-Analyzer.html#Static-Analyzer" rel="up" title="Static Analyzer">
+<link href="User-Experience-Guidelines.html#User-Experience-Guidelines" rel="next" title="User Experience Guidelines">
+<link href="Analyzer-Internals.html#Analyzer-Internals" rel="previous" title="Analyzer Internals">
+<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="Debugging-the-Analyzer"></a>
+<div class="header">
+<p>
+Previous: <a href="Analyzer-Internals.html#Analyzer-Internals" accesskey="p" rel="previous">Analyzer Internals</a>, Up: <a href="Static-Analyzer.html#Static-Analyzer" accesskey="u" rel="up">Static Analyzer</a> &nbsp; [<a href="index.html#SEC_Contents" title="Table of contents" rel="contents">Contents</a>][<a href="Option-Index.html#Option-Index" title="Index" rel="index">Index</a>]</p>
+</div>
+<hr>
+<a name="Debugging-the-Analyzer-1"></a>
+<h3 class="section">27.2 Debugging the Analyzer</h3>
+<a name="index-analyzer_002c-debugging"></a>
+<a name="index-static-analyzer_002c-debugging"></a>
+
+<p>When debugging the analyzer I normally use all of these options
+together:
+</p>
+<div class="smallexample">
+<pre class="smallexample">./xgcc -B. \
+ -S \
+ -fanalyzer \
+ OTHER_GCC_ARGS \
+ -wrapper gdb,--args \
+ -fdump-analyzer-stderr \
+ -fanalyzer-fine-grained \
+ -fdump-ipa-analyzer=stderr
+</pre></div>
+
+<p>where:
+</p>
+<ul>
+<li> <code>./xgcc -B.</code>
+is the usual way to invoke a self-built GCC from within the <samp>BUILDDIR/gcc</samp>
+subdirectory.
+
+</li><li> <code>-S</code>
+so that the driver (<code>./xgcc</code>) invokes <code>cc1</code>, but doesn&rsquo;t bother
+running the assembler or linker (since the analyzer runs inside <code>cc1</code>).
+
+</li><li> <code>-fanalyzer</code>
+enables the analyzer, obviously.
+
+</li><li> <code>-wrapper gdb,--args</code>
+invokes <code>cc1</code> under the debugger so that I can debug <code>cc1</code> and
+set breakpoints and step through things.
+
+</li><li> <code>-fdump-analyzer-stderr</code>
+so that the logging interface is enabled and goes to stderr, which often
+gives valuable context into what&rsquo;s happening when stepping through the
+analyzer
+
+</li><li> <code>-fanalyzer-fine-grained</code>
+which splits the effect of every statement into its own
+exploded_node, rather than the default (which tries to combine
+successive stmts to reduce the size of the exploded_graph). This makes
+it easier to see exactly where a particular change happens.
+
+</li><li> <code>-fdump-ipa-analyzer=stderr</code>
+which dumps the GIMPLE IR seen by the analyzer pass to stderr
+
+</li></ul>
+
+<p>Other useful options:
+</p>
+<ul>
+<li> <code>-fdump-analyzer-exploded-graph</code>
+which dumps a <samp>SRC.eg.dot</samp> GraphViz file that I can look at (with
+python-xdot)
+
+</li><li> <code>-fdump-analyzer-exploded-nodes-2</code>
+which dumps a <samp>SRC.eg.txt</samp> file containing the full <code>exploded_graph</code>.
+
+</li></ul>
+
+<p>Assuming that you have the
+<a href="https://gcc-newbies-guide.readthedocs.io/en/latest/debugging.html">python support scripts for gdb</a>
+installed, you can use:
+</p>
+<div class="smallexample">
+<pre class="smallexample">(gdb) break-on-saved-diagnostic
+</pre></div>
+
+<p>to put a breakpoint at the place where a diagnostic is saved during
+<code>exploded_graph</code> exploration, to see where a particular diagnostic
+is being saved, and:
+</p>
+<div class="smallexample">
+<pre class="smallexample">(gdb) break-on-diagnostic
+</pre></div>
+
+<p>to put a breakpoint at the place where diagnostics are actually emitted.
+</p>
+<a name="Special-Functions-for-Debugging-the-Analyzer"></a>
+<h4 class="subsection">27.2.1 Special Functions for Debugging the Analyzer</h4>
+
+<p>The analyzer recognizes various special functions by name, for use
+in debugging the analyzer, and for use in DejaGnu tests.
+</p>
+<p>The declarations of these functions can be seen in the testsuite
+in <samp>analyzer-decls.h</samp>. None of these functions are actually
+implemented in terms of code, merely as <code>known_function</code> subclasses
+(in <samp>gcc/analyzer/kf-analyzer.cc</samp>).
+</p>
+<dl compact="compact">
+<dt><code>__analyzer_break</code></dt>
+<dd><p>Add:
+</p><div class="smallexample">
+<pre class="smallexample"> __analyzer_break ();
+</pre></div>
+<p>to the source being analyzed to trigger a breakpoint in the analyzer when
+that source is reached. By putting a series of these in the source, it&rsquo;s
+much easier to effectively step through the program state as it&rsquo;s analyzed.
+</p>
+</dd>
+<dt><code>__analyzer_describe</code></dt>
+<dd><p>The analyzer handles:
+</p>
+<div class="smallexample">
+<pre class="smallexample">__analyzer_describe (0, expr);
+</pre></div>
+
+<p>by emitting a warning describing the 2nd argument (which can be of any
+type), at a verbosity level given by the 1st argument. This is for use when
+debugging, and may be of use in DejaGnu tests.
+</p>
+</dd>
+<dt><code>__analyzer_dump</code></dt>
+<dd><div class="smallexample">
+<pre class="smallexample">__analyzer_dump ();
+</pre></div>
+
+<p>will dump the copious information about the analyzer&rsquo;s state each time it
+reaches the call in its traversal of the source.
+</p>
+</dd>
+<dt><code>__analyzer_dump_capacity</code></dt>
+<dd><div class="smallexample">
+<pre class="smallexample">extern void __analyzer_dump_capacity (const void *ptr);
+</pre></div>
+
+<p>will emit a warning describing the capacity of the base region of
+the region pointed to by the 1st argument.
+</p>
+</dd>
+<dt><code>__analyzer_dump_escaped</code></dt>
+<dd><div class="smallexample">
+<pre class="smallexample">extern void __analyzer_dump_escaped (void);
+</pre></div>
+
+<p>will emit a warning giving the number of decls that have escaped on this
+analysis path, followed by a comma-separated list of their names,
+in alphabetical order.
+</p>
+</dd>
+<dt><code>__analyzer_dump_path</code></dt>
+<dd><div class="smallexample">
+<pre class="smallexample">__analyzer_dump_path ();
+</pre></div>
+
+<p>will emit a placeholder &ldquo;note&rdquo; diagnostic with a path to that call site,
+if the analyzer finds a feasible path to it. This can be useful for
+writing DejaGnu tests for constraint-tracking and feasibility checking.
+</p>
+</dd>
+<dt><code>__analyzer_dump_exploded_nodes</code></dt>
+<dd><p>For every callsite to <code>__analyzer_dump_exploded_nodes</code> the analyzer
+will emit a warning after it finished the analysis containing information
+on all of the exploded nodes at that program point.
+</p>
+<div class="smallexample">
+<pre class="smallexample"> __analyzer_dump_exploded_nodes (0);
+</pre></div>
+
+<p>will output the number of &ldquo;processed&rdquo; nodes, and the IDs of
+both &ldquo;processed&rdquo; and &ldquo;merger&rdquo; nodes, such as:
+</p>
+<div class="smallexample">
+<pre class="smallexample">warning: 2 processed enodes: [EN: 56, EN: 58] merger(s): [EN: 54-55, EN: 57, EN: 59]
+</pre></div>
+
+<p>With a non-zero argument
+</p>
+<div class="smallexample">
+<pre class="smallexample"> __analyzer_dump_exploded_nodes (1);
+</pre></div>
+
+<p>it will also dump all of the states within the &ldquo;processed&rdquo; nodes.
+</p>
+</dd>
+<dt><code>__analyzer_dump_named_constant</code></dt>
+<dd><p>When the analyzer sees a call to <code>__analyzer_dump_named_constant</code> it
+will emit a warning describing what is known about the value of a given
+named constant, for parts of the analyzer that interact with target
+headers.
+</p>
+<p>For example:
+</p>
+<div class="smallexample">
+<pre class="smallexample">__analyzer_dump_named_constant (&quot;O_RDONLY&quot;);
+</pre></div>
+
+<p>might lead to the analyzer emitting the warning:
+</p>
+<div class="smallexample">
+<pre class="smallexample">warning: named constant 'O_RDONLY' has value '1'
+</pre></div>
+
+</dd>
+<dt><code>__analyzer_dump_region_model</code></dt>
+<dd><div class="smallexample">
+<pre class="smallexample"> __analyzer_dump_region_model ();
+</pre></div>
+<p>will dump the region_model&rsquo;s state to stderr.
+</p>
+</dd>
+<dt><code>__analyzer_dump_state</code></dt>
+<dd><div class="smallexample">
+<pre class="smallexample">__analyzer_dump_state (&quot;malloc&quot;, ptr);
+</pre></div>
+
+<p>will emit a warning describing the state of the 2nd argument
+(which can be of any type) with respect to the state machine with
+a name matching the 1st argument (which must be a string literal).
+This is for use when debugging, and may be of use in DejaGnu tests.
+</p>
+</dd>
+<dt><code>__analyzer_eval</code></dt>
+<dd><div class="smallexample">
+<pre class="smallexample">__analyzer_eval (expr);
+</pre></div>
+<p>will emit a warning with text &quot;TRUE&quot;, FALSE&quot; or &quot;UNKNOWN&quot; based on the
+truthfulness of the argument. This is useful for writing DejaGnu tests.
+</p>
+</dd>
+<dt><code>__analyzer_get_unknown_ptr</code></dt>
+<dd><div class="smallexample">
+<pre class="smallexample">__analyzer_get_unknown_ptr ();
+</pre></div>
+<p>will obtain an unknown <code>void *</code>.
+</p>
+</dd>
+</dl>
+
+<a name="Other-Debugging-Techniques"></a>
+<h4 class="subsection">27.2.2 Other Debugging Techniques</h4>
+
+<p>To compare two different exploded graphs, try
+<code>-fdump-analyzer-exploded-nodes-2 -fdump-noaddr -fanalyzer-fine-grained</code>.
+This will dump a <samp>SRC.eg.txt</samp> file containing the full
+<code>exploded_graph</code>. I use <code>diff -u50 -p</code> to compare two different
+such files (e.g. before and after a patch) to find the first place where the
+two graphs diverge. The option <samp>-fdump-noaddr</samp> will suppress
+printing pointers withihn the dumps (which would otherwise hide the real
+differences with irrelevent churn).
+</p>
+<p>The option <samp>-fdump-analyzer-json</samp> will dump both the supergraph
+and the exploded graph in compressed JSON form.
+</p>
+<p>One approach when tracking down where a particular bogus state is
+introduced into the <code>exploded_graph</code> is to add custom code to
+<code>program_state::validate</code>.
+</p>
+<p>The debug function <code>region::is_named_decl_p</code> can be used when debugging,
+such as for assertions and conditional breakpoints. For example, when
+tracking down a bug in handling a decl called <code>yy_buffer_stack</code>, I
+temporarily added a:
+</p><div class="smallexample">
+<pre class="smallexample"> gcc_assert (!m_base_region-&gt;is_named_decl_p (&quot;yy_buffer_stack&quot;));
+</pre></div>
+<p>to <code>binding_cluster::mark_as_escaped</code> to trap a point where
+<code>yy_buffer_stack</code> was mistakenly being treated as having escaped.
+</p>
+<hr>
+<div class="header">
+<p>
+Previous: <a href="Analyzer-Internals.html#Analyzer-Internals" accesskey="p" rel="previous">Analyzer Internals</a>, Up: <a href="Static-Analyzer.html#Static-Analyzer" accesskey="u" rel="up">Static Analyzer</a> &nbsp; [<a href="index.html#SEC_Contents" title="Table of contents" rel="contents">Contents</a>][<a href="Option-Index.html#Option-Index" title="Index" rel="index">Index</a>]</p>
+</div>
+
+
+
+</body>
+</html>