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

如何在禁用glibc的情况下编译自定义C语言malloc实现?

解决方法:手动基于brk系统调用实现sbrk函数

因为-nostdlib会完全禁用glibc的所有库函数,而sbrk()本身是glibc对底层brk系统调用的封装,所以你需要自己手动实现sbrk()的逻辑,直接调用系统调用完成内存断点的调整。

核心原理

在x86_64架构下,brk系统调用的编号是12(无需依赖头文件,直接硬编码即可):

  • 传入参数为0时,会返回当前程序的内存断点地址
  • 传入具体地址时,会将程序断点调整到该地址,成功返回0,失败返回-1
  • sbrk()的本质就是:获取当前断点→计算新断点→调用brk更新→返回旧断点

手动实现sbrk函数(x86_64)

直接用内联汇编编写符合逻辑的sbrk,不需要依赖任何glibc函数:

#include <stdint.h>

void *sbrk(intptr_t increment) {
    static void *current_brk = NULL;
    void *old_brk;
    uint64_t sys_ret;

    // 首次调用先获取当前内存断点
    if (current_brk == NULL) {
        __asm__ volatile (
            "mov $12, %%rax\n"    // brk系统调用编号
            "mov $0, %%rdi\n"     // 参数0:获取当前断点
            "syscall\n"
            "mov %%rax, %0\n"
            : "=r"(sys_ret)
            :
            : "%rax", "%rdi", "%rcx", "%r11"  // 声明被修改的寄存器
        );
        current_brk = (void *)sys_ret;
    }

    old_brk = current_brk;
    void *new_brk = (void *)((uintptr_t)current_brk + increment);

    // 调用brk设置新断点
    __asm__ volatile (
        "mov $12, %%rax\n"
        "mov %1, %%rdi\n"     // 参数:新的断点地址
        "syscall\n"
        "mov %%rax, %0\n"
        : "=r"(sys_ret)
        : "r"(new_brk)
        : "%rax", "%rdi", "%rcx", "%r11"
    );

    // 处理调用失败的情况
    if (sys_ret == (uint64_t)-1) {
        return (void *)-1;
    }

    current_brk = new_brk;
    return old_brk;
}

补充:实现程序入口函数

因为-nostdlib会禁用glibc的_start入口,你需要自己编写一个简单的入口函数来启动程序:

#include <stdint.h>

void main();

// x86_64架构的程序入口
void _start() {
    main();
    // 调用exit系统调用退出(编号60)
    __asm__ volatile (
        "mov $60, %%rax\n"
        "mov $0, %%rdi\n"
        "syscall\n"
    );
}

编译注意事项

保持你原有的编译标志即可:

gcc -m64 -fPIC -pedantic -Wall -Wextra -Werror -nostdlib -ggdb3 your_malloc.c -o your_malloc
  • stddef.h和stdint.h是编译器内置的标准头文件,-nostdlib不会影响它们的使用
  • 上述代码仅适配x86_64架构,和你的-m64编译标志匹配

内容的提问来源于stack exchange,提问作者Nayrosk

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.06 03:28:10