我在 C 中有一个函数,用于扩展 python,之前使用 BOOST_MODULE 函数来完成此操作。转换到 python-C API 时出现此错误。我确信 run_mymodule 函数在没有这个包装器的情况下运行良好。

static PyObject * wrap_run_mymodule(PyObject *, PyObject *args) { 
    char *file1, *file2, *file3; 
    PyObject *tmpp; 
    if(!PyArg_ParseTuple(args, "sssO", &file1, &file2, &file3, &tmpp)) 
        return NULL; 
    return Py_BuildValue("i", run_mymodule(file1, file2, file3, tmpp)); 
} 
 
static PyMethodDef myModule_methods[] = { 
    {"run_mymodule", (PyCFunction) wrap_run_mymodule, METH_VARARGS}, 
    {NULL, NULL} 
}; 
 
extern "C" void initmymodule(void) 
{ 
    (void) Py_InitModule("mymodule", myModule_methods); 
} 

函数的声明是这样的形式:int run_mymodule(char *file1, char *file2, char *file3, PyObject *tmpp)

这是我收到的确切错误消息:

 python(35137,0x7fff76453310) malloc: *** error for object 0x10afcfb78: pointer being freed was not allocated 
*** set a breakpoint in malloc_error_break to debug 
 Abort trap: 6 

我该如何解决这个问题?这个 malloc 错误来自哪里?在 python 中,我将字符串作为前三个参数传递,将 python 类作为第四个参数传递。当然,我很乐意将探针放入我的代码中。

SanderMertens 建议我发布 valgrind 输出-

$ valgrind python test_mymodule.py 
==30715== Memcheck, a memory error detector 
==30715== Copyright (C) 2002-2013, and GNU GPL'd, by Julian Seward et al. 
==30715== Using Valgrind-3.10.1 and LibVEX; rerun with -h for copyright info 
==30715== Command: python test_mymodule.py 
==30715==  
==30715== Syscall param posix_spawn(pid) points to unaddressable byte(s) 
==30715==    at 0x3D266E: __posix_spawn (in /usr/lib/system/libsystem_kernel.dylib) 
==30715==    by 0x100001DC2: ??? (in /usr/local/bin/python) 
==30715==    by 0x25E5FC: start (in /usr/lib/system/libdyld.dylib) 
==30715==    by 0x1: ??? 
==30715==    by 0x1000138CF: ??? 
==30715==    by 0x104803AD1: ??? 
==30715==  Address 0x0 is not stack'd, malloc'd or (recently) free'd 
==30715==  
Python(30715,0x7fff74a8e310) malloc: *** mach_vm_map(size=140735173898240) failed (error code=3) 
*** error: can't allocate region 
*** set a breakpoint in malloc_error_break to debug 
libc++abi.dylib: terminating with uncaught exception of type std::bad_alloc: std::bad_alloc 
 Abort trap: 6 

请您参考如下方法:

正如现在在一些评论中所解释的那样,您遇到了内存损坏问题。关键指标是:

  • 问题重现不规律。
  • 确切的症状是从将意外的错误值传递到某些函数,到异常大的内存分配失败。
  • 当 run_module 的实现很简单时,其他人不会重现这些症状。

鉴于 valgrind 没有为您精确定位,这可能是堆栈损坏。您可以查找您的代码调用失败函数的地方(来自 valgrind)并查看您的代码在此之前做了什么,但这会很慢。

在这个阶段,您最好的选择是使用现有的堆栈验证工具。例如,假设您使用的是 gcc,请尝试 address sanitizer or mudflap功能(取决于您使用的版本)。


评论关闭
IT序号网

微信公众号号:IT虾米 (左侧二维码扫一扫)欢迎添加!