void setupSys() { sys_modules_dict = new BoxedDict(); constants.push_back(sys_modules_dict); // This is ok to call here because we've already created the sys_modules_dict sys_module = createModule(autoDecref(boxString("sys"))); // sys_module is what holds on to all of the other modules: Py_INCREF(sys_module); late_constants.push_back(sys_module); sys_module->giveAttrBorrowed("modules", sys_modules_dict); BoxedList* sys_path = new BoxedList(); constants.push_back(sys_path); sys_module->giveAttrBorrowed("path", sys_path); sys_module->giveAttr("argv", new BoxedList()); sys_module->giveAttr("exc_info", new BoxedBuiltinFunctionOrMethod(FunctionMetadata::create((void*)sysExcInfo, BOXED_TUPLE, 0), "exc_info", exc_info_doc)); sys_module->giveAttr("exc_clear", new BoxedBuiltinFunctionOrMethod(FunctionMetadata::create((void*)sysExcClear, NONE, 0), "exc_clear", exc_clear_doc)); sys_module->giveAttr( "exit", new BoxedBuiltinFunctionOrMethod(FunctionMetadata::create((void*)sysExit, NONE, 1, false, false), "exit", { None }, NULL, exit_doc)); sys_module->giveAttr("warnoptions", new BoxedList()); sys_module->giveAttrBorrowed("py3kwarning", Py_False); sys_module->giveAttr("byteorder", boxString(isLittleEndian() ? "little" : "big")); sys_module->giveAttr("platform", boxString(Py_GetPlatform())); sys_module->giveAttr("executable", boxString(Py_GetProgramFullPath())); sys_module->giveAttr( "_getframe", new BoxedFunction(FunctionMetadata::create((void*)sysGetFrame, UNKNOWN, 1, false, false), { NULL })); sys_module->giveAttr("_current_frames", new BoxedFunction(FunctionMetadata::create((void*)sysCurrentFrames, UNKNOWN, 0))); sys_module->giveAttr("getdefaultencoding", new BoxedBuiltinFunctionOrMethod( FunctionMetadata::create((void*)sysGetDefaultEncoding, STR, 0), "getdefaultencoding", getdefaultencoding_doc)); sys_module->giveAttr("getfilesystemencoding", new BoxedBuiltinFunctionOrMethod( FunctionMetadata::create((void*)sysGetFilesystemEncoding, STR, 0), "getfilesystemencoding", getfilesystemencoding_doc)); sys_module->giveAttr("getrecursionlimit", new BoxedBuiltinFunctionOrMethod( FunctionMetadata::create((void*)sysGetRecursionLimit, UNKNOWN, 0), "getrecursionlimit", getrecursionlimit_doc)); // As we don't support compile() etc yet force 'dont_write_bytecode' to true. sys_module->giveAttrBorrowed("dont_write_bytecode", Py_True); sys_module->giveAttr("prefix", boxString(Py_GetPrefix())); sys_module->giveAttr("exec_prefix", boxString(Py_GetExecPrefix())); sys_module->giveAttr("copyright", boxString("Copyright 2014-2016 Dropbox.\nAll Rights Reserved.\n\nCopyright (c) 2001-2014 " "Python Software Foundation.\nAll Rights Reserved.\n\nCopyright (c) 2000 " "BeOpen.com.\nAll Rights Reserved.\n\nCopyright (c) 1995-2001 Corporation for " "National Research Initiatives.\nAll Rights Reserved.\n\nCopyright (c) " "1991-1995 Stichting Mathematisch Centrum, Amsterdam.\nAll Rights Reserved.")); sys_module->giveAttr("version", boxString(generateVersionString())); sys_module->giveAttr("hexversion", boxInt(PY_VERSION_HEX)); sys_module->giveAttr("subversion", BoxedTuple::create({ autoDecref(boxString("Pyston")), autoDecref(boxString("")), autoDecref(boxString("")) })); sys_module->giveAttr("maxint", boxInt(PYSTON_INT_MAX)); sys_module->giveAttr("maxsize", boxInt(PY_SSIZE_T_MAX)); sys_flags_cls = BoxedClass::create(type_cls, object_cls, 0, 0, sizeof(BoxedSysFlags), false, "flags", false, NULL, NULL, false); sys_flags_cls->giveAttr( "__new__", new BoxedFunction(FunctionMetadata::create((void*)BoxedSysFlags::__new__, UNKNOWN, 1, true, true))); sys_flags_cls->tp_dealloc = (destructor)BoxedSysFlags::dealloc; #define ADD(name) sys_flags_cls->giveAttrMember(STRINGIFY(name), T_OBJECT, offsetof(BoxedSysFlags, name)); ADD(division_warning); ADD(bytes_warning); ADD(no_user_site); ADD(optimize); #undef ADD #define SET_SYS_FROM_STRING(key, value) sys_module->giveAttr((key), (value)) #ifdef Py_USING_UNICODE SET_SYS_FROM_STRING("maxunicode", PyInt_FromLong(PyUnicode_GetMax())); #endif /* float repr style: 0.03 (short) vs 0.029999999999999999 (legacy) */ #ifndef PY_NO_SHORT_FLOAT_REPR SET_SYS_FROM_STRING("float_repr_style", PyString_FromString("short")); #else SET_SYS_FROM_STRING("float_repr_style", PyString_FromString("legacy")); #endif sys_flags_cls->freeze(); auto sys_str = getStaticString("sys"); for (auto& md : sys_methods) { sys_module->giveAttr(md.ml_name, new BoxedCApiFunction(&md, NULL, sys_str)); } sys_module->giveAttrBorrowed("__displayhook__", sys_module->getattr(autoDecref(internStringMortal("displayhook")))); sys_module->giveAttr("flags", new BoxedSysFlags()); }
/* * Class: org_jpy_PyLib * Method: startPython0 * Signature: ([Ljava/lang/String;)Z */ JNIEXPORT jboolean JNICALL Java_org_jpy_PyLib_startPython0 (JNIEnv* jenv, jclass jLibClass, jobjectArray jPathArray) { int pyInit = Py_IsInitialized(); JPy_DIAG_PRINT(JPy_DIAG_F_ALL, "PyLib_startPython: entered: jenv=%p, pyInit=%d, JPy_Module=%p\n", jenv, pyInit, JPy_Module); if (!pyInit) { Py_Initialize(); PyLib_RedirectStdOut(); pyInit = Py_IsInitialized(); } if (pyInit) { if (JPy_DiagFlags != 0) { printf("PyLib_startPython: global Python interpreter information:\n"); #if defined(JPY_COMPAT_33P) printf(" Py_GetProgramName() = \"%ls\"\n", Py_GetProgramName()); printf(" Py_GetPrefix() = \"%ls\"\n", Py_GetPrefix()); printf(" Py_GetExecPrefix() = \"%ls\"\n", Py_GetExecPrefix()); printf(" Py_GetProgramFullPath() = \"%ls\"\n", Py_GetProgramFullPath()); printf(" Py_GetPath() = \"%ls\"\n", Py_GetPath()); printf(" Py_GetPythonHome() = \"%ls\"\n", Py_GetPythonHome()); #elif defined(JPY_COMPAT_27) printf(" Py_GetProgramName() = \"%s\"\n", Py_GetProgramName()); printf(" Py_GetPrefix() = \"%s\"\n", Py_GetPrefix()); printf(" Py_GetExecPrefix() = \"%s\"\n", Py_GetExecPrefix()); printf(" Py_GetProgramFullPath() = \"%s\"\n", Py_GetProgramFullPath()); printf(" Py_GetPath() = \"%s\"\n", Py_GetPath()); printf(" Py_GetPythonHome() = \"%s\"\n", Py_GetPythonHome()); #endif printf(" Py_GetVersion() = \"%s\"\n", Py_GetVersion()); printf(" Py_GetPlatform() = \"%s\"\n", Py_GetPlatform()); printf(" Py_GetCompiler() = \"%s\"\n", Py_GetCompiler()); printf(" Py_GetBuildInfo() = \"%s\"\n", Py_GetBuildInfo()); } // If we've got jPathArray, add all entries to Python's "sys.path" // if (jPathArray != NULL) { PyObject* pyPathList; PyObject* pyPath; jstring jPath; jsize i, pathCount; pathCount = (*jenv)->GetArrayLength(jenv, jPathArray); //printf(">> pathCount=%d\n", pathCount); if (pathCount > 0) { JPy_BEGIN_GIL_STATE pyPathList = PySys_GetObject("path"); //printf(">> pyPathList=%p, len=%ld\n", pyPathList, PyList_Size(pyPathList)); if (pyPathList != NULL) { Py_INCREF(pyPathList); for (i = pathCount - 1; i >= 0; i--) { jPath = (*jenv)->GetObjectArrayElement(jenv, jPathArray, i); //printf(">> i=%d, jPath=%p\n", i, jPath); if (jPath != NULL) { pyPath = JPy_FromJString(jenv, jPath); //printf(">> i=%d, pyPath=%p\n", i, pyPath); if (pyPath != NULL) { PyList_Insert(pyPathList, 0, pyPath); } } } Py_DECREF(pyPathList); } //printf(">> pyPathList=%p, len=%ld\n", pyPathList, PyList_Size(pyPathList)); //printf(">> pyPathList=%p, len=%ld (check)\n", PySys_GetObject("path"), PyList_Size(PySys_GetObject("path"))); JPy_END_GIL_STATE } }
std::string PySetup::get_platform() { return Py_GetPlatform(); }
void setupSys() { sys_modules_dict = new BoxedDict(); PyThreadState_GET()->interp->modules = incref(sys_modules_dict); constants.push_back(sys_modules_dict); // This is ok to call here because we've already created the sys_modules_dict sys_module = createModule(autoDecref(boxString("sys"))); // sys_module is what holds on to all of the other modules: Py_INCREF(sys_module); late_constants.push_back(sys_module); sys_module->giveAttrBorrowed("modules", sys_modules_dict); BoxedList* sys_path = new BoxedList(); constants.push_back(sys_path); sys_module->giveAttrBorrowed("path", sys_path); sys_module->giveAttr("argv", new BoxedList()); sys_module->giveAttr("exc_info", new BoxedBuiltinFunctionOrMethod(BoxedCode::create((void*)sysExcInfo, BOXED_TUPLE, 0, "exc_info", exc_info_doc))); sys_module->giveAttr("exc_clear", new BoxedBuiltinFunctionOrMethod( BoxedCode::create((void*)sysExcClear, NONE, 0, "exc_clear", exc_clear_doc))); sys_module->giveAttr( "exit", new BoxedBuiltinFunctionOrMethod( BoxedCode::create((void*)sysExit, NONE, 1, false, false, "exit", exit_doc), { Py_None }, NULL)); sys_module->giveAttr("warnoptions", new BoxedList()); sys_module->giveAttrBorrowed("py3kwarning", Py_False); sys_module->giveAttr("byteorder", boxString(isLittleEndian() ? "little" : "big")); sys_module->giveAttr("platform", boxString(Py_GetPlatform())); sys_module->giveAttr("executable", boxString(Py_GetProgramFullPath())); sys_module->giveAttr( "_getframe", new BoxedFunction(BoxedCode::create((void*)sysGetFrame, UNKNOWN, 1, false, false, "_getframe"), { NULL })); sys_module->giveAttr("_current_frames", new BoxedFunction(BoxedCode::create((void*)sysCurrentFrames, UNKNOWN, 0, "_current_frames"))); sys_module->giveAttr("getdefaultencoding", new BoxedBuiltinFunctionOrMethod(BoxedCode::create( (void*)sysGetDefaultEncoding, STR, 0, "getdefaultencoding", getdefaultencoding_doc))); sys_module->giveAttr("getfilesystemencoding", new BoxedBuiltinFunctionOrMethod(BoxedCode::create( (void*)sysGetFilesystemEncoding, STR, 0, "getfilesystemencoding", getfilesystemencoding_doc))); sys_module->giveAttr("getrecursionlimit", new BoxedBuiltinFunctionOrMethod(BoxedCode::create( (void*)sysGetRecursionLimit, UNKNOWN, 0, "getrecursionlimit", getrecursionlimit_doc))); sys_module->giveAttr("dont_write_bytecode", boxBool(Py_DontWriteBytecodeFlag)); sys_module->giveAttr("prefix", boxString(Py_GetPrefix())); sys_module->giveAttr("exec_prefix", boxString(Py_GetExecPrefix())); sys_module->giveAttr("copyright", boxString("Copyright 2014-2016 Dropbox.\nAll Rights Reserved.\n\nCopyright (c) 2001-2014 " "Python Software Foundation.\nAll Rights Reserved.\n\nCopyright (c) 2000 " "BeOpen.com.\nAll Rights Reserved.\n\nCopyright (c) 1995-2001 Corporation for " "National Research Initiatives.\nAll Rights Reserved.\n\nCopyright (c) " "1991-1995 Stichting Mathematisch Centrum, Amsterdam.\nAll Rights Reserved.")); sys_module->giveAttr("version", boxString(generateVersionString())); sys_module->giveAttr("hexversion", boxInt(PY_VERSION_HEX)); sys_module->giveAttr("subversion", BoxedTuple::create({ autoDecref(boxString("Pyston")), autoDecref(boxString("")), autoDecref(boxString("")) })); sys_module->giveAttr("maxint", boxInt(PYSTON_INT_MAX)); sys_module->giveAttr("maxsize", boxInt(PY_SSIZE_T_MAX)); #define SET_SYS_FROM_STRING(key, value) sys_module->giveAttr((key), (value)) #ifdef Py_USING_UNICODE SET_SYS_FROM_STRING("maxunicode", PyInt_FromLong(PyUnicode_GetMax())); #endif /* float repr style: 0.03 (short) vs 0.029999999999999999 (legacy) */ #ifndef PY_NO_SHORT_FLOAT_REPR SET_SYS_FROM_STRING("float_repr_style", PyString_FromString("short")); #else SET_SYS_FROM_STRING("float_repr_style", PyString_FromString("legacy")); #endif auto sys_str = getStaticString("sys"); for (auto& md : sys_methods) { sys_module->giveAttr(md.ml_name, new BoxedCApiFunction(&md, NULL, sys_str)); } sys_module->giveAttrBorrowed("__displayhook__", sys_module->getattr(autoDecref(internStringMortal("displayhook")))); }
void setupSys() { sys_modules_dict = new BoxedDict(); gc::registerPermanentRoot(sys_modules_dict); // This is ok to call here because we've already created the sys_modules_dict sys_module = createModule("sys"); sys_module->giveAttr("modules", sys_modules_dict); BoxedList* sys_path = new BoxedList(); sys_module->giveAttr("path", sys_path); sys_module->giveAttr("argv", new BoxedList()); sys_module->giveAttr("stdout", new BoxedFile(stdout, "<stdout>", "w")); sys_module->giveAttr("stdin", new BoxedFile(stdin, "<stdin>", "r")); sys_module->giveAttr("stderr", new BoxedFile(stderr, "<stderr>", "w")); sys_module->giveAttr("__stdout__", sys_module->getattr(internStringMortal("stdout"))); sys_module->giveAttr("__stdin__", sys_module->getattr(internStringMortal("stdin"))); sys_module->giveAttr("__stderr__", sys_module->getattr(internStringMortal("stderr"))); sys_module->giveAttr( "exc_info", new BoxedBuiltinFunctionOrMethod(boxRTFunction((void*)sysExcInfo, BOXED_TUPLE, 0), "exc_info")); sys_module->giveAttr("exc_clear", new BoxedBuiltinFunctionOrMethod(boxRTFunction((void*)sysExcClear, NONE, 0), "exc_clear")); sys_module->giveAttr("exit", new BoxedBuiltinFunctionOrMethod( boxRTFunction((void*)sysExit, NONE, 1, 1, false, false), "exit", { None })); sys_module->giveAttr("warnoptions", new BoxedList()); sys_module->giveAttr("py3kwarning", False); sys_module->giveAttr("byteorder", boxString(isLittleEndian() ? "little" : "big")); sys_module->giveAttr("platform", boxString(Py_GetPlatform())); sys_module->giveAttr("executable", boxString(Py_GetProgramFullPath())); sys_module->giveAttr("_getframe", new BoxedFunction(boxRTFunction((void*)sysGetFrame, UNKNOWN, 1, 1, false, false), { NULL })); sys_module->giveAttr( "getdefaultencoding", new BoxedBuiltinFunctionOrMethod(boxRTFunction((void*)sysGetDefaultEncoding, STR, 0), "getdefaultencoding")); sys_module->giveAttr("getfilesystemencoding", new BoxedBuiltinFunctionOrMethod(boxRTFunction((void*)sysGetFilesystemEncoding, STR, 0), "getfilesystemencoding")); sys_module->giveAttr( "getrecursionlimit", new BoxedBuiltinFunctionOrMethod(boxRTFunction((void*)sysGetRecursionLimit, UNKNOWN, 0), "getrecursionlimit")); sys_module->giveAttr("meta_path", new BoxedList()); sys_module->giveAttr("path_hooks", new BoxedList()); sys_module->giveAttr("path_importer_cache", new BoxedDict()); // As we don't support compile() etc yet force 'dont_write_bytecode' to true. sys_module->giveAttr("dont_write_bytecode", True); sys_module->giveAttr("prefix", boxString(Py_GetPrefix())); sys_module->giveAttr("exec_prefix", boxString(Py_GetExecPrefix())); sys_module->giveAttr("copyright", boxString("Copyright 2014-2015 Dropbox.\nAll Rights Reserved.\n\nCopyright (c) 2001-2014 " "Python Software Foundation.\nAll Rights Reserved.\n\nCopyright (c) 2000 " "BeOpen.com.\nAll Rights Reserved.\n\nCopyright (c) 1995-2001 Corporation for " "National Research Initiatives.\nAll Rights Reserved.\n\nCopyright (c) " "1991-1995 Stichting Mathematisch Centrum, Amsterdam.\nAll Rights Reserved.")); sys_module->giveAttr("version", boxString(generateVersionString())); sys_module->giveAttr("hexversion", boxInt(PY_VERSION_HEX)); // TODO: this should be a "sys.version_info" object, not just a tuple (ie can access fields by name) sys_module->giveAttr("version_info", BoxedTuple::create({ boxInt(PYTHON_VERSION_MAJOR), boxInt(PYTHON_VERSION_MINOR), boxInt(PYTHON_VERSION_MICRO), boxString("beta"), boxInt(0) })); sys_module->giveAttr("maxint", boxInt(PYSTON_INT_MAX)); sys_module->giveAttr("maxsize", boxInt(PY_SSIZE_T_MAX)); sys_flags_cls = new (0) BoxedHeapClass(object_cls, BoxedSysFlags::gcHandler, 0, 0, sizeof(BoxedSysFlags), false, static_cast<BoxedString*>(boxString("flags"))); sys_flags_cls->giveAttr("__new__", new BoxedFunction(boxRTFunction((void*)BoxedSysFlags::__new__, UNKNOWN, 1, 0, true, true))); #define ADD(name) \ sys_flags_cls->giveAttr(STRINGIFY(name), \ new BoxedMemberDescriptor(BoxedMemberDescriptor::OBJECT, offsetof(BoxedSysFlags, name))) ADD(division_warning); ADD(bytes_warning); ADD(no_user_site); ADD(optimize); #undef ADD #define SET_SYS_FROM_STRING(key, value) sys_module->giveAttr((key), (value)) #ifdef Py_USING_UNICODE SET_SYS_FROM_STRING("maxunicode", PyInt_FromLong(PyUnicode_GetMax())); #endif sys_flags_cls->tp_mro = BoxedTuple::create({ sys_flags_cls, object_cls }); sys_flags_cls->freeze(); for (auto& md : sys_methods) { sys_module->giveAttr(md.ml_name, new BoxedCApiFunction(&md, sys_module)); } sys_module->giveAttr("__displayhook__", sys_module->getattr(internStringMortal("displayhook"))); sys_module->giveAttr("flags", new BoxedSysFlags()); }
static void smisk_crash_sighandler(int signum, siginfo_t* info, void*ptr) { FILE *out = NULL; char out_fn[PATH_MAX]; char cwd_buf[PATH_MAX]; char *cwd = NULL; struct tm *t; time_t timer; size_t i = 0; const char *found_gdb_path; char cmd[1024]; // Signal code table (from http://www.opengroup.org/onlinepubs/007908799/xsh/signal.h.html) static const char *si_codes[][9] = { {"", "", "", "", "", "", "", "", ""}, {"", "", "", "", "", "", "", "", ""}, {"", "", "", "", "", "", "", "", ""}, {"", "ILL_ILLOPC\tillegal opcode", "ILL_ILLOPN\tillegal operand", "ILL_ILLADR\tillegal addressing mode", "ILL_ILLTRP\tillegal trap", "ILL_PRVOPC\tprivileged opcode", "ILL_PRVREG\tprivileged register", "ILL_COPROC\tcoprocessor error", "ILL_BADSTK\tinternal stack error"}, // ILL {"", "", "", "", "", "", "", "", ""}, {"", "", "", "", "", "", "", "", ""}, {"", "", "", "", "", "", "", "", ""}, {"", "FPE_INTDIV\tinteger divide by zero", "FPE_INTOVF\tinteger overflow", "FPE_FLTDIV\tfloating point divide by zero", "FPE_FLTOVF\tfloating point overflow", "FPE_FLTUND\tfloating point underflow", "FPE_FLTRES\tfloating point inexact result", "FPE_FLTINV\tinvalid floating point operation", "FPE_FLTSUB\tsubscript out of range"}, // FPE {"", "", "", "", "", "", "", "", ""}, {"", "BUS_ADRALN\tinvalid address alignment", "BUS_ADRERR\tnon-existent physical address", "BUS_OBJERR\tobject specific hardware error", "", "", "", ""}, // BUS {"", "SEGV_MAPERR\taddress not mapped to object", "SEGV_ACCERR\tinvalid permissions for mapped object", "", "", "", "", "", ""} // SEGV }; // Possible paths to GDB static const char *gdb_path[] = { "/usr/bin/gdb", "/usr/local/bin/gdb", "/opt/local/bin/gdb", "/opt/bin/gdb", "/local/bin/gdb", NULL }; // Header fputs("FATAL: smisk died from ", stderr); switch(signum) { case SIGILL: fputs("Illegal instruction ", stderr); break; case SIGFPE: fputs("Floating-point exception ", stderr); break; case SIGBUS: fputs("Bus error ", stderr); break; case SIGSEGV: fputs("Segmentation violation ", stderr); break; } fprintf(stderr, "[%d] ", signum); fflush(stderr); // Construct filename smisk-YYYYMMDD-HHMMSS.PID.crash timer = time(NULL); t = localtime(&timer); cwd = getcwd(cwd_buf, PATH_MAX); sprintf(out_fn, "%s/smisk-%04d%02d%02d-%02d%02d%02d.%d.crash", (access(cwd ? cwd : ".", W_OK) == 0) ? (cwd ? cwd : ".") : "/tmp", 1900+t->tm_year, t->tm_mon+1, t->tm_mday, t->tm_hour, t->tm_min, t->tm_sec, getpid()); // Open file fprintf(stderr, "Writing crash dump to %s...\n", out_fn); out = fopen(out_fn, "w"); if (!out) out = stderr; // Basic info fprintf(out, "Time: %04d-%02d-%02d %02d:%02d:%02d\n", 1900+t->tm_year, t->tm_mon+1, t->tm_mday, t->tm_hour, t->tm_min, t->tm_sec); fprintf(out, "Process: %d\n", getpid()); fprintf(out, "Working directory: %s\n", cwd ? cwd : "?"); fprintf(out, "Python: %s %s\n", Py_GetProgramFullPath(), Py_GetVersion()); fprintf(out, "Smisk: %s (%s)\n", SMISK_VERSION, SMISK_BUILD_ID); #if HAVE_SYS_UTSNAME_H struct utsname un; if (uname(&un) == 0) { fprintf(out, "System: %s, %s, %s, %s\n", un.sysname, un.release, un.version, un.machine); fprintf(out, "Hostname: %s\n", un.nodename); } else #endif fprintf(out, "System: %s\n", Py_GetPlatform()); fprintf(out, "\n"); fprintf(out, "Signal: %d\n", signum); fprintf(out, "Errno: %d\n", info->si_errno); fprintf(out, "Code: %d\t%s\n", info->si_code, (signum > 0) ? si_codes[signum-1][info->si_code] : "?"); fprintf(out, "Address: %p\n", info->si_addr); // Find GDB i = 0; found_gdb_path = NULL; do { if (access(*(gdb_path+i), R_OK) == 0) { found_gdb_path = *(gdb_path+i); log_debug("found gdb at %s", found_gdb_path); break; } } while ( *(gdb_path + ++i) ); // Write backtrace fprintf(out, "\nBacktrace:\n"); if (found_gdb_path) { fclose(out); system("/bin/echo 'backtrace' > /tmp/smisk_gdb_args"); sprintf(cmd, "%s -batch -x /tmp/smisk_gdb_args %s %d >> %s", found_gdb_path, Py_GetProgramFullPath(), getpid(), out_fn); system(cmd); } else { log_error("Note: GDB not found. Install GDB to get a more detailed backtrace."); smisk_crash_write_backtrace(info, ptr, out); fclose(out); } //exit(-1); _exit(-1); }