diff --git a/docs/en/api-guides/core_dump.rst b/docs/en/api-guides/core_dump.rst index 0b3a156b7d..b826e28842 100644 --- a/docs/en/api-guides/core_dump.rst +++ b/docs/en/api-guides/core_dump.rst @@ -1,99 +1,87 @@ Core Dump ========= +:link_to_translation:`zh_CN:[中文]` + Overview -------- -ESP-IDF provides support to generate core dumps on unrecoverable software errors. This useful technique allows post-mortem analysis of software state at the moment of failure. -Upon the crash system enters panic state, prints some information and halts or reboots depending configuration. User can choose to generate core dump in order to analyse -the reason of failure on PC later on. Core dump contains snapshots of all tasks in the system at the moment of failure. Snapshots include tasks control blocks (TCB) and stacks. -So it is possible to find out what task, at what instruction (line of code) and what callstack of that task lead to the crash. It is also possible dumping variables content on -demand if previously attributed accordingly. -ESP-IDF provides special commands to help users to retrieve and analyse core dumps: +A core dump is a set of software state information that is automatically saved by the panic handler when a fatal error occurs. Core dumps are useful for conducting post-mortem analysis of the software's state at the moment of failure. ESP-IDF provides support for generating core dumps. -* ``idf.py coredump-info`` - prints crashed task's registers, callstack, list of available tasks in the system, memory regions and contents of memory stored in core dump (TCBs and stacks) -* ``idf.py coredump-debug`` - creates core dump ELF file and runs GDB debug session with this file. User can examine memory, variables and tasks states manually. Note that since not all memory is saved in core dump only values of variables allocated on stack will be meaningful +A core dump contains snapshots of all tasks in the system at the moment of failure, where each snapshot includes a task's control block (TCB) and stack. By analyzing the task snapshots, it is possible to find out what task, at what instruction (line of code), and what call stack of that task lead to the crash. It is also possible to dump the contents of variables on demand, provided those variables are assigned special core dump attributes. -For more information about core dump internals see the - :doc:`Core dump internals ` +Core dump data is saved to a core dump file according to a particular format, see :doc:`Core dump internals ` for more details. However, ESP-IDF's ``idf.py`` command provides special subcommands to decode and analyze the core dump file. Configurations -------------- -There are a number of core dump related configuration options which user can choose in project configuration menu (``idf.py menuconfig``). +Destination +^^^^^^^^^^^ -**Core dump data destination (Components -> Core dump -> Data destination)** +The :ref:`CONFIG_ESP_COREDUMP_TO_FLASH_OR_UART` option enables or disables core dump, and selects the core dump destination if enabled. When a crash occurs, the generated core dump file can either be saved to flash, or output to a connected host over UART. - * Save core dump to Flash (Flash) - * Print core dump to UART (UART) - * Disable core dump generation (None) +Format & Size +^^^^^^^^^^^^^ -**Core dump data format (Components -> Core dump -> Core dump data format)** +The :ref:`CONFIG_ESP_COREDUMP_DATA_FORMAT` option controls the format of the core dump file, namely ELF format or Binary format. - * ELF format (Executable and Linkable Format file for core dump) - * Binary format (Basic binary format for core dump) +The ELF format contains extended features and allows more information regarding erroneous tasks and crashed software to be saved. However, using the ELF format causes the core dump file to be larger. This format is recommended for new software designs and is flexible enough to be extended in future revisions to save more information. - The ELF format contains extended features and allow to save more information about broken tasks and crashed software but it requires more space in the flash memory. - This format of core dump is recommended for new software designs and is flexible enough to extend saved information for future revisions. +The Binary format is kept for compatibility reasons. Binary format core dump files are smaller while provide better performance. - The Binary format is kept for compatibility reasons, it uses less space in the memory to keep data and provides better performance. +The :ref:`CONFIG_ESP_COREDUMP_MAX_TASKS_NUM` option configures the number of task snapshots saved by the core dump. -**Core dump data integrity check (Components -> Core dump -> Core dump data integrity check)** +Core dump data integrity checking is supported via the ``Components`` > ``Core dump`` > ``Core dump data integrity check`` option. - .. only:: esp32 +.. only:: esp32 - * Use CRC32 for core dump integrity verification - * Use SHA256 for core dump integrity verification (only work in ELF format) + Data Integrity Check + ^^^^^^^^^^^^^^^^^^^^ - The CRC32 option provides better calculation performance and consumes less memory for storage. + Core dump files include a checksum, which can be used to verify the integrity of the core dump file, i.e., the file has not been corrupted. The :ref:`CONFIG_ESP_COREDUMP_CHECKSUM` option controls the type of checksum, namely CRC32 or SHA256 (only supported in the ELF format). - The SHA256 hash algorithm provides greater probability of detecting corruption than a CRC32 with multiple bit errors. + The CRC32 option provides better calculation performance and consumes less memory for storage. - .. only:: not esp32 + The SHA256 hash algorithm provides a greater probability of detecting corruption than a CRC32 with multiple-bit errors. - * Use CRC32 for core dump integrity verification +Reserved Stack Size +^^^^^^^^^^^^^^^^^^^ -**Maximum number of tasks snapshots in core dump (Components -> Core dump -> Maximum number of tasks)** +Core dump routines run from a separate stack due to core dump itself needing to parse and save all other task stacks. The :ref:`CONFIG_ESP_COREDUMP_STACK_SIZE` option controls the size of the core dump's stack in number of bytes. -**Delay before core dump is printed to UART (Components -> Core dump -> Delay before print to UART)** +Setting this option to 0 bytes will cause the core dump routines to run from the ISR stack, thus saving a bit of memory. Setting the option greater than zero will cause a separate stack to be instantiated. - The value is in ms. +.. note:: -**Handling of UART core dumps in IDF Monitor (Components -> Core dump -> Delay before print to UART)** + If a separate stack is used, the recommended stack size should be larger than 800 bytes to ensure that the core dump routines themselves do not cause a stack overflow. - The value is base64 encoded. +Core Dump to Flash +------------------ - * Decode and show summary (info_corefile) - * Don't decode +When the core dump file is saved to flash, the file is saved to a special core dump partition in flash. Specifying the core dump partition will reserve space on the flash chip to store the core dump file. -**Reserved stack size (Components -> Core dump -> Reserved stack size)** +The core dump partition is automatically declared when using the default partition table provided by ESP-IDF. However, when using a custom partition table, you need to declare the core dump partition, as illustrated below: - Size of the memory to be reserved for core dump stack. If 0 core dump process will run on the stack of crashed task/ISR, otherwise special stack will be allocated. - To ensure that core dump itself will not overflow task/ISR stack set this to the value above 800. +.. code-block:: none -Save core dump to flash ------------------------ - -When this option is selected core dumps are saved to special partition on flash. When using default partition table files which are provided with ESP-IDF it automatically -allocates necessary space on flash, But if user wants to use its own layout file together with core dump feature it should define separate partition for core dump -as it is shown below:: - - # Name, Type, SubType, Offset, Size - # Note: if you have increased the bootloader size, make sure to update the offsets to avoid overlap - nvs, data, nvs, 0x9000, 0x6000 - phy_init, data, phy, 0xf000, 0x1000 - factory, app, factory, 0x10000, 1M - coredump, data, coredump,, 64K + # Name, Type, SubType, Offset, Size + # Note: if you have increased the bootloader size, make sure to update the offsets to avoid overlap + nvs, data, nvs, 0x9000, 0x6000 + phy_init, data, phy, 0xf000, 0x1000 + factory, app, factory, 0x10000, 1M + coredump, data, coredump,, 64K .. important:: - If :doc:`Flash Encryption <../security/flash-encryption>` is enabled on the device then please add `encrypted` flag to the coredump partition:: + + If :doc:`../security/flash-encryption` is enabled on the device, please add an ``encrypted`` flag to the core dump partition declaration. + + .. code-block:: none coredump, data, coredump,, 64K, encrypted -There are no special requirements for partition name. It can be chosen according to the user application needs, but partition type should be 'data' and -sub-type should be 'coredump'. Also when choosing partition size note that core dump data structure introduces constant overhead of 20 bytes and per-task overhead of 12 bytes. -This overhead does not include size of TCB and stack for every task. So partition size should be at least 20 + max tasks number x (12 + TCB size + max task stack size) bytes. +There are no special requirements for the partition name. It can be chosen according to the application's needs, but the partition type should be ``data`` and the sub-type should be ``coredump``. Also, when choosing partition size, note that the core dump file introduces a constant overhead of 20 bytes and a per-task overhead of 12 bytes. This overhead does not include the size of TCB and stack for every task. So the partition size should be at least ``20 + max tasks number x (12 + TCB size + max task stack size)`` bytes. -The example of generic command to analyze core dump from flash is: +An example of the generic command to analyze core dump from flash is: .. code-block:: bash @@ -105,11 +93,69 @@ or idf.py coredump-debug -Print core dump to UART ------------------------ +Core Dump to UART +----------------- -When this option is selected base64-encoded core dumps are printed on UART upon system panic. In this case user should save core dump text body to some file manually and -then run the following command: +When the core dump file is output to UART, the output file is Base64-encoded. The :ref:`CONFIG_ESP_COREDUMP_DECODE` option allows for selecting whether the output file is automatically decoded by the ESP-IDF monitor or kept encoded for manual decoding. + +Automatic Decoding +^^^^^^^^^^^^^^^^^^ + +If :ref:`CONFIG_ESP_COREDUMP_DECODE` is set to automatically decode the UART core dump, ESP-IDF monitor will automatically decode the data, translate any function addresses to source code lines, and display it in the monitor. The output to ESP-IDF monitor would resemble the following output: + +The :ref:`CONFIG_ESP_COREDUMP_UART_DELAY` allows for an optional delay to be added before the core dump file is output to UART. + +.. code-block:: none + + =============================================================== + ==================== ESP32 CORE DUMP START ==================== + + Crashed task handle: 0x3ffc5640, name: 'main', GDB name: 'process 1073501760' + + ================== CURRENT THREAD REGISTERS =================== + exccause 0x1d (StoreProhibitedCause) + excvaddr 0x0 + epc1 0x40027657 + epc2 0x0 + ... + ==================== CURRENT THREAD STACK ===================== + #0 0x400251cd in panic_abort (details=0x3ffc553b "abort() was called at PC 0x40087b84 on core 0") at /home/User/esp/esp-idf/components/esp_system/panic.c:452 + #1 0x40028970 in esp_system_abort (details=0x3ffc553b "abort() was called at PC 0x40087b84 on core 0") at /home/User/esp/esp-idf/components/esp_system/port/esp_system_chip.c:93 + ... + ======================== THREADS INFO ========================= + Id Target Id Frame + * 1 process 1073501760 0x400251cd in panic_abort (details=0x3ffc553b "abort() was called at PC 0x40087b84 on core 0") at /home/User/esp/esp-idf/components/esp_system/panic.c:452 + 2 process 1073503644 vPortTaskWrapper (pxCode=0x0, pvParameters=0x0) at /home/User/esp/esp-idf/components/freertos/FreeRTOS-Kernel/portable/xtensa/port.c:161 + ... + ==================== THREAD 1 (TCB: 0x3ffc5640, name: 'main') ===================== + #0 0x400251cd in panic_abort (details=0x3ffc553b "abort() was called at PC 0x40087b84 on core 0") at /home/User/esp/esp-idf/components/esp_system/panic.c:452 + #1 0x40028970 in esp_system_abort (details=0x3ffc553b "abort() was called at PC 0x40087b84 on core 0") at /home/User/esp/esp-idf/components/esp_system/port/esp_system_chip.c:93 + ... + ==================== THREAD 2 (TCB: 0x3ffc5d9c, name: 'IDLE') ===================== + #0 vPortTaskWrapper (pxCode=0x0, pvParameters=0x0) at /home/User/esp/esp-idf/components/freertos/FreeRTOS-Kernel/portable/xtensa/port.c:161 + #1 0x40000000 in ?? () + ... + ======================= ALL MEMORY REGIONS ======================== + Name Address Size Attrs + ... + .iram0.vectors 0x40024000 0x403 R XA + .dram0.data 0x3ffbf1c0 0x2c0c RW A + ... + ===================== ESP32 CORE DUMP END ===================== + =============================================================== + +Manual Decoding +^^^^^^^^^^^^^^^ + +If you set :ref:`CONFIG_ESP_COREDUMP_DECODE` to no decoding, then the raw Base64-encoded body of core dump is output to UART between the following header and footer of the UART output: + +.. code-block:: none + + ================= CORE DUMP START ================= + + ================= CORE DUMP END =================== + +It is advised to manually save the core dump text body to a file. The ``CORE DUMP START`` and ``CORE DUMP END`` lines must not be included in a core dump text file. The saved text can the be decoded using the following command: .. code-block:: bash @@ -121,57 +167,59 @@ or idf.py coredump-debug -c -Base64-encoded body of core dump will be between the following header and footer:: - ================= CORE DUMP START ================= - - ================= CORE DUMP END =================== +Core Dump Commands +------------------ + +ESP-IDF provides special commands to help to retrieve and analyze core dumps: + +* ``idf.py coredump-info`` - prints crashed task's registers, call stack, list of available tasks in the system, memory regions, and contents of memory stored in core dump (TCBs and stacks). +* ``idf.py coredump-debug`` - creates core dump ELF file and runs GDB debug session with this file. You can examine memory, variables, and task states manually. Note that since not all memory is saved in the core dump, only the values of variables allocated on the stack are meaningful. -The ``CORE DUMP START`` and ``CORE DUMP END`` lines must not be included in core dump text file. ROM Functions in Backtraces --------------------------- -It is possible situation that at the moment of crash some tasks or/and crashed task itself have one or more ROM functions in their callstacks. -Since ROM is not part of the program ELF it will be impossible for GDB to parse such callstacks, because it tries to analyse functions' prologues to accomplish that. -In that case callstack printing will be broken with error message at the first ROM function. -To overcome this issue, `ROM ELF `_ provided by Espressif is loaded automatically based on the target and its revision. More details about ROM ELFs can be found `here `_. +It is a possible that at the moment of a crash, some tasks and/or the crashed task itself have one or more ROM functions in their call stacks. Since ROM is not part of the program ELF, it is impossible for GDB to parse such call stacks due to GDB analyzing functions' prologues to decode backtraces. Thus, call stack parsing will break with an error message upon the first ROM function that is encountered. -Dumping variables on demand +To overcome this issue, the `ROM ELF `_ provided by Espressif is loaded automatically by ESP-IDF monitor based on the target and its revision. More details about ROM ELFs can be found in `esp-rom-elfs `_. + + +Dumping Variables on Demand --------------------------- -Sometimes you want to read the last value of a variable to understand the root cause of a crash. -Core dump supports retrieving variable data over GDB by attributing special notations declared variables. +Sometimes you want to read the last value of a variable to understand the root cause of a crash. Core dump supports retrieving variable data over GDB by applying special attributes to declared variables. -Supported notations and RAM regions + +Supported Notations and RAM Regions ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ .. list:: - * ``COREDUMP_DRAM_ATTR`` places variable into DRAM area which will be included into dump. - :SOC_RTC_FAST_MEM_SUPPORTED or SOC_RTC_SLOW_MEM_SUPPORTED: * ``COREDUMP_RTC_ATTR`` places variable into RTC area which will be included into dump. - :SOC_RTC_FAST_MEM_SUPPORTED: * ``COREDUMP_RTC_FAST_ATTR`` places variable into RTC_FAST area which will be included into dump. + * ``COREDUMP_DRAM_ATTR`` places the variable into the DRAM area, which is included in the dump. + :SOC_RTC_FAST_MEM_SUPPORTED or SOC_RTC_SLOW_MEM_SUPPORTED: * ``COREDUMP_RTC_ATTR`` places the variable into the RTC area, which is included in the dump. + :SOC_RTC_FAST_MEM_SUPPORTED: * ``COREDUMP_RTC_FAST_ATTR`` places the variable into the RTC_FAST area, which is included in the dump. Example ^^^^^^^ 1. In :ref:`project-configuration-menu`, enable :ref:`COREDUMP TO FLASH `, then save and exit. -2. In your project, create a global variable in DRAM area as such as: +2. In your project, create a global variable in the DRAM area, such as: .. code-block:: bash // uint8_t global_var; COREDUMP_DRAM_ATTR uint8_t global_var; -3. In main application, set the variable to any value and ``assert(0)`` to cause a crash. +3. In the main application, set the variable to any value and ``assert(0)`` to cause a crash. .. code-block:: bash global_var = 25; assert(0); -4. Build, flash and run the application on a target device and wait for the dumping information. +4. Build, flash, and run the application on a target device and wait for the dumping information. 5. Run the command below to start core dumping in GDB, where ``PORT`` is the device USB port: @@ -189,7 +237,7 @@ Example Running ``idf.py coredump-info`` and ``idf.py coredump-debug`` -------------------------------------------------------------- -``idf.py coredump-info --help`` and ``idf.py coredump-debug --help`` commands can be used to get more details on usage +``idf.py coredump-info --help`` and ``idf.py coredump-debug --help`` commands can be used to get more details on usage. Related Documents ^^^^^^^^^^^^^^^^^ diff --git a/docs/en/api-guides/core_dump_internals.rst b/docs/en/api-guides/core_dump_internals.rst index 4000a1d2f2..e95a51cfc7 100644 --- a/docs/en/api-guides/core_dump_internals.rst +++ b/docs/en/api-guides/core_dump_internals.rst @@ -1,38 +1,46 @@ -Anatomy of core dump image +Anatomy of Core Dump Image -------------------------- -Core dump component can be configured to use old legacy binary format or the new ELF one. The ELF format is recommended for new designs. It provides more information about the CPU and memory state of a program at the moment when panic handler is entered. -The memory state embeds a snapshot of all tasks mapped in the memory space of the program. The CPU state contains register values when the core dump has been generated. Core dump file uses a subset of the ELF structures to register these information. -Loadable ELF segments are used for the memory state of the process while ELF notes (ELF.PT_NOTE) are used for process metadata (pid, registers, signal, ...). Especially, the CPU status is stored in a note with a special name and type (``CORE``, ``NT_PRSTATUS type``). +:link_to_translation:`zh_CN:[中文]` -Here is an overview of coredump layout: +A core dump file's format can be configured to use the ELF format, or a legacy binary format. The ELF format is recommended for all new designs as it provides more information regarding the software's state at the moment the crash occurs, e.g., CPU registers and memory contents. + +The memory state embeds a snapshot of all tasks mapped in the memory space of the program. The CPU state contains register values when the core dump has been generated. The core dump file uses a subset of the ELF structures to register this information. + +Loadable ELF segments are used to store the process' memory state, while ELF notes (``ELF.PT_NOTE``) are used to store the process' metadata (e.g., PID, registers, signal etc). In particular, the CPU's status is stored in a note with a special name and type (``CORE``, ``NT_PRSTATUS type``). + +Here is an overview of the core dump layout: .. figure:: ../../_static/core_dump_format_elf.png :align: center - :alt: Core dump image format + :alt: Core Dump ELF Image Format :figclass: align-center - Core dump ELF image format + Core Dump ELF Image Format .. figure:: ../../_static/core_dump_format_bin.png :align: center - :alt: Core dump binary image format + :alt: Core Dump Binary Image Format :figclass: align-center - Core dump binary image format + Core Dump Binary Image Format -Note: The format of image file showed on the above pictures represents current version of image and can be changed in future releases. +.. note:: -Overview of implementation + The format of the image file shown in the above pictures represents the current version of the image and can be changed in future releases. + +Overview of Implementation -------------------------- -The figure below describes some basic aspects related to implementation of core dump: +The figure below describes some basic aspects related to the implementation of the core dump: .. figure:: ../../_static/core_dump_impl.png :align: center - :alt: Core dump implementation overview + :alt: Core Dump Implementation Overview :figclass: align-center - Core dump implementation overview + Core Dump Implementation Overview -Note: The diagram above hide some details and represents current implementation of the core dump and can be changed later. \ No newline at end of file +.. note:: + + The diagram above hides some details and represents the current implementation of the core dump which can be changed later. \ No newline at end of file diff --git a/docs/zh_CN/api-guides/core_dump.rst b/docs/zh_CN/api-guides/core_dump.rst index 5acbd83246..ed18e49f15 100644 --- a/docs/zh_CN/api-guides/core_dump.rst +++ b/docs/zh_CN/api-guides/core_dump.rst @@ -1 +1,248 @@ -.. include:: ../../en/api-guides/core_dump.rst \ No newline at end of file +核心转储 +========= + +:link_to_translation:`en:[English]` + +概述 +-------- + +核心转储是软件发生致命错误时,由紧急处理程序自动保存的一组软件状态信息。核心转储有助于对故障进行事后分析,了解软件状态。ESP-IDF 支持生成核心转储。 + +核心转储包含了系统中所有任务在发生故障时的快照,每个快照都包括任务的控制块 (TCB) 和栈信息。通过分析任务快照,可以确定是哪个任务、在哪个指令(代码行),以及该任务的哪个调用栈导致了系统崩溃。如果将某些变量赋予特殊的核心转储属性,还可以转储这些变量的内容。 + +核心转储数据会按照特定格式保存在核心转储文件中,详情请参阅 :doc:`core_dump_internals`。然而,ESP-IDF 的 ``idf.py`` 命令提供了专门的子命令,用于解码和分析核心转储文件。 + +配置 +-------------- + +目标 +^^^^^^^^^^^ + +选项 :ref:`CONFIG_ESP_COREDUMP_TO_FLASH_OR_UART` 可以启用或禁用核心转储,并在启用时选择核心转储的目标。发生崩溃时,生成的核心转储文件可以保存到 flash 中,也可以通过 UART 输出到连接的主机上。 + +格式和大小 +^^^^^^^^^^^^^ + +选项 :ref:`CONFIG_ESP_COREDUMP_DATA_FORMAT` 控制核心转储文件格式,即 ELF 格式或二进制格式。 + +ELF 格式具备扩展特性,支持在发生崩溃时保存更多关于错误任务和崩溃软件的信息,但使用 ELF 格式会使核心转储文件变大。建议在新的软件设计中使用此格式,该格式足够灵活,可以在未来的修订版本中进行扩展,保存更多信息。 + +出于兼容性考虑,核心转储文件保留二进制格式。二进制格式的核心转储文件更小,性能更优。 + +选项 :ref:`CONFIG_ESP_COREDUMP_MAX_TASKS_NUM` 配置核心转储保存的任务快照数量。 + +通过 ``Components`` > ``Core dump`` > ``Core dump data integrity check`` 选项可进行核心转储数据完整性检查。 + +.. only:: esp32 + + 数据完整性检查 + ^^^^^^^^^^^^^^^^^^^^ + + 核心转储文件包含一个校验和,用于验证核心转储文件在保存时是否完整(即未损坏)。选项 :ref:`CONFIG_ESP_COREDUMP_CHECKSUM` 控制校验和的类型,即 CRC32 或 SHA256(仅在 ELF 格式中支持)。 + + CRC32 选项能够提供更好的计算性能,在存储时占用内存较少。 + + SHA256 哈希算法检测到损坏的概率高于具有多位错误的 CRC32。 + +保留栈大小 +^^^^^^^^^^^^^^^^^^^ + +核心转储例程需要解析并保存所有其他任务的栈,因此会从单独的栈中运行。选项 :ref:`CONFIG_ESP_COREDUMP_STACK_SIZE` 控制核心转储栈大小,以字节数表示。 + +将此选项设置为 0 字节将使核心转储例程从 ISR 栈中运行,从而节省内存。将选项设置为大于零的值将创建一个独立的栈。 + +.. note:: + + 如果使用了独立的栈,建议栈大小应大于 800 字节,确保核心转储例程本身不会导致栈溢出。 + +将核心转储保存到 flash +----------------------- + +将核心转储文件保存至 flash 时,这些文件会保存到 flash 上的特殊分区。指定核心转储分区可以在 flash 芯片上预留空间来存储核心转储文件。 + +使用 ESP-IDF 提供的默认分区表时,核心转储分区会自动声明。但使用自定义分区表时,请按如下示例进行核心转储分区声明: + +.. code-block:: none + + # 名称, 类型,子类型, 偏移量, 大小 + # 注意:如果增加了引导加载程序大小,请及时更新偏移量,避免产生重叠 + nvs, data, nvs, 0x9000, 0x6000 + phy_init, data, phy, 0xf000, 0x1000 + factory, app, factory, 0x10000, 1M + coredump, data, coredump,, 64K + +.. important:: + + 如果设备启用了 :doc:`../security/flash-encryption`,请在核心转储分区中添加 ``encrypted`` 标志。 + + .. code-block:: none + + coredump, data, coredump,, 64K, encrypted + +分区命名没有特殊要求,可以根据应用程序的需要选择。但分区类型应为 ``data``,子类型应为 ``coredump``。此外,在选择分区大小时需注意,核心转储的数据结构会产生 20 字节的固定开销和 12 字节的单任务开销,此开销不包括每个任务的 TCB 和栈的大小。因此,分区大小应至少为 ``20 + 最大任务数 x(12 + TCB 大小 + 最大任务栈大小)`` 字节。 + +用于分析 flash 中核心转储的常用命令,可参考以下示例: + +.. code-block:: bash + + idf.py coredump-info + +或 + +.. code-block:: bash + + idf.py coredump-debug + +将核心转储保存到 UART +----------------------- + +当核心转储文件输出到 UART 时,输出文件会以 Base64 编码方式呈现。通过 :ref:`CONFIG_ESP_COREDUMP_DECODE` 选项,可以选择 ESP-IDF 监视器对输出文件自动解码,或保持编码状态等待手动解码。 + +自动解码 +^^^^^^^^^^^^^^^^^^ + +如果设置 :ref:`CONFIG_ESP_COREDUMP_DECODE`,使其自动解码 UART 核心转储文件,ESP-IDF 监视器会自动解码数据,将所有函数地址转换为源代码行,并在监视器中显示相应信息。ESP-IDF 监视器会输出类似以下内容: + +此外,选项 :ref:`CONFIG_ESP_COREDUMP_UART_DELAY` 支持在将核心转储文件输出到 UART 前添加延迟。 + +.. code-block:: none + + =============================================================== + ==================== ESP32 CORE DUMP START ==================== + + Crashed task handle: 0x3ffc5640, name: 'main', GDB name: 'process 1073501760' + + ================== CURRENT THREAD REGISTERS =================== + exccause 0x1d (StoreProhibitedCause) + excvaddr 0x0 + epc1 0x40027657 + epc2 0x0 + ... + ==================== CURRENT THREAD STACK ===================== + #0 0x400251cd in panic_abort (details=0x3ffc553b "abort() was called at PC 0x40087b84 on core 0") at /home/User/esp/esp-idf/components/esp_system/panic.c:452 + #1 0x40028970 in esp_system_abort (details=0x3ffc553b "abort() was called at PC 0x40087b84 on core 0") at /home/User/esp/esp-idf/components/esp_system/port/esp_system_chip.c:93 + ... + ======================== THREADS INFO ========================= + Id Target Id Frame + * 1 process 1073501760 0x400251cd in panic_abort (details=0x3ffc553b "abort() was called at PC 0x40087b84 on core 0") at /home/User/esp/esp-idf/components/esp_system/panic.c:452 + 2 process 1073503644 vPortTaskWrapper (pxCode=0x0, pvParameters=0x0) at /home/User/esp/esp-idf/components/freertos/FreeRTOS-Kernel/portable/xtensa/port.c:161 + ... + ==================== THREAD 1 (TCB: 0x3ffc5640, name: 'main') ===================== + #0 0x400251cd in panic_abort (details=0x3ffc553b "abort() was called at PC 0x40087b84 on core 0") at /home/User/esp/esp-idf/components/esp_system/panic.c:452 + #1 0x40028970 in esp_system_abort (details=0x3ffc553b "abort() was called at PC 0x40087b84 on core 0") at /home/User/esp/esp-idf/components/esp_system/port/esp_system_chip.c:93 + ... + ==================== THREAD 2 (TCB: 0x3ffc5d9c, name: 'IDLE') ===================== + #0 vPortTaskWrapper (pxCode=0x0, pvParameters=0x0) at /home/User/esp/esp-idf/components/freertos/FreeRTOS-Kernel/portable/xtensa/port.c:161 + #1 0x40000000 in ?? () + ... + ======================= ALL MEMORY REGIONS ======================== + Name Address Size Attrs + ... + .iram0.vectors 0x40024000 0x403 R XA + .dram0.data 0x3ffbf1c0 0x2c0c RW A + ... + ===================== ESP32 CORE DUMP END ===================== + =============================================================== + +手动解码 +^^^^^^^^^^^^^^^ + +如果设置 :ref:`CONFIG_ESP_COREDUMP_DECODE` 为不解码,则在以下 UART 输出的页眉和页脚之间,将输出核心转储的原始 Base64 编码正文: + +.. code-block:: none + + ================= CORE DUMP START ================= + <将 Base64 编码的核心转储内容解码,并将其保存到磁盘文件中> + ================= CORE DUMP END =================== + +建议将核心转储文本主体手动保存到文件,``CORE DUMP START`` 和 ``CORE DUMP END`` 行不应包含在核心转储文本文件中。随后,可以使用以下命令解码保存的文本: + +.. code-block:: bash + + idf.py coredump-info -c + +或 + +.. code-block:: bash + + idf.py coredump-debug -c + + +核心转储命令 +------------------ + +ESP-IDF 提供了一些特殊命令,有助于检索和分析核心转储: + +* ``idf.py coredump-info`` - 打印崩溃任务的寄存器、调用栈、系统可用任务列表、内存区域以及核心转储中存储的内存内容(包括 TCB 和栈)。 +* ``idf.py coredump-debug`` - 创建核心转储 ELF 文件,并使用该文件运行 GDB 调试会话。你可以手动检查内存、变量和任务状态。请注意,由于并未将所有内存保存在核心转储中,因此只有在栈上分配的变量的值才有意义。 + + +回溯中的 ROM 函数 +--------------------------- + +程序崩溃时,某些任务和/或崩溃任务本身的调用栈中可能包含一或多个 ROM 函数。由于 ROM 不是程序 ELF 的一部分,而 GDB 需要分析函数序言来解码回溯,因此 GDB 无法解析这些调用栈。因此,在遇到第一个 ROM 函数时,调用栈解析将中断并报错。 + +为解决这一问题,ESP-IDF 监视器会根据目标芯片及其修订版本自动加载乐鑫提供的 `ROM ELF `_。有关 ROM ELF 的详细信息,请参阅 `esp-rom-elfs `_。 + + +按需转储变量 +--------------------------- + +通过读取变量的最后一个值,可以了解崩溃发生的根本原因。核心转储支持通过为已声明的变量添加特殊标记,在 GDB 上检索变量数据。 + + +支持的标记和 RAM 区域 +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +.. list:: + + * ``COREDUMP_DRAM_ATTR`` 将变量放置在 DRAM 区域,该区域包含在转储中。 + :SOC_RTC_FAST_MEM_SUPPORTED or SOC_RTC_SLOW_MEM_SUPPORTED: * ``COREDUMP_RTC_ATTR`` 将变量放置在 RTC 区域,该区域包含在转储中。 + :SOC_RTC_FAST_MEM_SUPPORTED: * ``COREDUMP_RTC_FAST_ATTR`` 将变量放置在 RTC_FAST 区域,该区域包含在转储中。 + +示例 +^^^^^^^ + +1. 在 :ref:`project-configuration-menu` 中启用 :ref:`COREDUMP TO FLASH `,随后保存并退出。 + +2. 在项目中,创建如下全局变量,放置在 DRAM 区域: + +.. code-block:: bash + + // uint8_t global_var; + COREDUMP_DRAM_ATTR uint8_t global_var; + +3. 在主应用程序中,将该变量设置为任意值,并以 ``assert(0)`` 引发崩溃。 + +.. code-block:: bash + + global_var = 25; + assert(0); + +4. 在目标设备上构建、烧写并运行应用程序,等待转储信息。 + +5. 运行以下命令,在 GDB 中开始核心转储,其中 ``PORT`` 是设备的 USB 端口: + +.. code-block:: bash + + idf.py coredump-debug + +6. 在 GDB shell 中,输入 ``p global_var`` 获取变量内容: + +.. code-block:: bash + + (gdb) p global_var + $1 = 25 '\031' + +运行 ``idf.py coredump-info`` 和 ``idf.py coredump-debug`` +-------------------------------------------------------------- + +要获取更多有关使用方法的详情,请运行 ``idf.py coredump-info --help`` 和 ``idf.py coredump-debug --help`` 命令。 + +相关文档 +^^^^^^^^^^^^^^^^^ + +.. toctree:: + :maxdepth: 1 + + core_dump_internals diff --git a/docs/zh_CN/api-guides/core_dump_internals.rst b/docs/zh_CN/api-guides/core_dump_internals.rst index 3de3b65edd..b5474896ef 100644 --- a/docs/zh_CN/api-guides/core_dump_internals.rst +++ b/docs/zh_CN/api-guides/core_dump_internals.rst @@ -1 +1,46 @@ -.. include:: ../../en/api-guides/core_dump_internals.rst \ No newline at end of file +核心转储图像文件详解 +-------------------------- + +:link_to_translation:`en:[English]` + +核心转储文件的格式可以配置为使用 ELF 格式或传统的二进制格式。建议在所有新设计中使用 ELF 格式,该格式在发生崩溃时会提供更多关于软件状态的信息,例如 CPU 寄存器和内存内容。 + +内存状态包含程序内存空间中映射的所有任务的快照;CPU 状态包含核心转储生成时的寄存器值。核心转储文件使用 ELF 结构的子集注册这些信息。 + +可加载的 ELF 段用于存储进程的内存状态,ELF 注释 (``ELF.PT_NOTE``) 用于存储进程的元数据(如 pid、寄存器、信号等)。CPU 状态则存储在一个具有特殊名称 (``CORE``) 和类型 (``NT_PRSTATUS type``) 的注释中。 + +下图展示了核心转储的结构: + +.. figure:: ../../_static/core_dump_format_elf.png + :align: center + :alt: 核心转储 ELF 图像文件格式 + :figclass: align-center + + 核心转储 ELF 图像文件格式 + +.. figure:: ../../_static/core_dump_format_bin.png + :align: center + :alt: 核心转储二进制图像文件格式 + :figclass: align-center + + 核心转储二进制图像文件格式 + +.. note:: + + 上图仅展示当前版本图像的文件格式,在未来的发布版本中可能会发生变化。 + +核心转储实现 +-------------------------- + +下图展示了核心转储实现的基本情况: + +.. figure:: ../../_static/core_dump_impl.png + :align: center + :alt: 核心转储实现 + :figclass: align-center + + 核心转储实现 + +.. note:: + + 上图隐藏了部分细节,仅展示当前版本的核心转储实现,在未来的发布版本中可能会发生变化。 \ No newline at end of file