instantiate python object within a c function called via ctypes
Posted
by
gwk
on Stack Overflow
See other posts from Stack Overflow
or by gwk
Published on 2012-12-04T18:57:32Z
Indexed on
2012/12/04
23:03 UTC
Read the original article
Hit count: 359
My embedded Python 3.3 program segfaults when I instantiate python objects from a c function called by ctypes.
After setting up the interpreter, I can successfully instantiate a python Int (as well as a custom c extension type) from c main:
#import <Python/Python.h>
#define LOGPY(x) \
{ fprintf(stderr, "%s: ", #x); PyObject_Print((PyObject*)(x), stderr, 0); fputc('\n', stderr); }
// c function to be called from python script via ctypes.
void instantiate() {
PyObject* instance = PyObject_CallObject((PyObject*)&PyLong_Type, NULL);
LOGPY(instance);
}
int main(int argc, char* argv[]) {
Py_Initialize();
instantiate(); // works fine
// run a script that calls instantiate() via ctypes.
FILE* scriptFile = fopen("emb.py", "r");
if (!scriptFile) {
fprintf(stderr, "ERROR: cannot open script file\n");
return 1;
}
PyRun_SimpleFileEx(scriptFile, scriptPath, 1); // close on completion
return 0;
}
I then run a python script using PyRun_SimpleFileEx. It appears to run just fine, but when it calls instantiate() via ctypes, the program segfaults inside PyObject_CallObject:
import ctypes as ct
dy = ct.CDLL('./emb')
dy.instantiate() # segfaults
lldb output:
instance: 0
Process 52068 stopped
* thread #1: tid = 0x1c03, 0x000000010000d3f5 Python`PyObject_Call + 69, stop reason = EXC_BAD_ACCESS (code=1, address=0x18)
frame #0: 0x000000010000d3f5 Python`PyObject_Call + 69
Python`PyObject_Call + 69:
-> 0x10000d3f5: movl 24(%rax), %edx
0x10000d3f8: incl %edx
0x10000d3fa: movl %edx, 24(%rax)
0x10000d3fd: leaq 2069148(%rip), %rax ; _Py_CheckRecursionLimit
(lldb) bt
* thread #1: tid = 0x1c03, 0x000000010000d3f5 Python`PyObject_Call + 69, stop reason = EXC_BAD_ACCESS (code=1, address=0x18)
frame #0: 0x000000010000d3f5 Python`PyObject_Call + 69
frame #1: 0x00000001000d5197 Python`PyEval_CallObjectWithKeywords + 87
frame #2: 0x0000000201100d8e emb`instantiate + 30 at emb.c:9
Why does the call to instantiate() fail from ctypes only? The function only crashes when it calls into the python lib, so perhaps some interpreter state is getting munged by the ctypes FFI call?
© Stack Overflow or respective owner