微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

python 扩展上的地址消毒剂导致 AddressSanitizer:DEADLYSIGNAL

如何解决python 扩展上的地址消毒剂导致 AddressSanitizer:DEADLYSIGNAL

c 源代码如下:

#include<stdlib.h>
#include<stdio.h>
#include "demo_c.h"

void func(data_pair* pair) {
  printf("func called");
  pair->len=4;
  pair->data = (char*)malloc(pair->len + 1);
  memset(pair->data,pair->len + 1);
  memcpy(pair->data,"test",4);
  return;
}

gcc -fpic -c demo_c.c -fno-omit-frame-pointer -fsanitize=address -fsanitize-recover=address
gcc --share demo_c.o -o libdemo_c.so

然后我像这样在python中导入这个库:

from ctypes import *
demo_c = CDLL('/xxx/libdemo_c.so',RTLD_GLOBAL)
libc = CDLL('libc.so.6')

libc.free.argtypes = [c_void_p]

class entry(Structure):
    _fields_ = [('len',c_int),('data',c_void_p)]

v = entry()
demo_c.func.argtypes = [c_void_p]
demo_c.func(byref(v))
libc.free(v.data)

然后我跑:

LD_PRELOAD=/lib64/libasan.so.5 python demo.py

输出为:

AddressSanitizer:DEADLYSIGNAL
=================================================================
==432489==ERROR: AddressSanitizer: BUS on unkNown address 0x000000000000 (pc 0x7f281c9c90fe bp 0x200000000000003 sp 0x7ffe0c369b20 T0)
    #0 0x7f281c9c90fd in _int_free (/lib64/libc.so.6+0x810fd)
    #1 0x7f281356cdcb in ffi_call_unix64 (/lib64/libffi.so.6+0x5dcb)
    #2 0x7f281356c6f4 in ffi_call (/lib64/libffi.so.6+0x56f4)
    #3 0x7f281377fc6a in _ctypes_callproc (/usr/lib64/python2.7/lib-dynload/_ctypes.so+0x10c6a)
    #4 0x7f2813779a64  (/usr/lib64/python2.7/lib-dynload/_ctypes.so+0xaa64)
    #5 0x7f281d687072 in PyObject_Call (/lib64/libpython2.7.so.1.0+0x4c072)
    #6 0x7f281d71b845 in PyEval_EvalFrameEx (/lib64/libpython2.7.so.1.0+0xe0845)
    #7 0x7f281d72264c in PyEval_EvalCodeEx (/lib64/libpython2.7.so.1.0+0xe764c)
    #8 0x7f281d722751 in PyEval_EvalCode (/lib64/libpython2.7.so.1.0+0xe7751)
    #9 0x7f281d73bb8e  (/lib64/libpython2.7.so.1.0+0x100b8e)
    #10 0x7f281d73cd5d in PyRun_FileExFlags (/lib64/libpython2.7.so.1.0+0x101d5d)
    #11 0x7f281d73dfe8 in PyRun_SimpleFileExFlags (/lib64/libpython2.7.so.1.0+0x102fe8)
    #12 0x7f281d74f19e in Py_Main (/lib64/libpython2.7.so.1.0+0x11419e)
    #13 0x7f281c96a554 in __libc_start_main (/lib64/libc.so.6+0x22554)
    #14 0x40068d  (/usr/bin/python2.7+0x40068d)

AddressSanitizer can not provide additional info.
SUMMARY: AddressSanitizer: BUS (/lib64/libc.so.6+0x810fd) in _int_free
==432489==ABORTING

但是如果我将 libc.so's free 包装在 demo_c.c 中并调用它而不是直接在 python 代码中直接调用 free,它工作正常。

解决方法

问题是您使用 Asan 的 malloc 分配内存,然后尝试使用 libc 的 free 释放它。这是行不通的,因为不同的分配器通常不兼容。

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。