blob: e7bc39517f737c7b15764b45ae70b6f3a079101f [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.19: https://docutils.sourceforge.io/" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Debugging ELF Loadable Modules &mdash; NuttX latest documentation</title>
<link rel="stylesheet" type="text/css" href="../_static/pygments.css" />
<link rel="stylesheet" type="text/css" href="../_static/css/theme.css" />
<link rel="stylesheet" type="text/css" href="../_static/copybutton.css" />
<link rel="stylesheet" type="text/css" href="../_static/design-style.1e8bd061cd6da7fc9cf755528e8ffc24.min.css" />
<link rel="stylesheet" type="text/css" href="../_static/custom.css" />
<link rel="shortcut icon" href="../_static/favicon.ico"/>
<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/design-tabs.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="Task Trace" href="tasktrace.html" />
<link rel="prev" title="gdbserver" href="gdbserver.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>
<option value="../../12.6.0" >12.6.0</option>
<option value="../../12.7.0" >12.7.0</option>
<option value="../../12.8.0" >12.8.0</option>
<option value="../../12.9.0" >12.9.0</option>
<option value="../../12.10.0" >12.10.0</option>
<option value="../../12.11.0" >12.11.0</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="../implementation/index.html">Implementation Details</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">Debugging</a><ul class="current">
<li class="toctree-l2"><a class="reference internal" href="gdbwithpython.html">GDB with Python</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="gdbserver.html">gdbserver</a></li>
<li class="toctree-l2 current"><a class="current reference internal" href="#">Debugging ELF Loadable Modules</a><ul>
<li class="toctree-l3"><a class="reference internal" href="#get-elf-module-load-address">1. Get ELF Module Load Address</a></li>
<li class="toctree-l3"><a class="reference internal" href="#make-the-elf-module-wait-for-you">2. Make the ELF Module Wait for You</a></li>
<li class="toctree-l3"><a class="reference internal" href="#start-the-debugger">3. Start the Debugger</a></li>
<li class="toctree-l3"><a class="reference internal" href="#load-offset-symbols">4. Load Offset Symbols</a></li>
<li class="toctree-l3"><a class="reference internal" href="#and-debug">5. And Debug</a></li>
<li class="toctree-l3"><a class="reference internal" href="#an-easier-way">An Easier Way?</a></li>
</ul>
</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="kasan.html">The Kernel Address Sanitizer (KASAN)</a></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="coresight.html">Coresight - HW Assisted Tracing on ARM</a></li>
<li class="toctree-l2"><a class="reference internal" href="stackcheck.html">Stack Overflow Check</a></li>
<li class="toctree-l2"><a class="reference internal" href="stackrecord.html">Run time stack statistics</a></li>
<li class="toctree-l2"><a class="reference internal" href="disabling_stackdumpdebug.html">Disabling the Stack Dump During Debugging</a></li>
<li class="toctree-l2"><a class="reference internal" href="debuggingflash_nuttxonarm.html">Debugging / flashing NuttX on ARM with hardware debugger (JTAG/SWD)</a></li>
<li class="toctree-l2"><a class="reference internal" href="cortexmhardfaults.html">Analyzing Cortex-M Hardfaults</a></li>
<li class="toctree-l2"><a class="reference internal" href="mte.html">ATM64 MTE extension</a></li>
</ul>
</li>
<li class="toctree-l1"><a class="reference internal" href="../guides/index.html">Guides</a></li>
<li class="toctree-l1"><a class="reference internal" href="../glossary.html">Glossary</a></li>
<li class="toctree-l1"><a class="reference internal" href="../logos/index.html">NuttX Logos</a></li>
<li class="toctree-l1"><a class="reference internal" href="../_tags/tagsindex.html">Tags</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">Debugging</a></li>
<li class="breadcrumb-item active">Debugging ELF Loadable Modules</li>
<li class="wy-breadcrumbs-aside">
<a href="https://github.com/apache/nuttx/blob/master/Documentation/debugging/debugging_elf_loadable_modules.rst" class="fa fa-github"> Edit on GitHub</a>
</li>
</ul>
<hr/>
</div>
<div role="main" class="document" itemscope="itemscope" itemtype="http://schema.org/Article">
<div itemprop="articleBody">
<section id="debugging-elf-loadable-modules">
<h1>Debugging ELF Loadable Modules<a class="headerlink" href="#debugging-elf-loadable-modules" title="Permalink to this heading"></a></h1>
<div class="admonition warning">
<p class="admonition-title">Warning</p>
<p>Migrated from:
<a class="reference external" href="https://cwiki.apache.org/confluence/display/NUTTX/Debugging+ELF+Loadable+Modules">https://cwiki.apache.org/confluence/display/NUTTX/Debugging+ELF+Loadable+Modules</a></p>
</div>
<p>Debugging ELF modules loaded in memory can be tricky because the load address
in memory does not match the addresses in the ELF file. This challenge has long
existed for debugging uClinux programs and Linux kernel modules; the same
solution can be used with NuttX ELF files (and probably with NxFLAT modules as
well). Below is a summary of one way to approach this:</p>
<section id="get-elf-module-load-address">
<h2>1. Get ELF Module Load Address<a class="headerlink" href="#get-elf-module-load-address" title="Permalink to this heading"></a></h2>
<p>Put a change in <code class="docutils literal notranslate"><span class="pre">nuttx/binfmt</span></code> so that you print the address where the ELF
text was loaded into memory.</p>
<p>Turning on BINFMT debug (<code class="docutils literal notranslate"><span class="pre">CONFIG_DEBUG_BINFMT=y</span></code>) should give you the same
information, although it may also provide more output than you really want.</p>
<p>Alternatively, you could place a <code class="docutils literal notranslate"><span class="pre">printf()</span></code> at the beginning of your <code class="docutils literal notranslate"><span class="pre">main()</span></code>
function so that your ELF module can print its own load address. For example,
the difference between the address of <code class="docutils literal notranslate"><span class="pre">main()</span></code> in your object file and the
address of <code class="docutils literal notranslate"><span class="pre">main()</span></code> at run time reveals the actual load address.</p>
</section>
<section id="make-the-elf-module-wait-for-you">
<h2>2. Make the ELF Module Wait for You<a class="headerlink" href="#make-the-elf-module-wait-for-you" title="Permalink to this heading"></a></h2>
<p>Insert an infinite loop in the <code class="docutils literal notranslate"><span class="pre">main()</span></code> routine of your ELF program. For
example:</p>
<div class="highlight-c notranslate"><div class="highlight"><pre><span></span><span class="k">volatile</span><span class="w"> </span><span class="kt">bool</span><span class="w"> </span><span class="n">waitforme</span><span class="p">;</span>
<span class="kt">int</span><span class="w"> </span><span class="nf">main</span><span class="w"> </span><span class="p">(</span><span class="kt">int</span><span class="w"> </span><span class="n">arc</span><span class="p">,</span><span class="w"> </span><span class="kt">char</span><span class="w"> </span><span class="o">**</span><span class="n">argv</span><span class="p">)</span>
<span class="p">{</span>
<span class="w"> </span><span class="k">while</span><span class="w"> </span><span class="p">(</span><span class="o">!</span><span class="n">waitforme</span><span class="p">);</span>
<span class="w"> </span><span class="p">...</span>
</pre></div>
</div>
<p>When you start the ELF program, you will see where it was loaded in memory, and
the ELF program will remain stuck in the infinite loop. It will continue to
wait for <code class="docutils literal notranslate"><span class="pre">waitforme</span></code> to become true before proceeding.</p>
</section>
<section id="start-the-debugger">
<h2>3. Start the Debugger<a class="headerlink" href="#start-the-debugger" title="Permalink to this heading"></a></h2>
<p>Start the debugger, connect to the GDB server, and halt the program. If your
debugger is well-behaved, it should stop at the infinite loop in <code class="docutils literal notranslate"><span class="pre">main()</span></code>.</p>
</section>
<section id="load-offset-symbols">
<h2>4. Load Offset Symbols<a class="headerlink" href="#load-offset-symbols" title="Permalink to this heading"></a></h2>
<p>Load symbols using the offset where the ELF module was loaded:</p>
<div class="highlight-shell notranslate"><div class="highlight"><pre><span></span><span class="o">(</span>gdb<span class="o">)</span><span class="w"> </span>add-symbol-file<span class="w"> </span>&lt;myprogram&gt;<span class="w"> </span>&lt;load-address&gt;
</pre></div>
</div>
<p>Here, <code class="docutils literal notranslate"><span class="pre">&lt;myprogram&gt;</span></code> is your ELF file containing symbols, and
<code class="docutils literal notranslate"><span class="pre">&lt;load-address&gt;</span></code> is the address where the program text was actually loaded (as
determined above). Single-step a couple of times and confirm that you are in the
infinite loop.</p>
</section>
<section id="and-debug">
<h2>5. And Debug<a class="headerlink" href="#and-debug" title="Permalink to this heading"></a></h2>
<p>Set <code class="docutils literal notranslate"><span class="pre">waitforme</span></code> to a non-zero value. Execution should exit the infinite loop,
and now you can debug the ELF program loaded into RAM in the usual way.</p>
</section>
<section id="an-easier-way">
<h2>An Easier Way?<a class="headerlink" href="#an-easier-way" title="Permalink to this heading"></a></h2>
<p>There might be an alternative that allows you to step into the ELF module
without modifying the code to include the <code class="docutils literal notranslate"><span class="pre">waitforme</span></code> loop. You could place a
breakpoint on the OS function <code class="docutils literal notranslate"><span class="pre">task_start()</span></code>. That function runs before your
ELF program starts, so you should be able to single-step from the OS code
directly into your loaded ELF application—no changes to the ELF application
required.</p>
<p>When you step into the application’s <code class="docutils literal notranslate"><span class="pre">main()</span></code>, you have the relocated address
of <code class="docutils literal notranslate"><span class="pre">main()</span></code> and can use that address (see step #1) to compute the load offset.</p>
</section>
</section>
</div>
</div>
<footer><div class="rst-footer-buttons" role="navigation" aria-label="Footer">
<a href="gdbserver.html" class="btn btn-neutral float-left" title="gdbserver" accesskey="p" rel="prev"><span class="fa fa-arrow-circle-left" aria-hidden="true"></span> Previous</a>
<a href="tasktrace.html" class="btn btn-neutral float-right" title="Task Trace" 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 2023, The Apache Software Foundation.</p>
</div>
</footer>
</div>
</div>
</section>
</div>
<script>
jQuery(function () {
SphinxRtdTheme.Navigation.enable(true);
});
</script>
</body>
</html>