mirror of
https://github.com/apache/nuttx.git
synced 2026-05-23 06:39:01 +08:00
Documentation: move debug pages to a separate top level page
Move debug related pages from Guides to a separate top level page. This way all pages related to debugging will be in one place which is more user friendly. Related Github issue: https://github.com/apache/nuttx/issues/15667 Signed-off-by: raiden00pl <raiden00@railab.me>
This commit is contained in:
@@ -0,0 +1,84 @@
|
||||
==============================
|
||||
Debugging ELF Loadable Modules
|
||||
==============================
|
||||
|
||||
.. warning::
|
||||
Migrated from:
|
||||
https://cwiki.apache.org/confluence/display/NUTTX/Debugging+ELF+Loadable+Modules
|
||||
|
||||
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:
|
||||
|
||||
1. Get ELF Module Load Address
|
||||
==============================
|
||||
|
||||
Put a change in ``nuttx/binfmt`` so that you print the address where the ELF
|
||||
text was loaded into memory.
|
||||
|
||||
Turning on BINFMT debug (``CONFIG_DEBUG_BINFMT=y``) should give you the same
|
||||
information, although it may also provide more output than you really want.
|
||||
|
||||
Alternatively, you could place a ``printf()`` at the beginning of your ``main()``
|
||||
function so that your ELF module can print its own load address. For example,
|
||||
the difference between the address of ``main()`` in your object file and the
|
||||
address of ``main()`` at run time reveals the actual load address.
|
||||
|
||||
2. Make the ELF Module Wait for You
|
||||
===================================
|
||||
|
||||
Insert an infinite loop in the ``main()`` routine of your ELF program. For
|
||||
example:
|
||||
|
||||
.. code-block:: c
|
||||
|
||||
volatile bool waitforme;
|
||||
int main (int arc, char **argv)
|
||||
{
|
||||
while (!waitforme);
|
||||
...
|
||||
|
||||
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 ``waitforme`` to become true before proceeding.
|
||||
|
||||
3. Start the Debugger
|
||||
=====================
|
||||
|
||||
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 ``main()``.
|
||||
|
||||
4. Load Offset Symbols
|
||||
======================
|
||||
|
||||
Load symbols using the offset where the ELF module was loaded:
|
||||
|
||||
.. code-block:: shell
|
||||
|
||||
(gdb) add-symbol-file <myprogram> <load-address>
|
||||
|
||||
Here, ``<myprogram>`` is your ELF file containing symbols, and
|
||||
``<load-address>`` 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.
|
||||
|
||||
5. And Debug
|
||||
============
|
||||
|
||||
Set ``waitforme`` 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.
|
||||
|
||||
An Easier Way?
|
||||
==============
|
||||
|
||||
There might be an alternative that allows you to step into the ELF module
|
||||
without modifying the code to include the ``waitforme`` loop. You could place a
|
||||
breakpoint on the OS function ``task_start()``. 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.
|
||||
|
||||
When you step into the application's ``main()``, you have the relocated address
|
||||
of ``main()`` and can use that address (see step #1) to compute the load offset.
|
||||
Reference in New Issue
Block a user