【问题标题】:Address Sanitizer on a python extension result in AddressSanitizer:DEADLYSIGNAL在 AddressSanitizer:DEADLYSIGNAL 中的 Python 扩展结果中的 Address Sanitizer
【发布时间】:2021-09-14 01:19:08
【问题描述】:

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, 0, 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 的 free 包装在 demo_c.c 中并调用它,而不是直接在 python 代码中直接调用 free,它就可以正常工作了。

【问题讨论】:

    标签: address-sanitizer ld-preload


    【解决方案1】:

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

    【讨论】:

    • 如果我不重新编译c代码,有没有asan_options可以解决这个问题?
    • 其实我只是希望这个python可以正常运行,因为我项目中的这个demo python脚本不是用来分离共享库的内存泄漏的。另一个任务会做。
    • @zzyy 在你的库中创建另一个函数以通过free 释放内存并调用它而不是libc.free
    猜你喜欢
    • 2017-10-09
    • 2022-01-23
    • 2015-09-17
    • 1970-01-01
    • 2021-09-22
    • 2015-11-16
    • 2019-06-06
    • 2016-12-25
    • 2020-07-01
    相关资源
    最近更新 更多