在Python中使用Go共享库时遇到“指针被释放但未分配”的错误。

huangapple go评论97阅读模式
英文:

Getting "pointer being freed was not allocated" error with using a go shared lib in python

问题

这里发生了什么情况?

这个错误是由于在运行PyCharm中的共享库时出现的。错误信息表明指针被释放,但并没有分配内存给它。这可能是由于在C代码中的FreeCString函数中出现了问题。

根据你提供的代码,我看到你在Go代码中使用了C.free函数来释放内存,但是在C代码中并没有看到相应的内存分配操作。这可能导致了指针被释放但未分配的错误。

你可以检查一下在Go代码中是否有其他地方分配了内存给这个指针,或者在FreeCString函数中确保只有在指针被分配内存后才进行释放操作。

另外,你的Python代码中也有一个问题。在调用FreeCString函数之后,你打印了指针b的值,但是在释放内存后,指针已经无效,所以打印的结果可能是不可预测的。你可以尝试将打印语句放在释放内存之前。

希望这些信息对你有帮助!如果你有任何其他问题,请随时提问。

英文:

I keep on getting this error whenever I run the shared lib in pycharm:

Python(20566,0x116d67dc0) malloc: *** error for object 0x5b6222f0: pointer being freed was not allocated
Python(20566,0x116d67dc0) malloc: *** set a breakpoint in malloc_error_break to debug
Abort trap: 6

Here is my go code turned into a share lib:

package main

// #include <stdio.h>
// #include <stdlib.h>
// #include <errno.h>
import "C"


//export FreeCString
func FreeCString(ptr *C.char) {
	C.free(unsafe.Pointer(ptr))
}

//export TestString
func TestString() *C.char {
	return C.CString("Hello World")
}

Here is my py code:

from ctypes import *
from ctypes import cdll

lib = cdll.LoadLibrary('./test.so')

b = lib.TestString()
lib.FreeCString(b)
print(b)

What is happening here?

答案1

得分: 2

首先,你在释放之后调用了print(b),这显然是一个坏主意。

更重要的是,你没有告诉Python关于lib.TestString返回类型,所以Python会做出假设。特别是:

> b = lib.TestString()

由于你没有设置lib.TestString.restype,Python认为返回类型是普通的int。所以b被设置为一个32位的int,它是从一个64位的c_void_p中丢弃了32位而得到的。(要修复这个问题,restype设置为c_void_p。对于你调用的所有函数,你也应该设置argtypes,尽管在你可能使用的机器上,这可能不重要。)

> lib.FreeCString(b)

这将间接调用free((void *)(int)malloc(some_size))。由于指针值经过int的传递而受损,free调用立即失败,程序在到达应该存储在b中的值的错误使用之前停止。

英文:

For one thing, you're calling print(b) after freeing it, which is clearly a bad idea.

Probably more important, you never told Python about lib.TestString's return type, so Python will make assumptions. In particular:

> b = lib.TestString()

Since you never set lib.TestString.restype, Python believes the return type is plain int. So b is set to a 32-bit int that results from throwing away 32 of the 64 bits of a 64-bit c_void_p. (To fix this, set the restype to c_void_p. You should set the argtypes as well for all functions you call, although on the machine you're probably using, this probably won't matter.)

> lib.FreeCString(b)

This then calls, indirectly, free((void *)(int)malloc(some_size)). As the pointer value has been damaged by the passage through int, the free call fails right then, stopping the program before you get to the bad use-after-free of the value that should have been stored in b.

huangapple
  • 本文由 发表于 2021年10月2日 06:27:29
  • 转载请务必保留本文链接:https://go.coder-hub.com/69412515.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定