I have an application where I'm embedding python. It was developed on windows where it works fine, but now I'm porting it to linux with less success where it crashes in Py_Initialize(). From gdb, it seems to happen when loading the os module.
gdb reports this callstack on seg fault:
#0 0x002384fc in import_submodule (mod=None, subname=0xb7d8a9bb "os", fullname=0xb7d8a9bb "os") at ../Python/import.c:2551
#1 0x0023893c in load_next (mod=<value optimized out>, altmod=<value optimized out>, p_name=0xb7d8a9ac, buf=0xb7d8a9bb "os", p_buflen=0xb7d8a9b4) at ../Python/import.c:2411
//.... etc...:
#65 0x002439de in Py_Initialize () at ../Python/pythonrun.c:361
source code of import_submodule in Python/import.c (downloaded from 2.6.5 python):
static PyObject *
import_submodule(PyObject *mod, char *subname, char *fullname)
{ //***************** THIS IS LINE 2551***************************
PyObject *modules = PyImport_GetModuleDict();
PyObject *m = NULL;
/* Require:
if mod == None: subname == fullname
else: mod.__name__ + "." + subname == fullname
*/
if ((m = PyDict_GetItemString(modules, fullname)) != NULL) {
Py_INCREF(m);
}
else {
PyObject *path, *loader = NULL;
char buf[MAXPATHLEN+1];
struct filedescr *fdp;
FILE *fp = NULL;
if (mod == Py_None)
path = NULL;
else {
path = PyObject_GetAttrString(mod, "__path__");
if (path == NULL) {
PyErr_Clear();
Py_INCREF(Py_None);
return Py_None;
}
}
buf[0] = '\0';
fdp = find_module(fullname, subname, path, buf, MAXPATHLEN+1,
&fp, &loader);
Py_XDECREF(path);
if (fdp == NULL) {
if (!PyErr_ExceptionMatches(PyExc_ImportError))
return NULL;
PyErr_Clear();
Py_INCREF(Py_None);
return Py_None;
}
m = load_module(fullname, fp, buf, fd开发者_C百科p->type, loader);
Py_XDECREF(loader);
if (fp)
fclose(fp);
if (!add_submodule(mod, m, fullname, subname, modules)) {
Py_XDECREF(m);
m = NULL;
}
}
return m;
}
Disassembly + part source + breakpoint:
2550 import_submodule(PyObject *mod, char *subname, char *fullname)
2551 {
0x002384f0 <+0>: push %ebp
0x002384f1 <+1>: mov %esp,%ebp
0x002384f3 <+3>: sub $0x1058,%esp
0x002384f9 <+9>: mov %ebx,-0xc(%ebp)
=> 0x002384fc <+12>: call 0x174787 <__i686.get_pc_thunk.bx>
0x00238501 <+17>: add $0x112af3,%ebx
0x00238507 <+23>: mov %esi,-0x8(%ebp)
0x0023850a <+26>: mov 0x8(%ebp),%esi
0x0023850d <+29>: mov %edi,-0x4(%ebp)
0x00238510 <+32>: mov %eax,-0x102c(%ebp)
0x00238516 <+38>: mov %edx,-0x1030(%ebp)
0x0023851c <+44>: mov %gs:0x14,%eax
What's happening here? Apparently some code from libpython2.6.so is loaded and run.
Try setting the Python home with Py_SetPythonHome before calling Py_Initialize. Start with hardcoded complete path to the python directory. Also make sure you are not mixing debug & release versions. Py_GetPath is a good API to see where all python is looking for modules - but dont know if it can be called before Py_Initialize.
char pySearchPath[] = "/users/abc/Python26";
Py_SetPythonHome(pySearchPath);
Py_Initialize();
PyRun_SimpleString("from time import time,ctime\n"
"print 'Today is',ctime(time())\n");
cerr << Py_GetPath() << endl;
精彩评论