Skip to main content

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


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() 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() 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:


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 \

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 \

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.

For a general list of recommended and not-recommended compiler flags, see this article:

Flags that specifically impact Memfault compatibility are listed in the sections below.

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.