2010-06-22 9 views
1

저는 파이썬을 임베드하는 애플리케이션이 있습니다. 그것은 잘 작동하는 창문에서 개발되었지만 지금은 Py_Initialize()에서 충돌이 적은 곳에서 리눅스로 이식하고 있습니다. gdb에서 os 모듈을로드 할 때 발생하는 것으로 보입니다.우분투에 파이썬을 임베드하는 동안 세분화 오류가 발생했습니다.

GDB 보고서 독방 감금 잘못에이 호출 스택 (2.6.5 파이썬에서 다운로드) 파이썬/import.c에서 import_submodule의

#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 

소스 코드 :

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, fdp->type, loader); 
     Py_XDECREF(loader); 
     if (fp) 
      fclose(fp); 
     if (!add_submodule(mod, m, fullname, subname, modules)) { 
      Py_XDECREF(m); 
      m = NULL; 
     } 
    } 

    return m; 
} 

분해 + 부분 소스 + 중단 점 :

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 

여기가 어떻게됩니까? 분명히 libpython2.6.so의 일부 코드가로드되어 실행됩니다.

+0

어떤 식 으로든 2551 행을 강조 표시하면 어떤 행이 충돌하는지 알 수 있으므로 도움이됩니다. –

답변

2

Py_Initialize를 호출하기 전에 Python 홈을 Py_SetPythonHome으로 설정해보십시오. 파이썬 디렉토리에 대한 하드 코드 된 완전한 경로로 시작하십시오. 또한 디버그 & 릴리스 버전을 혼합하지 않도록하십시오. Py_GetPath는 모든 파이썬이 모듈을 찾고있는 곳을 볼 수있는 좋은 API입니다. 그러나 Py_Initialize 전에 호출 할 수 있는지는 알 수 없습니다.

char pySearchPath[] = "https://stackoverflow.com/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; 
+0

Py_SetPythonHome이 작동했습니다! 감사! 충돌 선 번호가 몇 줄 벗어난 것 같아요. – Imbrondir

관련 문제