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

将带AddressSanitizer的C++库通过ctypes加载到Python的问题

问题:带AddressSanitizer的C++库通过ctypes加载到Python失败

我用g和cmake编译了带AddressSanitizer(asan)的C库,编译参数如下:

SET( AXULIARY_COMPILE_FLAGS "-g -Og -fsanitize=address -fno-omit-frame-pointer")

该库作为独立C++可执行程序运行正常,但通过ctypes加载到Python时无法工作。


尝试方案1:LD_PRELOAD预加载libasan.so

对应的run.sh脚本:

#!/bin/bash
#LD_PRELOAD=/usr/lib/gcc/x86_64-linux-gnu/11/libasan.so
LD_PRELOAD=$(g++ -print-file-name=libasan.so)
echo   $LD_PRELOAD
export $LD_PRELOAD
python3 run_asan.py

run_asan.py脚本:

import ctypes ;print("DEBUG 1 ")
asan = ctypes.CDLL( "/usr/lib/gcc/x86_64-linux-gnu/11/libasan.so", mode=ctypes.RTLD_LOCAL )                ;print("DEBUG 2 ")
lib  = ctypes.CDLL( "../../cpp/Build/libs/Molecular/libMMFFsp3_lib.so", mode=ctypes.RTLD_LOCAL )           ;print("DEBUG 3 ")

执行后错误:

prokop@DesktopGTX3060:~/git/FireCore/tests/tMMFFsp3$ ./run.sh
/usr/lib/gcc/x86_64-linux-gnu/11/libasan.so
./run.sh-: line 7: export: `/usr/lib/gcc/x86_64-linux-gnu/11/libasan.so': not a valid identifier
DEBUG 1 
==20016==ASan runtime does not come first in initial library list; you should either link runtime to your application or manually preload it with LD_PRELOAD.

尝试方案2:cmake静态链接asan

对应的run_asan.py脚本:

import ctypes; print("DEBUG 1 ")
lib  = ctypes.CDLL( "../../cpp/Build/libs/Molecular/libMMFFsp3_lib.so", mode=ctypes.RTLD_LOCAL )  

执行后错误:

prokop@DesktopGTX3060:~/git/FireCore/tests/tMMFFsp3$ python3 run_asan.py
/usr/lib/gcc/x86_64-linux-gnu/11/libasan.so
./run.sh-: line 7: export: `/usr/lib/gcc/x86_64-linux-gnu/11/libasan.so': not a valid identifier
DEBUG 1 
Traceback (most recent call last):
  File "/home/prokop/git/FireCore/tests/tMMFFsp3/run_asan.py", line 3, in <module>
    lib  = ctypes.CDLL( "../../cpp/Build/libs/Molecular/libMMFFsp3_lib.so", mode=ctypes.RTLD_LOCAL )           ;print("DEBUG 3 ")
  File "/usr/lib/python3.10/ctypes/__init__.py", line 374, in __init__
    self._handle = _dlopen(self._name, mode)
OSError: ../../cpp/Build/libs/Molecular/libMMFFsp3_lib.so: undefined symbol: __asan_option_detect_stack_use_after_return

解决方法

1. 修复LD_PRELOAD脚本与Python加载逻辑

第一个方案的核心错误是export $LD_PRELOAD语法错误,正确的export写法不需要变量名前的$。同时无需在Python代码中手动加载libasan.so,修改后的脚本如下:

修正后的run.sh:

#!/bin/bash
LD_PRELOAD=$(g++ -print-file-name=libasan.so)
echo $LD_PRELOAD
export LD_PRELOAD
python3 run_asan.py

简化后的run_asan.py:

import ctypes
print("DEBUG 1 ")
# 改用RTLD_GLOBAL确保ASan符号能被库正确引用
lib = ctypes.CDLL("../../cpp/Build/libs/Molecular/libMMFFsp3_lib.so", mode=ctypes.RTLD_GLOBAL)
print("DEBUG 3 ")

2. 确保编译时正确添加ASan链接参数

编译库时,仅加编译参数不够,必须同步添加链接参数。修改cmake配置:

SET(AXULIARY_COMPILE_FLAGS "-g -Og -fsanitize=address -fno-omit-frame-pointer")
SET(AXULIARY_LINK_FLAGS "-fsanitize=address")

# 将参数应用到目标库
target_compile_options(MMFFsp3_lib PRIVATE ${AXULIARY_COMPILE_FLAGS})
target_link_options(MMFFsp3_lib PRIVATE ${AXULIARY_LINK_FLAGS})

这样库会与ASan动态链接,配合LD_PRELOAD即可正常加载。

3. 静态链接ASan的正确配置

如果需要静态链接ASan,需在编译和链接阶段都添加-static-libasan参数:

SET(AXULIARY_COMPILE_FLAGS "-g -Og -fsanitize=address -fno-omit-frame-pointer -static-libasan")
SET(AXULIARY_LINK_FLAGS "-fsanitize=address -static-libasan")

target_compile_options(MMFFsp3_lib PRIVATE ${AXULIARY_COMPILE_FLAGS})
target_link_options(MMFFsp3_lib PRIVATE ${AXULIARY_LINK_FLAGS})

静态链接后无需LD_PRELOAD,直接用ctypes加载库即可,但会增大库体积,需注意环境兼容性。


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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.26 19:00:19