blob: 3f9953b4b6b50d9a1b49e274e9d3503c82b70049 [file] [log] [blame]
<!--
Documentation/_templates/layout.html
Licensed to the Apache Software Foundation (ASF) under one or more
contributor license agreements. See the NOTICE file distributed with
this work for additional information regarding copyright ownership. The
ASF licenses this file to you under the Apache License, Version 2.0 (the
"License"); you may not use this file except in compliance with the
License. You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
License for the specific language governing permissions and limitations
under the License.
-->
<!DOCTYPE html>
<html class="writer-html5" lang="en" >
<head>
<meta charset="utf-8" /><meta name="generator" content="Docutils 0.18.1: http://docutils.sourceforge.net/" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Analyzing Cortex-M Hardfaults &mdash; NuttX latest documentation</title>
<link rel="stylesheet" href="../_static/pygments.css" type="text/css" />
<link rel="stylesheet" href="../_static/css/theme.css" type="text/css" />
<link rel="stylesheet" href="../_static/copybutton.css" type="text/css" />
<link rel="stylesheet" href="../_static/tabs.css" type="text/css" />
<link rel="stylesheet" href="../_static/custom.css" type="text/css" />
<link rel="shortcut icon" href="../_static/favicon.ico"/>
<!--[if lt IE 9]>
<script src="../_static/js/html5shiv.min.js"></script>
<![endif]-->
<script src="../_static/jquery.js"></script>
<script src="../_static/_sphinx_javascript_frameworks_compat.js"></script>
<script data-url_root="../" id="documentation_options" src="../_static/documentation_options.js"></script>
<script src="../_static/doctools.js"></script>
<script src="../_static/sphinx_highlight.js"></script>
<script src="../_static/clipboard.min.js"></script>
<script src="../_static/copybutton.js"></script>
<script src="../_static/js/theme.js"></script>
<link rel="index" title="Index" href="../genindex.html" />
<link rel="search" title="Search" href="../search.html" />
<link rel="next" title="Core Dump" href="coredump.html" />
<link rel="prev" title="Nested Interrupts" href="nestedinterrupts.html" />
</head>
<body class="wy-body-for-nav">
<div class="wy-grid-for-nav">
<nav data-toggle="wy-nav-shift" class="wy-nav-side">
<div class="wy-side-scroll">
<div class="wy-side-nav-search" >
<a href="../index.html" class="icon icon-home"> NuttX
</a>
<!-- this version selector is quite ugly, should be probably replaced by something
more modern -->
<div class="version-selector">
<select onchange="javascript:location.href = this.value;">
<option value="../../latest" selected="selected">latest</option>
<option value="../../10.0.0" >10.0.0</option>
<option value="../../10.0.1" >10.0.1</option>
<option value="../../10.1.0" >10.1.0</option>
<option value="../../10.2.0" >10.2.0</option>
<option value="../../10.3.0" >10.3.0</option>
<option value="../../11.0.0" >11.0.0</option>
<option value="../../12.0.0" >12.0.0</option>
<option value="../../12.1.0" >12.1.0</option>
<option value="../../12.2.0" >12.2.0</option>
<option value="../../12.2.1" >12.2.1</option>
<option value="../../12.3.0" >12.3.0</option>
<option value="../../12.4.0" >12.4.0</option>
<option value="../../12.5.0" >12.5.0</option>
<option value="../../12.5.1" >12.5.1</option>
</select>
</div>
<div role="search">
<form id="rtd-search-form" class="wy-form" action="../search.html" method="get">
<input type="text" name="q" placeholder="Search docs" aria-label="Search docs" />
<input type="hidden" name="check_keywords" value="yes" />
<input type="hidden" name="area" value="default" />
</form>
</div>
</div><div class="wy-menu wy-menu-vertical" data-spy="affix" role="navigation" aria-label="Navigation menu">
<p class="caption" role="heading"><span class="caption-text">Table of Contents</span></p>
<ul class="current">
<li class="toctree-l1"><a class="reference internal" href="../index.html">Home</a></li>
<li class="toctree-l1"><a class="reference internal" href="../introduction/index.html">Introduction</a></li>
<li class="toctree-l1"><a class="reference internal" href="../quickstart/index.html">Getting Started</a></li>
<li class="toctree-l1"><a class="reference internal" href="../contributing/index.html">Contributing</a></li>
<li class="toctree-l1"><a class="reference internal" href="../introduction/inviolables.html">The Inviolable Principles of NuttX</a></li>
<li class="toctree-l1"><a class="reference internal" href="../platforms/index.html">Supported Platforms</a></li>
<li class="toctree-l1"><a class="reference internal" href="../components/index.html">OS Components</a></li>
<li class="toctree-l1"><a class="reference internal" href="../applications/index.html">Applications</a></li>
<li class="toctree-l1"><a class="reference internal" href="../reference/index.html">API Reference</a></li>
<li class="toctree-l1"><a class="reference internal" href="../faq/index.html">FAQ</a></li>
<li class="toctree-l1 current"><a class="reference internal" href="index.html">Guides</a><ul class="current">
<li class="toctree-l2"><a class="reference internal" href="nfs.html">NFS Client How-To</a></li>
<li class="toctree-l2"><a class="reference internal" href="usbtrace.html">USB Device Trace</a></li>
<li class="toctree-l2"><a class="reference internal" href="simulator.html">Simulator</a></li>
<li class="toctree-l2"><a class="reference internal" href="qemugdb.html">How to debug NuttX using QEMU and GDB</a></li>
<li class="toctree-l2"><a class="reference internal" href="rndis.html">How to use RNDIS</a></li>
<li class="toctree-l2"><a class="reference internal" href="drivers.html">Drivers</a></li>
<li class="toctree-l2"><a class="reference internal" href="tasktrace.html">Task Trace</a></li>
<li class="toctree-l2"><a class="reference internal" href="cpp_cmake.html">C++ Example using CMake</a></li>
<li class="toctree-l2"><a class="reference internal" href="pysimcoder.html">pysimCoder integration with NuttX</a></li>
<li class="toctree-l2"><a class="reference internal" href="customboards.html">Custom Boards How-To</a></li>
<li class="toctree-l2"><a class="reference internal" href="customapps.html">Custom Apps How-to</a></li>
<li class="toctree-l2"><a class="reference internal" href="zerolatencyinterrupts.html">High Performance, Zero Latency Interrupts</a></li>
<li class="toctree-l2"><a class="reference internal" href="nestedinterrupts.html">Nested Interrupts</a></li>
<li class="toctree-l2 current"><a class="current reference internal" href="#">Analyzing Cortex-M Hardfaults</a><ul>
<li class="toctree-l3"><a class="reference internal" href="#analyzing-the-register-dump">Analyzing the Register Dump</a></li>
<li class="toctree-l3"><a class="reference internal" href="#analyzing-the-stack-dump">Analyzing the Stack Dump</a><ul>
<li class="toctree-l4"><a class="reference internal" href="#the-task-stack">The Task Stack</a></li>
<li class="toctree-l4"><a class="reference internal" href="#the-interrupt-stack">The Interrupt Stack</a></li>
<li class="toctree-l4"><a class="reference internal" href="#full-stack-analysis">Full Stack Analysis</a></li>
</ul>
</li>
<li class="toctree-l3"><a class="reference internal" href="#recovering-state-at-the-time-of-the-hardfault">Recovering State at the Time of the Hardfault</a></li>
</ul>
</li>
<li class="toctree-l2"><a class="reference internal" href="coredump.html">Core Dump</a></li>
<li class="toctree-l2"><a class="reference internal" href="gdbwithpython.html">GDB with Python</a></li>
</ul>
</li>
<li class="toctree-l1"><a class="reference internal" href="../glossary.html">Glossary</a></li>
</ul>
</div>
</div>
</nav>
<section data-toggle="wy-nav-shift" class="wy-nav-content-wrap"><nav class="wy-nav-top" aria-label="Mobile navigation menu" >
<i data-toggle="wy-nav-top" class="fa fa-bars"></i>
<a href="../index.html">NuttX</a>
</nav>
<div class="wy-nav-content">
<div class="rst-content">
<div role="navigation" aria-label="Page navigation">
<ul class="wy-breadcrumbs">
<li><a href="../index.html" class="icon icon-home" aria-label="Home"></a></li>
<li class="breadcrumb-item"><a href="index.html">Guides</a></li>
<li class="breadcrumb-item active">Analyzing Cortex-M Hardfaults</li>
<li class="wy-breadcrumbs-aside">
<a href="../_sources/guides/cortexmhardfaults.rst.txt" rel="nofollow"> View page source</a>
</li>
</ul>
<hr/>
</div>
<div role="main" class="document" itemscope="itemscope" itemtype="http://schema.org/Article">
<div itemprop="articleBody">
<section id="analyzing-cortex-m-hardfaults">
<h1>Analyzing Cortex-M Hardfaults<a class="headerlink" href="#analyzing-cortex-m-hardfaults" title="Permalink to this heading"></a></h1>
<blockquote class="epigraph">
<div><p>&gt; I have a build of PX4 (NuttX 6.29 with some patches) with new
&gt; lpc43xx chip files on 4337 chip running from FLASH (master
&gt; vanilla NuttX has no such problem). This gives me a hardfault
&gt; below if I stress NSH console (UART2) with some big output.
&gt;
&gt; I read some threads but can’t get a clue how to analyze the
&gt; dump and where to look first:
&gt;
&gt; 1bXXX and 1aXXX addresses are FLASH. 100XXX addresses are RAM</p>
</div></blockquote>
<div class="highlight-console notranslate"><div class="highlight"><pre><span></span><span class="go">Assertion failed at file:armv7-m/up_hardfault.c line: 184 task: hpwork</span>
<span class="go">sp: 10001eb4</span>
<span class="go">IRQ stack:</span>
<span class="go"> base: 10001f00</span>
<span class="go"> size: 000003fc</span>
<span class="go">10001ea0: 1b02d961 1b03f07e 10001eb4 10005ed8 1a0312ab 1b03f600 000000b8 1b02d961</span>
<span class="go">10001ec0: 00000010 10001f40 00000003 00000000 1a03721d 1a037209 1b02d93b 00000000</span>
<span class="go">10001ee0: 1a0371f5 00000000 00000000 00000000 00000000 00000000 1a0314a5 10005d7c</span>
<span class="go">sp: 10005e50</span>
<span class="go">User stack:</span>
<span class="go"> base: 10005ed8</span>
<span class="go"> size: 00000f9c</span>
<span class="go">10005e40: 00000000 00000000 00000000 1b02d587 10004900 00000000 005b8d7f 00000000</span>
<span class="go">10005e60: 1a030f2e 00000000 00000000 00001388 00000000 00000005 10001994 00000000</span>
<span class="go">10005e80: 00000000 00000000 00000000 1b02c359 00000000 00000000 00000000 004c4b40</span>
<span class="go">10005ea0: 000002ff 00000000 00000000 1a030f2f 00000000 00000000 00000000 00000000</span>
<span class="go">10005ec0: 00000000 1a030f41 00000000 1b02c2a5 00000000 00000000 ffffffff 00bdeb39</span>
<span class="go">R0: ffffffff 00000000 00000016 00000000 00000000 00000000 00000000 00000000</span>
<span class="go">R8: 100036d8 00000000 00000000 004c4b40 10001370 10005e50 1b02b20b 1b02d596</span>
<span class="go">xPSR: 41000000 BASEPRI: 00000000 CONTROL: 00000000</span>
<span class="go">EXC_RETURN: ffffffe9</span>
</pre></div>
</div>
<p>This question was asked in the old Yahoo! Group for NuttX, before the
project joined the Apache Software Foundation. The old forum no longer
exists, but the thread has been archived at
<a class="reference external" href="https://nuttx.yahoogroups.narkive.com/QNbG3r5l/hardfault-help-analysing-where-to-start">Narkive</a>
(third party external link).</p>
<section id="analyzing-the-register-dump">
<h2>Analyzing the Register Dump<a class="headerlink" href="#analyzing-the-register-dump" title="Permalink to this heading"></a></h2>
<p>First, in the register dump:</p>
<div class="highlight-console notranslate"><div class="highlight"><pre><span></span><span class="go">R0: ffffffff 00000000 00000016 00000000 00000000 00000000 00000000 00000000</span>
<span class="go">R8: 100036d8 00000000 00000000 004c4b40 10001370 10005e50 1b02b20b 1b02d596</span>
<span class="go">xPSR: 41000000 BASEPRI: 00000000 CONTROL: 00000000</span>
</pre></div>
</div>
<p><code class="docutils literal notranslate"><span class="pre">R15</span></code> is the PC at the time of the crash (<code class="docutils literal notranslate"><span class="pre">1b02d596</span></code>). In order to
see where this is, I do this:</p>
<div class="highlight-console notranslate"><div class="highlight"><pre><span></span><span class="go">arm-none-eabi-objdump -d nuttx | vi -</span>
</pre></div>
</div>
<p>Of course, you can use any editor you prefer. In any case, this will
provide a full assembly language listing of your FLASH content along
with complete symbolic information.</p>
<p><strong>TIP:</strong> Not comfortable with ARM assembly language? Try the
<code class="docutils literal notranslate"><span class="pre">objdump</span> <span class="pre">--source</span></code> (or just <code class="docutils literal notranslate"><span class="pre">-S</span></code>) option. That will intermix the C
and the assembly language code so that you can see which C statements
the assembly language is implementing.</p>
<p>Once you have the FLASH image in the editor, it is then a simple thing
to do the search in order to find the instruction at <code class="docutils literal notranslate"><span class="pre">1b02d596</span></code>. The
symbolic information will show you exactly which function the address
is in and also the context of the instruction that can be used to
associate it to the exact line of code in the original C source file.</p>
<p>You also have all of the register contents so it is pretty easy to see
what happened (assuming you have some basic knowledge of Thumb2
assembly language and the ARM EABI). But it is usually not so easy to
see why it happened.</p>
<p>The rest of the instructions apply to finding out why the fault
happened.</p>
<p><code class="docutils literal notranslate"><span class="pre">R14</span></code> often contains the return address to the caller of the
offending functions. Bit one is set in this return address, but ignore
that (I.e., use <code class="docutils literal notranslate"><span class="pre">1b02b20a</span></code> instead of <code class="docutils literal notranslate"><span class="pre">1b02b20b</span></code>). Use the objdump
command above to see where that is.</p>
<p>Sometimes, however, <code class="docutils literal notranslate"><span class="pre">R14</span></code> is not the caller of the offending
function. If the offending functions calls some other function then
<code class="docutils literal notranslate"><span class="pre">R14</span></code> will be overwritten. But no problem, it will also then have
pushed the return address on the stack where we can find it by
analyzing the stack dump.</p>
</section>
<section id="analyzing-the-stack-dump">
<h2>Analyzing the Stack Dump<a class="headerlink" href="#analyzing-the-stack-dump" title="Permalink to this heading"></a></h2>
<section id="the-task-stack">
<h3>The Task Stack<a class="headerlink" href="#the-task-stack" title="Permalink to this heading"></a></h3>
<p>To go further back in the time, you have to analyze the stack. It is a
push down stack so older events are at higher stack addresses; the
most recent things that happened will be at lower stack addresses.</p>
<p>Analyzing the stack is done in basically the same way:</p>
<ol class="arabic simple">
<li><p>Start at the highest stack addresses (oldest) and work forward in
time (lower addresses)</p></li>
<li><p>Find interesting addresses,</p></li>
<li><p>Use <code class="docutils literal notranslate"><span class="pre">arm-none-eabi-objdump</span></code> to determine where those addresses
are in the code.</p></li>
</ol>
<p>An interesting address has these properties:</p>
<ol class="arabic simple">
<li><p>It lies in FLASH in your architecture. In your case these are the
addresses that begin with <code class="docutils literal notranslate"><span class="pre">0x1a</span></code> and <code class="docutils literal notranslate"><span class="pre">0x1b</span></code>. Other
architectures may have different FLASH addresses or even addresses
in RAM.</p></li>
<li><p>The interesting addresses are all odd for Cortex-M, that is, bit 0
will be set. This is because as the code progresses, the return
address (<code class="docutils literal notranslate"><span class="pre">R14</span></code>) will be pushed on the stack. All of the return
addresses will lie in FLASH and will be odd.</p></li>
</ol>
<p>Even FLASH addresses in the stack dump usually are references to
<code class="docutils literal notranslate"><span class="pre">.rodata</span></code> in FLASH but are sometimes of interest as well. Below are
examples of interesting addresses (in brackets):</p>
<div class="highlight-console notranslate"><div class="highlight"><pre><span></span><span class="go">sp: 10005e50</span>
<span class="go">User stack:</span>
<span class="go"> base: 10005ed8</span>
<span class="go"> size: 00000f9c</span>
<span class="go">10005e40: 00000000 00000000 00000000 [1b02d587] 10004900 00000000 005b8d7f 00000000</span>
<span class="go">10005e60: 1a030f2e 00000000 00000000 00001388 00000000 00000005 10001994 00000000</span>
<span class="go">10005e80: 00000000 00000000 00000000 [1b02c359] 00000000 00000000 00000000 004c4b40</span>
<span class="go">10005ea0: 000002ff 00000000 00000000 [1a030f2f] 00000000 00000000 00000000 00000000</span>
<span class="go">10005ec0: 00000000 [1a030f41] 00000000 [1b02c2a5] 00000000 00000000 ffffffff 00bdeb39</span>
</pre></div>
</div>
<p>That will give the full backtrace up to the point of the failure.</p>
</section>
<section id="the-interrupt-stack">
<h3>The Interrupt Stack<a class="headerlink" href="#the-interrupt-stack" title="Permalink to this heading"></a></h3>
<p>Note that in some cases there are two stacks listed. The interrupt
stack will be present if (1) the interrupt stack is enabled, and (2)
you are in an interrupt handler at the time that the failure occurred:</p>
<div class="highlight-console notranslate"><div class="highlight"><pre><span></span><span class="go">Assertion failed at file:armv7-m/up_hardfault.c line: 184 task: hpwork</span>
<span class="go">sp: 10001eb4</span>
<span class="go">IRQ stack:</span>
<span class="go"> base: 10001f00</span>
<span class="go"> size: 000003fc</span>
<span class="go">10001ea0: [1b02d961] 1b03f07e 10001eb4 10005ed8 1a0312ab 1b03f600 000000b8 [1b02d961]</span>
<span class="go">10001ec0: 00000010 10001f40 00000003 00000000 [1a03721d] [1a037209] [1b02d93b] 00000000</span>
<span class="go">10001ee0: [1a0371f5] 00000000 00000000 00000000 00000000 00000000 [1a0314a5] 10005d7c</span>
</pre></div>
</div>
<p>(Interesting addresses again in brackets).</p>
<p>The interrupt stack is sometimes interesting, for example when the
interrupt was caused by logic operating at the interrupt level. In
this case, it is probably not so interesting since fault was probably
caused by normal task code and the interrupt stack probably just shows
the normal operation of the interrupt handling logic.</p>
</section>
<section id="full-stack-analysis">
<h3>Full Stack Analysis<a class="headerlink" href="#full-stack-analysis" title="Permalink to this heading"></a></h3>
<p>What I have proposed here is just skimming through the stack, finding
and interpreting interesting addresses. Sometimes you need more
information and you need to analyze the stack in more detail. That is
also possible because every word on the stack is there because of an
explicit push instruction in the code (usually a push instruction on
Cortex-M or an stmdb instruction in other ARM architectures). This is
painstaking work but can also be done to provide a more detailed
answer to “what happened?”</p>
</section>
</section>
<section id="recovering-state-at-the-time-of-the-hardfault">
<h2>Recovering State at the Time of the Hardfault<a class="headerlink" href="#recovering-state-at-the-time-of-the-hardfault" title="Permalink to this heading"></a></h2>
<p>Here is another tip from Mike Smith:</p>
<blockquote class="epigraph">
<div><p>“… for systems like NuttX where catching hardfaults is difficult,
you can recover the faulting PC, LR and SP (by examining the
exception stack), then write these values back into the appropriate
processor registers (adjust the PC as necessary for the fault).</p>
<p>“This will put you back in the application code at the point at
which the fault occurred. Some local variables will show as having
invalid values (because at the time of the fault they were live in
registers and have been overwritten by the exception handler), but
the stack frame, function arguments etc. should all show correctly.”</p>
</div></blockquote>
</section>
</section>
</div>
</div>
<footer><div class="rst-footer-buttons" role="navigation" aria-label="Footer">
<a href="nestedinterrupts.html" class="btn btn-neutral float-left" title="Nested Interrupts" accesskey="p" rel="prev"><span class="fa fa-arrow-circle-left" aria-hidden="true"></span> Previous</a>
<a href="coredump.html" class="btn btn-neutral float-right" title="Core Dump" accesskey="n" rel="next">Next <span class="fa fa-arrow-circle-right" aria-hidden="true"></span></a>
</div>
<hr/>
<div role="contentinfo">
<p>&#169; Copyright 2020, The Apache Software Foundation.</p>
</div>
</footer>
</div>
</div>
</section>
</div>
<script>
jQuery(function () {
SphinxRtdTheme.Navigation.enable(true);
});
</script>
</body>
</html>