You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何让backtrace_symbols调用__wrap_malloc?wrap_malloc拦截问题

问题分析

为什么__wrap_malloc无法拦截backtrace_symbols的malloc调用?核心原因有两个:

  1. 链接器wrap机制的局限性:--wrap=malloc是链接阶段的符号替换手段,仅作用于你的代码中对malloc的外部引用,而backtrace_symbols是glibc预编译好的库函数,它内部对malloc的调用已经直接绑定到glibc自身的malloc实现,链接器无法修改库内部的符号引用。
  2. 动态链接的符号优先级:程序运行时,glibc内部的函数调用会直接使用库内的符号,不会去查找外部的__wrap_malloc。
解决方案

针对GCC 7.5.0环境,有两种可行的解决方式:

方式一:使用LD_PRELOAD加载自定义动态库

这是最通用的拦截手段,通过动态链接器的预加载机制,让自定义的malloc优先被所有代码(包括glibc内部函数)调用。

  1. 编写自定义malloc实现文件(比如mymalloc.c):
#define _GNU_SOURCE
#include <stdio.h>
#include <stdlib.h>
#include <dlfcn.h>

// 保存原始的malloc函数指针
static void* (*original_malloc)(size_t) = NULL;

// 自定义malloc
void* malloc(size_t size) {
    if (!original_malloc) {
        original_malloc = dlsym(RTLD_NEXT, "malloc");
        if (!original_malloc) {
            fprintf(stderr, "dlsym error: %s\n", dlerror());
            exit(1);
        }
    }
    printf("Intercepted malloc call, size: %zu\n", size);
    return original_malloc(size);
}

// 实现free避免链接报错
void free(void* ptr) {
    static void (*original_free)(void*) = NULL;
    if (!original_free) {
        original_free = dlsym(RTLD_NEXT, "free");
        if (!original_free) {
            fprintf(stderr, "dlsym error: %s\n", dlerror());
            exit(1);
        }
    }
    original_free(ptr);
}
  1. 编译动态库:
gcc -shared -fPIC -ldl mymalloc.c -o libmymalloc.so
  1. 运行程序时预加载该库:
LD_PRELOAD=./libmymalloc.so ./your_program

方式二:使用glibc的malloc钩子(仅适用于旧版glibc)

GCC 7.5.0对应的glibc版本(一般为2.23左右)还支持已废弃的__malloc_hook机制,可在程序初始化时替换malloc调用:

  1. 修改程序代码:
#define _GNU_SOURCE
#include <stdio.h>
#include <stdlib.h>
#include <malloc.h>
#include <execinfo.h>

// 自定义malloc
static void* my_malloc(size_t size, const void* caller) {
    printf("Intercepted malloc via hook, size: %zu\n", size);
    // 先恢复钩子避免递归调用
    __malloc_hook = NULL;
    void* ptr = malloc(size);
    // 重新设置钩子
    __malloc_hook = my_malloc;
    return ptr;
}

// 初始化钩子
static void init_hook() {
    __malloc_hook = my_malloc;
}

// 程序启动时自动执行初始化
__attribute__((constructor))
void setup() {
    init_hook();
}

int main() {
    void* callstack[10];
    int frames = backtrace(callstack, 10);
    char** strs = backtrace_symbols(callstack, frames);
    // 后续处理
    free(strs);
    return 0;
}
  1. 编译运行:
gcc your_program.c -o your_program -rdynamic
./your_program

注意:__malloc_hook在glibc 2.26之后被正式移除,仅适配你的GCC 7.5.0环境,长期来看推荐使用LD_PRELOAD方式。

内容的提问来源于stack exchange,提问作者刘肃超

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.08 13:02:31