GDB 调试器 - "malloc" 未定义。尝试使用调试器分配 C 数组
GDB Debugger - "malloc" not defined. Trying to assign C array with debugger
我使用 here 的 gcc-arm-none-eabi 工具链(自定义工具链提供gdb 支持 python3) 。我基本上是在尝试 malloc
在 运行 时间从 GDB 调试器控制台获取一个数组,然后用我提供的元素填充它。
我在 .c 文件中定义了一个指针,例如:static float32_t *array;
。
然后我想调用一个命令,如:call (void*) malloc(num_of_elements*sizeof(float32_t))
从 GDB 控制台内部在 运行 时间分配一个数组,然后用可能的元素填充它:call (void*) memcpy(array, {var1, var2... var n}, n)
我的问题是 GDB 调试器找不到 malloc
stdlib 函数。如果我这样做:
break malloc
Function "malloc" not defined.
Make breakpoint pending on future shared library load? (y or [n]) [answered N; input not from terminal]
它找不到这个函数,虽然它可以找到 fns,例如 memcpy
,但我不太明白为什么会这样。
我觉得这可能与链接有关,程序是用 Makefile 构建的,最后的标志可能很有趣:
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
为了调试,我将 GDB 与 Jlink 服务器类型设置一起使用。
It can't find this function
该函数可能不会 link 编辑到您的二进制文件中。
- 你的二进制 在其他地方调用
malloc
吗?
- 你link反对
libc.so
或libc.a
吗?
nm a.out | grep ' malloc'
找到了吗?
it is fine with finding <string.h> fns, like memcpy
如果您的二进制调用 memcpy
而您 link 反对 libc.a
,那么 memcpy
实现将被 link 编辑。使用相同的 [=上面的 19=] 命令将显示 memcpy
符号存在而 malloc
不存在。
如果您想在运行时调用 malloc
,您需要确保它已被 link 编辑。实现此目的的一种方法是添加:
const char *argv0;
int main(int argc, char *argv[])
{
argv0 = strdup(argv[0]); // This should guarantee that malloc is linked in.
// rest of the program
}
您的代码需要显式引用该符号以将其强制为 link,并且您需要防止 link 优化删除未使用的引用。与其进行具有潜在不良副作用的虚拟调用,不如通过函数指针实例化简单地引用该符号:
void* (*volatile force_malloc_link)(size_t) = &malloc ;
或者更简单,因为您实际上不会通过指针调用该函数:
volatile void* force_link_malloc = &malloc ;
您可以使用宏为您想要的任何符号使其通用link:
#define FORCE_LINK( sym ) volatile void* force_link_ ## sym = &sym
您还可以强制对整个库进行 link 编辑(如果您有 space)- How to force gcc to link an unused static library。那里的答案之一解释了如何解压静态库和 link 个单独的目标文件。
我使用 here 的 gcc-arm-none-eabi 工具链(自定义工具链提供gdb 支持 python3) 。我基本上是在尝试 malloc
在 运行 时间从 GDB 调试器控制台获取一个数组,然后用我提供的元素填充它。
我在 .c 文件中定义了一个指针,例如:static float32_t *array;
。
然后我想调用一个命令,如:call (void*) malloc(num_of_elements*sizeof(float32_t))
从 GDB 控制台内部在 运行 时间分配一个数组,然后用可能的元素填充它:call (void*) memcpy(array, {var1, var2... var n}, n)
我的问题是 GDB 调试器找不到 malloc
stdlib 函数。如果我这样做:
break malloc
Function "malloc" not defined.
Make breakpoint pending on future shared library load? (y or [n]) [answered N; input not from terminal]
它找不到这个函数,虽然它可以找到 memcpy
,但我不太明白为什么会这样。
我觉得这可能与链接有关,程序是用 Makefile 构建的,最后的标志可能很有趣:
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
为了调试,我将 GDB 与 Jlink 服务器类型设置一起使用。
It can't find this function
该函数可能不会 link 编辑到您的二进制文件中。
- 你的二进制 在其他地方调用
malloc
吗? - 你link反对
libc.so
或libc.a
吗? nm a.out | grep ' malloc'
找到了吗?
it is fine with finding <string.h> fns, like
memcpy
如果您的二进制调用 memcpy
而您 link 反对 libc.a
,那么 memcpy
实现将被 link 编辑。使用相同的 [=上面的 19=] 命令将显示 memcpy
符号存在而 malloc
不存在。
如果您想在运行时调用 malloc
,您需要确保它已被 link 编辑。实现此目的的一种方法是添加:
const char *argv0;
int main(int argc, char *argv[])
{
argv0 = strdup(argv[0]); // This should guarantee that malloc is linked in.
// rest of the program
}
您的代码需要显式引用该符号以将其强制为 link,并且您需要防止 link 优化删除未使用的引用。与其进行具有潜在不良副作用的虚拟调用,不如通过函数指针实例化简单地引用该符号:
void* (*volatile force_malloc_link)(size_t) = &malloc ;
或者更简单,因为您实际上不会通过指针调用该函数:
volatile void* force_link_malloc = &malloc ;
您可以使用宏为您想要的任何符号使其通用link:
#define FORCE_LINK( sym ) volatile void* force_link_ ## sym = &sym
您还可以强制对整个库进行 link 编辑(如果您有 space)- How to force gcc to link an unused static library。那里的答案之一解释了如何解压静态库和 link 个单独的目标文件。