我正在尝试诊断Linux内核中的NULL指针访问:
BUG: unable to handle kernel NULL pointer dereference at 00000100
IP: [<c1145647>] kmem_cache_alloc+0x47/0x150
但是,kmem_cache_alloc
充满了内联函数。为了精确定位NULL指针访问的确切位置,我需要构建没有内联函数的内核。我知道使用-fno-inline构建内核并不是一个好主意,但它仅用于诊断目的。
所以我在Makefile中为KBUILD_CFLAGS
添加了一些选项:
-fno-default-inline
-fno-inline
-fno-inline-small-functions
-fno-indirect-inlining
-fno-inline-functions-called-once
不幸的是,-fno-inline
导致构建错误,被BUILD_BUG
宏触发:
mm/filemap.c:338:22: note: in expansion of macro ‘HPAGE_PMD_NR’
page_ref_sub(page, HPAGE_PMD_NR);
引起:
./include/linux/huge_mm.h:161:28: note: in expansion of macro ‘BUILD_BUG’
#define HPAGE_PMD_SHIFT ({ BUILD_BUG(); 0; })
显然,我们不应该在未配置HPAGE_PMD_SHIFT
的情况下使用CONFIG_TRANSPARENT_HUGEPAGE
,但HPAGE_PMD_NR
通过HPAGE_PMD_ORDER
执行此操作。无论CONFIG_TRANSPARENT_HUGEPAGE
是什么,两者都可用:
#define HPAGE_PMD_ORDER (HPAGE_PMD_SHIFT-PAGE_SHIFT)
#define HPAGE_PMD_NR (1<<HPAGE_PMD_ORDER)
我的问题是:是否可以使用-fno-inline构建内核?
我很想知道,因为根据我的理解,无论是否设置-fno-inline,此错误都应该会发生。而且这段代码非常接近我目前正在诊断的代码。
更新:在CONFIG_TRANSPARENT_HUGEPAGE
中进行配置时,所有内容都会编译,但不会链接。我认为我可以通过一些肘部油脂来解决这个问题,但这不是真正的解决方案,因为CONFIG_TRANSPARENT_HUGEPAGE
不能与我们的应用所依赖的CONFIG_PREEMPT_RT_FULL
一起使用。