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

如何修复Clang的__ubsan_handle_out_of_bounds未定义符号错误

使用Clang -fsanitize=array-bounds 编译时出现__ubsan_handle_out_of_bounds未定义错误的解决方案

问题描述

使用Clang编译器的-fsanitize=array-bounds标志编译C99代码时,遭遇__ubsan_handle_out_of_bounds未定义符号错误。即使将代码简化为基础的数组赋值操作,错误依然存在。

初始代码

void _add_entry(const char* api_name, void* api_ptr) {
    int id = _produce_id_from_string(api_name);

    ASSERT(_api_hash_map.entry_index < MAX_ENTRIES);

    _key_value_pair* map_entry = &_api_hash_map.entries[_api_hash_map.entry_index++]; //out of bounds
    map_entry->unique_id = id;
    map_entry->value = (uintptr)api_ptr;
};

修改后的代码(仍报错)

void _add_entry(const char* api_name, void* api_ptr) {
    int id = _produce_id_from_string(api_name);

    ASSERT(_api_hash_map.entry_index < MAX_ENTRIES);

    if(_api_hash_map.entry_index < MAX_ENTRIES) {
        _key_value_pair* map_entry = &_api_hash_map.entries[_api_hash_map.entry_index];
        map_entry->unique_id = id;
        map_entry->value = (uintptr)api_ptr;
        _api_hash_map.entry_index++;
    }
};

简化后的测试代码(仍报错)

void _add_entry(const char* api_name, void* api_ptr) {
    int arr[10] = { 0 };
    arr[3] = 23;
};

构建脚本

@echo off

REM This represents the full directory path to your batch file
set cwd=%~dp0

call "C:\msvc\setup.bat"

REM -fno-stack-protector tells compiler to not worry about security calls (like __security_cookie) that would typically be inserted with c libs. -mstack-probe-size=99999999999 basically says don't worry about __chkdsk for checking stack overruns
REM Note that the -Wpadded option isn't really working at the moment. I think there is a github issue on this open so we'll have to see if this is fixed in a later version (https://github.com/llvm/llvm-project/issues/58100)
set compiler_flags=-g -fdebug-macro -O0 -fno-stack-protector -Wall -Wpadded -mstack-probe-size=9999999 -fno-builtin -std=c99 -fdiagnostics-absolute-paths -fsanitize=array-bounds

REM -STACK:0x100000,0x100000 is setting function stack default to 1MB. Can increase this if we need to. Keep in mind though this also increases default stack size for all threads created
set linker_flags=-subsystem:windows -machine:x64 -incremental:no -opt:ref -debug:full -ignore:4099 -NODEFAULTLIB -STACK:0x100000,0x100000

set include_paths=-I"%cwd%source" -I"C:\msvc\Windows Kits\10\Include\10.0.22621.0\um"
set library_paths=-LIBPATH:"C:\msvc\Windows Kits\10\Lib\10.0.22621.0\um\x64" 
set import_libraries="kernel32.lib" "user32.lib" "glew32s.lib" "opengl32.lib" "gdi32.lib"

IF NOT EXIST bin mkdir bin
pushd bin

clang --compile ..\source\editor.c %compiler_flags%
lld-link editor.o -dll %linker_flags% -export:editor_update -noentry

clang --compile ..\source\win64_main.c %compiler_flags% %include_paths% -I"%cwd%dep\glew-2.1.0\include" -DBGZ_WIN64 -Wno-unused-function -Wno-unused-variable -Wno-unused-but-set-variable -Wno-null-dereference
lld-link win64_main.o -OUT:win64_main.exe %linker_flags% %library_paths% %import_libraries% -LIBPATH:"%cwd%dep\glew-2.1.0\lib\win64-release"

错误信息

----- Build Debug x64 -----
Executing build command:
clang_build.bat
lld-link: error: undefined symbol: __ubsan_handle_out_of_bounds
>>> referenced by D:\User Program Files_Data\software_projects\bgz_engine\source\api_directory.h:52
>>>               win64_main.o:(_add_entry)
>>> referenced by D:\User Program Files_Data\software_projects\bgz_engine\source\api_directory.h:74
>>>               win64_main.o:(_get_api)
>>> referenced by D:\User Program Files_Data\software_projects\bgz_engine\source\stb_sprintf.h:595
>>>               win64_main.o:(stbsp_vsprintfcb)
>>> referenced 209 more times
===== Success : 1 errors, 0 warnings =====

错误原因

这不是代码存在数组越界问题,而是链接阶段缺少UBSan(Undefined Behavior Sanitizer)的运行时库。启用-fsanitize=array-bounds后,Clang会在编译时插入数组越界检查的逻辑,这些逻辑依赖UBSan的运行时函数(如__ubsan_handle_out_of_bounds),但当前构建脚本仅在编译阶段添加了该标志,链接阶段未配置对应的库,导致符号未找到。

解决方法

1. 在链接阶段添加UBSan标志

将-fsanitize=array-bounds添加到链接命令中,让lld-link自动链接所需的UBSan运行时库。修改构建脚本中的lld-link命令:

lld-link win64_main.o -OUT:win64_main.exe %linker_flags% %library_paths% %import_libraries% -LIBPATH:"%cwd%dep\glew-2.1.0\lib\win64-release" -fsanitize=array-bounds

或者直接把该标志加入linker_flags变量:

set linker_flags=-subsystem:windows -machine:x64 -incremental:no -opt:ref -debug:full -ignore:4099 -NODEFAULTLIB -STACK:0x100000,0x100000 -fsanitize=array-bounds

2. 手动指定UBSan库(备选)

如果自动链接不生效,可以手动将ubsan.lib添加到import_libraries中:

set import_libraries="kernel32.lib" "user32.lib" "glew32s.lib" "opengl32.lib" "gdi32.lib" "ubsan.lib"

注意事项

  • 确保使用的Clang版本支持UBSan,且UBSan运行时库已随Clang正确安装。
  • 若使用-NODEFAULTLIB,需确认未排除UBSan相关库,否则需手动引入ubsan.lib。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.03 08:45:25