diff options
Diffstat (limited to 'Python/pythonrun.c')
| -rw-r--r-- | Python/pythonrun.c | 94 | 
1 files changed, 62 insertions, 32 deletions
| diff --git a/Python/pythonrun.c b/Python/pythonrun.c index bea7fe1..1888fba 100644 --- a/Python/pythonrun.c +++ b/Python/pythonrun.c @@ -62,6 +62,7 @@ static PyObject *run_mod(mod_ty, const char *, PyObject *, PyObject *,  static PyObject *run_pyc_file(FILE *, const char *, PyObject *, PyObject *,                                PyCompilerFlags *);  static void err_input(perrdetail *); +static void err_free(perrdetail *);  static void initsigs(void);  static void call_py_exitfuncs(void);  static void wait_for_thread_shutdown(void); @@ -70,6 +71,8 @@ extern void _PyUnicode_Init(void);  extern void _PyUnicode_Fini(void);  extern int _PyLong_Init(void);  extern void PyLong_Fini(void); +extern int _PyFaulthandler_Init(void); +extern void _PyFaulthandler_Fini(void);  #ifdef WITH_THREAD  extern void _PyGILState_Init(PyInterpreterState *, PyThreadState *); @@ -165,18 +168,25 @@ error:      return NULL;  } -#if defined(HAVE_LANGINFO_H) && defined(CODESET)  static char* -get_codeset(void) +get_locale_encoding(void)  { +#ifdef MS_WINDOWS +    char codepage[100]; +    PyOS_snprintf(codepage, sizeof(codepage), "cp%d", GetACP()); +    return get_codec_name(codepage); +#elif defined(HAVE_LANGINFO_H) && defined(CODESET)      char* codeset = nl_langinfo(CODESET);      if (!codeset || codeset[0] == '\0') {          PyErr_SetString(PyExc_ValueError, "CODESET is not set or empty");          return NULL;      }      return get_codec_name(codeset); -} +#else +    PyErr_SetNone(PyExc_NotImplementedError); +    return NULL;  #endif +}  void  Py_InitializeEx(int install_sigs) @@ -289,6 +299,10 @@ Py_InitializeEx(int install_sigs)      _PyImportHooks_Init(); +    /* initialize the faulthandler module */ +    if (_PyFaulthandler_Init()) +        Py_FatalError("Py_Initialize: can't initialize faulthandler"); +      /* Initialize _warnings. */      _PyWarnings_Init(); @@ -462,6 +476,9 @@ Py_Finalize(void)      /* Destroy the database used by _PyImport_{Fixup,Find}Extension */      _PyImport_Fini(); +    /* unload faulthandler module */ +    _PyFaulthandler_Fini(); +      /* Debugging stuff */  #ifdef COUNT_ALLOCS      dump_counts(stdout); @@ -736,24 +753,17 @@ static int  initfsencoding(PyInterpreterState *interp)  {      PyObject *codec; -#if defined(HAVE_LANGINFO_H) && defined(CODESET) -    char *codeset = NULL; - -    if (Py_FileSystemDefaultEncoding == NULL) { -        /* On Unix, set the file system encoding according to the -           user's preference, if the CODESET names a well-known -           Python codec, and Py_FileSystemDefaultEncoding isn't -           initialized by other means. */ -        codeset = get_codeset(); -        if (codeset == NULL) + +    if (Py_FileSystemDefaultEncoding == NULL) +    { +        Py_FileSystemDefaultEncoding = get_locale_encoding(); +        if (Py_FileSystemDefaultEncoding == NULL)              Py_FatalError("Py_Initialize: Unable to get the locale encoding"); -        Py_FileSystemDefaultEncoding = codeset;          Py_HasFileSystemDefaultEncoding = 0;          interp->fscodec_initialized = 1;          return 0;      } -#endif      /* the encoding is mbcs, utf-8 or ascii */      codec = _PyCodec_Lookup(Py_FileSystemDefaultEncoding); @@ -1585,7 +1595,7 @@ print_exception(PyObject *f, PyObject *value)          moduleName = PyObject_GetAttrString(type, "__module__");          if (moduleName == NULL || !PyUnicode_Check(moduleName))          { -            Py_DECREF(moduleName); +            Py_XDECREF(moduleName);              err = PyFile_WriteString("<unknown>", f);          }          else { @@ -1894,12 +1904,13 @@ PyParser_ASTFromString(const char *s, const char *filename, int start,          flags->cf_flags |= iflags & PyCF_MASK;          mod = PyAST_FromNode(n, flags, filename, arena);          PyNode_Free(n); -        return mod;      }      else {          err_input(&err); -        return NULL; +        mod = NULL;      } +    err_free(&err); +    return mod;  }  mod_ty @@ -1924,14 +1935,15 @@ PyParser_ASTFromFile(FILE *fp, const char *filename, const char* enc,          flags->cf_flags |= iflags & PyCF_MASK;          mod = PyAST_FromNode(n, flags, filename, arena);          PyNode_Free(n); -        return mod;      }      else {          err_input(&err);          if (errcode)              *errcode = err.error; -        return NULL; +        mod = NULL;      } +    err_free(&err); +    return mod;  }  /* Simplified interface to parsefile -- return node or set exception */ @@ -1945,6 +1957,7 @@ PyParser_SimpleParseFileFlags(FILE *fp, const char *filename, int start, int fla                                        start, NULL, NULL, &err, flags);      if (n == NULL)          err_input(&err); +    err_free(&err);      return n;  } @@ -1959,6 +1972,7 @@ PyParser_SimpleParseStringFlags(const char *str, int start, int flags)                                          start, &err, flags);      if (n == NULL)          err_input(&err); +    err_free(&err);      return n;  } @@ -1971,6 +1985,7 @@ PyParser_SimpleParseStringFlagsFilename(const char *str, const char *filename,                              &_PyParser_Grammar, start, &err, flags);      if (n == NULL)          err_input(&err); +    err_free(&err);      return n;  } @@ -1984,11 +1999,23 @@ PyParser_SimpleParseStringFilename(const char *str, const char *filename, int st     even parser modules. */  void +PyParser_ClearError(perrdetail *err) +{ +    err_free(err); +} + +void  PyParser_SetError(perrdetail *err)  {      err_input(err);  } +static void +err_free(perrdetail *err) +{ +    Py_CLEAR(err->filename); +} +  /* Set the error appropriate to the given input error code (see errcode.h) */  static void @@ -1996,7 +2023,6 @@ err_input(perrdetail *err)  {      PyObject *v, *w, *errtype, *errtext;      PyObject *msg_obj = NULL; -    PyObject *filename;      char *msg = NULL;      errtype = PyExc_SyntaxError; @@ -2082,17 +2108,8 @@ err_input(perrdetail *err)          errtext = PyUnicode_DecodeUTF8(err->text, strlen(err->text),                                         "replace");      } -    if (err->filename != NULL) -        filename = PyUnicode_DecodeFSDefault(err->filename); -    else { -        Py_INCREF(Py_None); -        filename = Py_None; -    } -    if (filename != NULL) -        v = Py_BuildValue("(NiiN)", filename, -                          err->lineno, err->offset, errtext); -    else -        v = NULL; +    v = Py_BuildValue("(OiiN)", err->filename, +                      err->lineno, err->offset, errtext);      if (v != NULL) {          if (msg_obj)              w = Py_BuildValue("(OO)", msg_obj, v); @@ -2116,11 +2133,24 @@ cleanup:  void  Py_FatalError(const char *msg)  { +    const int fd = fileno(stderr); +    PyThreadState *tstate; +      fprintf(stderr, "Fatal Python error: %s\n", msg);      fflush(stderr); /* it helps in Windows debug build */      if (PyErr_Occurred()) {          PyErr_PrintEx(0);      } +    else { +        tstate = _Py_atomic_load_relaxed(&_PyThreadState_Current); +        if (tstate != NULL) { +            fputc('\n', stderr); +            fflush(stderr); +            _Py_DumpTracebackThreads(fd, tstate->interp, tstate); +        } +        _PyFaulthandler_Fini(); +    } +  #ifdef MS_WINDOWS      {          size_t len = strlen(msg); | 
