Search code examples
cgccgdbembeddedgnu

GDB Debugger - "malloc" not defined. Trying to assign C array with debugger


I've got some software compiled to run on an embedded NRF24 target, using a gcc-arm-none-eabi toolchain from here (a custom one that provides gdb with support for python3) . I'm trying essentially, malloc an array from the GDB debugger console at runtime, then fill it with elements that I provide.

I have a pointer defined in a .c file like: static float32_t *array;. I want to then call a cmd like: call (void*) malloc(num_of_elements*sizeof(float32_t)) from inside the GDB console to allocate an array at runtime, and then fill it with elements with something like maybe: call (void*) memcpy(array, {var1, var2... var n}, n)

My issue is the GDB debugger cannot find the malloc stdlib function. If I do something like:

break malloc 
Function "malloc" not defined.
Make breakpoint pending on future shared library load? (y or [n]) [answered N; input not from terminal]

It can't find this function, although it is fine with finding <string.h> fns, like memcpy for example and I can't quite work out why this is.

I have a feeling it could be something to do with linking, the program is built with a Makefile, the flags towards the end may be of interest:

LIB_FILES += \
  $(SDK_ROOT)/components/toolchain/cmsis/dsp/GCC/libarm_cortexM4lf_math.a \

# Optimization flags
OPT = -O0 -g3
# Uncomment the line below to enable link time optimization
#OPT += -flto

# C flags common to all targets
CFLAGS += $(OPT)
CFLAGS += -DBOARD_PCA10056
CFLAGS += -DARM_MATH_CM4
CFLAGS += -DBSP_DEFINES_ONLY
CFLAGS += -DCONFIG_GPIO_AS_PINRESET
CFLAGS += -DFLOAT_ABI_HARD
CFLAGS += -DNRF52840_XXAA
CFLAGS += -mcpu=cortex-m4
CFLAGS += -mthumb -mabi=aapcs
CFLAGS += -mfloat-abi=hard -mfpu=fpv4-sp-d16
# keep every function in a separate section, this allows linker to discard unused ones
CFLAGS += -ffunction-sections -fdata-sections -fno-strict-aliasing
CFLAGS += -fno-builtin -fshort-enums

CFLAGS += -DDEV8_PINOUT
CFLAGS += -DNUM_FLASH_BLOCKS=128
CFLAGS += -DDEBUG
CFLAGS += -DNRF_LOG_ENABLED=1
CFLAGS += -DNRF_LOG_BACKEND_UART_ENABLED=1

# C++ flags common to all targets
CXXFLAGS += $(OPT)
# Assembler flags common to all targets
ASMFLAGS += $(OPT)
ASMFLAGS += -mcpu=cortex-m4
ASMFLAGS += -mthumb -mabi=aapcs
ASMFLAGS += -mfloat-abi=hard -mfpu=fpv4-sp-d16
ASMFLAGS += -DBOARD_PCA10056
ASMFLAGS += -DBSP_DEFINES_ONLY
ASMFLAGS += -DCONFIG_GPIO_AS_PINRESET
ASMFLAGS += -DFLOAT_ABI_HARD
ASMFLAGS += -DNRF52840_XXAA
ASMFLAGS += -DARM_MATH_CM4

# Linker flags
LDFLAGS += $(OPT)
LDFLAGS += -mthumb -mabi=aapcs -L$(SDK_ROOT)/modules/nrfx/mdk -T$(LINKER_SCRIPT)
LDFLAGS += -mcpu=cortex-m4
LDFLAGS += -mfloat-abi=hard -mfpu=fpv4-sp-d16
# let linker dump unused sections
LDFLAGS += -Wl,--gc-sections
# use newlib in nano version
LDFLAGS += --specs=nano.specs
LDFLAGS += -Wl,--print-memory-usage

nrf52840_xxaa: CFLAGS += -D__HEAP_SIZE=8192
nrf52840_xxaa: CFLAGS += -D__STACK_SIZE=8192
nrf52840_xxaa: ASMFLAGS += -D__HEAP_SIZE=8192
nrf52840_xxaa: ASMFLAGS += -D__STACK_SIZE=8192

# Add standard libraries at the very end of the linker input, after all objects
# that may need symbols provided by these libraries.
LIB_FILES += -lc -lnosys -lm

To debug I'm using GDB with a Jlink server type setup.


Solution

  • Your code needs to explicitly reference the symbol to force it to link, and you need to prevent link optimisation from removing unused references. Rather then doing a dummy call with potential unwanted side effects, you can simply refer to the symbol via a function pointer instantiation thus:

     void* (*volatile force_malloc_link)(size_t) = &malloc ;
    

    Or more simply since you will not actually invoke the function through the pointer:

    volatile void* force_link_malloc = &malloc ;
    

    You could make it generic with a macro for any symbol you wish to link:

    #define FORCE_LINK( sym ) volatile void* force_link_ ## sym = &sym 
    

    You can also force the entire library to be linked (if you have the space) - How to force gcc to link an unused static library. One of the answers there explains how you can also unpack the static library and link individual object files.