Frequently Asked Questions
Linker "Duplicate definition" error for HardFault_Handler
etc.
The Memfault SDK includes definitions for several exception handlers, for example:
HardFault_Handler
MemoryManagement_Handler
etc.
See here for the implementation.
These handlers should replace the existing ones in your project. You can remove
the existing implementations entirely, or you can for mark them with the weak
attribute (eg, using the MEMFAULT_WEAK
compiler-agnostic define) to avoid the
linker error.
What is memfault_platform_coredump_get_regions()
/ memfault_platform_sanitize_address_range()
?
memfault_platform_coredump_get_regions()
memfault_platform_coredump_get_regions()
tells the Memfault fault handler
which memory regions should be collected as part of a coredump. The Memfault SDK
by default will collect the CPU registers and various fault registers of
interest. memfault_platform_coredump_get_regions()
provides additional memory
regions, which could be the entire contents of RAM, or selected sections only
(the RAM-backed coredump storage provides a default implementation that collects
a portion of the current stack). Typically, if sufficient storage is available,
including the entire RAM regions in the coredump will provide the most
information on a crash.
memfault_platform_sanitize_address_range()
memfault_platform_sanitize_address_range()
is used to filter out sections of
memory that should not be captured by the Memfault fault handler as part of a
coredump. It's necessary to prevent the core dump writer from attempting to copy
data from inaccessible memory regions, which would cause the core dump to fail.
We highly recommend implementing it; usually it's sufficient to set it up with
the accessible memory regions for that device, for example, a chip with a single
0x40000
byte RAM section, starting at address 0x20000000
, would have an
implementation like:
size_t memfault_platform_sanitize_address_range(void *start_addr,
size_t desired_size) {
// these values can be provided by the linker script, or explicitly defined
const uint32_t RAM_ORIGIN = 0x20000000;
const uint32_t RAM_LENGTH = 0x40000;
struct {
uint32_t start_addr;
size_t length;
} s_mcu_mem_regions[] = {
{
.start_addr = RAM_ORIGIN,
.length = RAM_LENGTH,
},
};
for (size_t i = 0; i < MEMFAULT_ARRAY_SIZE(s_mcu_mem_regions); i++) {
const uint32_t lower_addr = s_mcu_mem_regions[i].start_addr;
const uint32_t upper_addr = lower_addr + s_mcu_mem_regions[i].length;
if ((uint32_t)start_addr >= lower_addr &&
((uint32_t)start_addr < upper_addr)) {
return MEMFAULT_MIN(desired_size, upper_addr - (uint32_t)start_addr);
}
}
return 0;
}
Compilation error variable tracking requested, but useless unless producing debug info
The following error may occur when building an application that includes the Memfault Firmware SDK:
cc1: error: variable tracking requested, but useless unless producing debug info [-Werror]
The Memfault SDK requires building with debug info enabled. Note that enabling debug info does not impact the binary executable in the final program, but only the metadata (debug info) that enables debugging a program.
To resolve this warning, be sure to enable debug info in the build system. For
gcc
based builds, the following flag can be used:
-ggdb3
Other IDE's will have a "Debug" checkbox in the C compiler settings that should
be enabled, which translates to the above option when the IDE builds with gcc
.
Merging auxiliary symbol files into an ELF
Memfault allows including additional ELFs (i.e. for ROM code or otherwise)
inside the "main" ELF file, by embedding each additional ELF in a section
prefixed with .mflt_aux_symbols
.
The objcopy
program from GNU binutils can be used to do this. Note, if you are
using a GCC based cross compiler, the binary is likely to be named after the
target platform, for example arm-none-eabi-objcopy
.
In the following example, we have got a main.elf
file containing the
application firmware and 2 ROM ELF files, rom-a.elf
and rom-b.elf
. The ROM
ELFs are merged into the main ELF, producing merged.elf
.
Note that the name of the section needs to start with .mflt_aux_symbols
. When
adding multiple auxiliary ELFs, make sure to add a unique suffixes or else
objcopy
will complain.
objcopy \
--add-section .mflt_aux_symbols.a=rom-a.elf \
--add-section .mflt_aux_symbols.b=rom-b.elf \
main.elf \
merged.elf
If there's only a single ROM elf file, rom.elf
, this example would apply (note
that the output section, .mflt_aux_symbols
, doesn't need a suffix here because
there's only 1 section of that name):
objcopy \
--add-section .mflt_aux_symbols=rom.elf \
main.elf \
merged.elf
The symbols and debug info in the auxiliary ELFs are currently only loaded to produce the backtrace. They are not yet passed into the "Globals & Statics” view.
Recommended Compiler and Linker Flags
For a general list of recommended and not-recommended compiler flags, see this article:
https://interrupt.memfault.com/blog/best-and-worst-gcc-clang-compiler-flags
Flags that specifically impact Memfault compatibility are listed in the sections below.
Link Time Optimization (LTO) -flto
We strongly recommend against using Link Time Optimization (LTO) in the programs you want to be able to debug using coredumps. When LTO is enabled, the analysis of the coredumps can become lacking or even fail completely.