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

Ubuntu 22.04内核模块编译遇ASan未定义符号错误求助

KASAN相关内核模块编译问题解答

问题背景

我正尝试在**Ubuntu 22.04(Linux内核6.1.25)**环境下编译“Hello, World”内核模块,但执行make命令时,遇到与AddressSanitizer(ASan)相关的错误:

make -C /lib/modules/6.1.25-lkp-kernel/build/ M=$(PWD) modules
make[1]: Entering directory '/home/c2kp/kernels/linux-6.1.25'
  CC [M]  /home/c2kp/Linux-Kernel-Programming_2E/ch4/helloworld_lkm/helloworld_lkm.o
  MODPOST /home/c2kp/Linux-Kernel-Programming_2E/ch4/helloworld_lkm/Module.symvers
ERROR: modpost: "__asan_unregister_globals" [/home/c2kp/Linux-Kernel-Programming_2E/ch4/helloworld_lkm/helloworld_lkm.ko] undefined!
ERROR: modpost: "__asan_register_globals" [/home/c2kp/Linux-Kernel-Programming_2E/ch4/helloworld_lkm/helloworld_lkm.ko] undefined!
make[2]: *** [scripts/Makefile.modpost:126: /home/c2kp/Linux-Kernel-Programming_2E/ch4/helloworld_lkm/Module.symvers] Error 1
make[1]: *** [Makefile:1964: modpost] Error 2
make[1]: Leaving directory '/home/c2kp/kernels/linux-6.1.25'
make: *** [Makefile:9: all] Error 2

我的Makefile内容如下:

PWD   := $(shell pwd)
KDIR  := /lib/modules/$(shell uname -r)/build/
obj-m += helloworld_lkm.o
ccflags-y += -fsanitize=kernel-address

all:
        make -C $(KDIR) M=$(PWD) modules
install:
        make -C $(KDIR) M=$(PWD) modules_install
clean:
        make -C $(KDIR) M=$(PWD) clean

咨询问题

  1. 为何这些未定义符号会导致我的内核模块编译失败?
  2. 当内核已启用KASAN时,确保模块正确编译的最佳方式是什么?
  3. 在Makefile中添加ccflags-y += -fsanitize=kernel-address是否为正确修复方案,还是应在内核中禁用KASAN?

问题解答

1. 未定义符号导致编译失败的原因

__asan_register_globals和__asan_unregister_globals是KASAN(内核地址 sanitizer)提供的核心符号,负责在模块加载/卸载时注册、清理内存检测所需的全局元数据。
你手动在Makefile中添加-fsanitize=kernel-address编译选项,强制模块启用KASAN,但当前使用的内核要么未编译KASAN支持,要么KASAN的符号未导出到模块可用范围,导致链接阶段找不到这些必要符号,最终编译失败。

2. 内核已启用KASAN时模块正确编译的最佳方式

如果内核已经启用KASAN(内核配置中CONFIG_KASAN=y或CONFIG_KASAN=m),无需手动在模块Makefile中添加-fsanitize=kernel-address:

  • 内核构建系统会自动将全局的KASAN编译选项继承到模块编译流程中,确保模块与内核的KASAN配置一致。
  • 确认内核配置:查看/boot/config-$(uname -r)文件,检查是否存在CONFIG_KASAN=y或CONFIG_KASAN=m;如果是模块化KASAN(CONFIG_KASAN=m),需先加载kasan.ko内核模块。

3. Makefile添加编译选项vs禁用内核KASAN的选择

  • 不要手动添加ccflags-y += -fsanitize=kernel-address:该操作会强制模块启用KASAN,若内核本身无KASAN支持或符号未导出,必然触发未定义符号错误。正确做法是让内核构建系统自动处理KASAN编译选项的继承。
  • 是否禁用内核KASAN?取决于你的需求:
    • 若无需内存检测功能,且当前内核的KASAN导致模块编译问题,可重新编译内核并关闭CONFIG_KASAN选项。
    • 若需要KASAN的内存检测能力,确保内核已正确启用KASAN(且符号导出),移除Makefile中手动添加的KASAN编译选项后重新编译模块即可。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.14 10:33:20