ctypes memmove时发生segmentation fault

sophistcxf 2014-06-05 11:27:19
data = dll.fun(byref(out_len))
// data是.so中返回的字符串buffer,out_len是其长度。
然后我执行下面的语句:
addr = create_string_buffer(out_len)
memmove(addr, data, out_len)

此时如果out_len比较小(大概在几万以下),则没有问题,但是如果out_len比较大(50W以上),则会在memmove的时候发生segmentation fault。请问这是为什么?

我猜想的几点原因:
1. 在create_string_buffer时就已经出错了,但是pdb后发现addr的内存地址是正常的,有什么办法可以知道create_string_buffer是否成功?
2. 创建的buffer太大,但是 500K而已,应该不算大吧。如果真的是太大了,超过了python栈空间的大小,那么有什么办法可以增加python的栈空间吗?
3. memmove有其限制大小。

关于ctypes这部分的资料好像不是很详细,有哪位有更好的资源吗?谢谢。

下面是我写的一个小例子:

// dll.h
extern "C" {
struct DataHandle;
DataHandle* create_data_handle();
void destroy_data_handle(DataHandle* handle);
const char* output_string(DataHandle*, int, int*);
}

// dll.cpp
#include <stdlib.h>
#include "dll.h"
#include <string.h>
#include <string>
#include <sstream>

struct DataHandle {
std::string m_str_data;
};

DataHandle* create_data_handle() {
return new DataHandle;
}

void destroy_data_handle(DataHandle* handle) {
if (handle != NULL) {
delete handle;
}
}

const char* output_string(DataHandle* handle, int line_num, int* outlen) {
std::stringstream ss;
for (int i = 0; i < line_num; ++i) {
ss << "This is line " << i << "\n";
}
handle->m_str_data = ss.str();
*outlen = handle->m_str_data.size();
return handle->m_str_data.c_str();
}


编为dll.so


from ctypes import *
import os
import pdb

class OutInt(Structure):
_fields_ = [('v', c_int)]

out_len = OutInt()

line_num = 50000
dll = cdll.LoadLibrary(os.getcwd()+'/dll.so')
handle = dll.create_data_handle()
data = dll.output_string(handle, line_num, byref(out_len))
print "out len : ", out_len.v
addr = create_string_buffer(out_len.v*10)
pdb.set_trace()
memmove(addr, data, out_len.v)

for i in addr.value.strip().split('\n'):
print i

现在程序成败取决于line_num的大小。。
...全文
157 回复 打赏 收藏 转发到动态 举报
写回复
用AI写文章
回复
切换为时间正序
请发表友善的回复…
发表回复

37,718

社区成员

发帖
与我相关
我的任务
社区描述
JavaScript,VBScript,AngleScript,ActionScript,Shell,Perl,Ruby,Lua,Tcl,Scala,MaxScript 等脚本语言交流。
社区管理员
  • 脚本语言(Perl/Python)社区
  • IT.BOB
加入社区
  • 近7日
  • 近30日
  • 至今

试试用AI创作助手写篇文章吧