如何捕捉AddressSanitizer在通过python扩展访问的C++库中引发的错误

问题描述:

我有一个python模块,它使用外部C++库,使用带distutils的C++扩展构建。当我使用地址清理器编译C++库时,使用GCC的-fsanitize选项,运行单元测试时会出现段错误。现在,最初我以为是因为我为两个二进制文件,C++ python扩展和库使用了不同的编译器选项,但现在我越来越确信这是因为地址清理器在库中发现了一个错误,并触发了一个seg错误,如here所述。 这也支持这样一个事实,即如果我编译没有地址清理器的C++库,一切正常。 当我运行单元测试,程序输出的信息非常少:如何捕捉AddressSanitizer在通过python扩展访问的C++库中引发的错误

./run_unit_tests 
Segmentation fault (core dumped) 

即使看核心转储我只能找到指向C++库中的堆栈跟踪,但没有提及地址消毒剂。

我曾尝试使用ASAN_OPTIONS重定向消毒剂输出到一个文件,但消毒显然不会拿起选择:

ASAN_OPTIONS=help=1 ./run_unit_tests 
Segmentation fault (core dumped) 

我应该采取什么策略,在这里,以确认赛格故障COMS从卫生消毒剂,并可能发现它是什么样的错误?

+0

你说你看着核心转储,但你真的在调试器中运行它来追踪问题吗? –

+0

我已经尝试过,但不能真正获得大量信息,我不知道应该如何分析核心转储,我应该在启动gdb时指定python可执行文件还是C++库? – Perennialista

+0

@Perennialista一个选项是直接在GDB下运行你的app:'gdb -ex'set environment ASAN_OPTIONS = ...'-ex'set environment LD_PRELOAD = ...'--args/usr/bin/python ... ' – yugr

一是一些澄清:

这是因为消毒剂的地址找到了库是错误的,并引发了赛格故障

当阿三检测到错误,它总是会发出一个友好的错误信息。段错误意味着

  • 无论是仪表出了问题,在某些时候
  • 或(不太可能)改动的代码inadverently引起了一些已经存在的严重错误

这也被事实支持如果我用未定义的行为消毒剂编译C++库,一切工作正常

UBSan是很多比ASan更简单,所以一般来说你不能分享他们的结论。

我曾尝试使用ASAN_OPTIONS重定向消毒剂输出到一个文件,但消毒显然不会拿起选择:

help=1失败的事实告诉我们,消毒程序segfaulted早期在牙山能够解析ASAN_OPTIONS并做出适当反应之前,这通常发生在如何启用Asan的基本问题上。

我的猜测是,你错过了哪些应用阿三时想要一个DSO,而不是主要的应用(如与口译消毒C/C++插件的情况下,检查Asan FAQ)需要LD_PRELOAD=path/to/libasan.so环境设置。

如果这没有帮助,我建议提供更多信息(例如GCC版本,在segv点符号化堆栈)。

+0

我修改了原来的帖子,指定如果我使用C++库编译的没有地址清理器的python单元测试,它们会通过,但是如果我使用库的清理版本运行它们,我有一个SEGFAULT。 – Perennialista

+0

我试过LD_PRELOAD,但显然是错误的库,我找到了好的,现在我的Python单元测试工作!非常感谢@yugr,我会接受你的回答,并尝试用我最近的发现改善我的问题。 – Perennialista

+0

@Perennialista快乐黑客) – yugr