(original) (raw)

changeset: 84502:65f2c92ed079 user: Victor Stinner victor.stinner@gmail.com date: Sun Jul 07 23:30:24 2013 +0200 files: Include/pymem.h Modules/_cursesmodule.c Modules/_pickle.c Modules/faulthandler.c Modules/main.c Modules/python.c Objects/obmalloc.c Python/pythonrun.c description: Issue #18203: Add _PyMem_RawStrdup() and _PyMem_Strdup() Replace strdup() with _PyMem_RawStrdup() or _PyMem_Strdup(), depending if the GIL is held or not. diff -r 31a635303e55 -r 65f2c92ed079 Include/pymem.h --- a/Include/pymem.h Sun Jul 07 22:57:45 2013 +0200 +++ b/Include/pymem.h Sun Jul 07 23:30:24 2013 +0200 @@ -58,6 +58,9 @@ PyAPI_FUNC(void *) PyMem_Realloc(void *ptr, size_t new_size); PyAPI_FUNC(void) PyMem_Free(void *ptr); +PyAPI_FUNC(char *) _PyMem_RawStrdup(const char *str); +PyAPI_FUNC(char *) _PyMem_Strdup(const char *str); + /* Macros. */ /* PyMem_MALLOC(0) means malloc(1). Some systems would return NULL diff -r 31a635303e55 -r 65f2c92ed079 Modules/_cursesmodule.c --- a/Modules/_cursesmodule.c Sun Jul 07 22:57:45 2013 +0200 +++ b/Modules/_cursesmodule.c Sun Jul 07 23:30:24 2013 +0200 @@ -529,7 +529,7 @@ wo = PyObject_NEW(PyCursesWindowObject, &PyCursesWindow_Type); if (wo == NULL) return NULL; wo->win = win; - wo->encoding = strdup(encoding); + wo->encoding = _PyMem_Strdup(encoding); if (wo->encoding == NULL) { Py_DECREF(wo); PyErr_NoMemory(); @@ -543,7 +543,7 @@ { if (wo->win != stdscr) delwin(wo->win); if (wo->encoding != NULL) - free(wo->encoding); + PyMem_Free(wo->encoding); PyObject_DEL(wo); } @@ -1938,13 +1938,13 @@ ascii = PyUnicode_AsASCIIString(value); if (ascii == NULL) return -1; - encoding = strdup(PyBytes_AS_STRING(ascii)); + encoding = _PyMem_Strdup(PyBytes_AS_STRING(ascii)); Py_DECREF(ascii); if (encoding == NULL) { PyErr_NoMemory(); return -1; } - free(self->encoding); + PyMem_Free(self->encoding); self->encoding = encoding; return 0; } diff -r 31a635303e55 -r 65f2c92ed079 Modules/_pickle.c --- a/Modules/_pickle.c Sun Jul 07 22:57:45 2013 +0200 +++ b/Modules/_pickle.c Sun Jul 07 23:30:24 2013 +0200 @@ -1213,8 +1213,8 @@ if (errors == NULL) errors = "strict"; - self->encoding = strdup(encoding); - self->errors = strdup(errors); + self->encoding = _PyMem_Strdup(encoding); + self->errors = _PyMem_Strdup(errors); if (self->encoding == NULL || self->errors == NULL) { PyErr_NoMemory(); return -1; @@ -5590,8 +5590,8 @@ _Unpickler_MemoCleanup(self); PyMem_Free(self->marks); PyMem_Free(self->input_line); - free(self->encoding); - free(self->errors); + PyMem_Free(self->encoding); + PyMem_Free(self->errors); Py_TYPE(self)->tp_free((PyObject *)self); } @@ -5627,9 +5627,9 @@ self->marks = NULL; PyMem_Free(self->input_line); self->input_line = NULL; - free(self->encoding); + PyMem_Free(self->encoding); self->encoding = NULL; - free(self->errors); + PyMem_Free(self->errors); self->errors = NULL; return 0; diff -r 31a635303e55 -r 65f2c92ed079 Modules/faulthandler.c --- a/Modules/faulthandler.c Sun Jul 07 22:57:45 2013 +0200 +++ b/Modules/faulthandler.c Sun Jul 07 23:30:24 2013 +0200 @@ -475,7 +475,7 @@ Py_CLEAR(thread.file); if (thread.header) { - free(thread.header); + PyMem_Free(thread.header); thread.header = NULL; } } @@ -504,7 +504,7 @@ "Timeout (%lu:%02lu:%02lu)!\n", hour, min, sec); - return strdup(buffer); + return _PyMem_Strdup(buffer); } static PyObject* @@ -570,7 +570,7 @@ if (PyThread_start_new_thread(faulthandler_thread, NULL) == -1) { PyThread_release_lock(thread.running); Py_CLEAR(thread.file); - free(header); + PyMem_Free(header); thread.header = NULL; PyErr_SetString(PyExc_RuntimeError, "unable to start watchdog thread"); @@ -729,9 +729,10 @@ return NULL; if (user_signals == NULL) { - user_signals = calloc(NSIG, sizeof(user_signal_t)); + user_signals = PyMem_Malloc(NSIG * sizeof(user_signal_t)); if (user_signals == NULL) return PyErr_NoMemory(); + memset(user_signals, 0, NSIG * sizeof(user_signal_t)); } user = &user_signals[signum]; @@ -1136,7 +1137,7 @@ if (user_signals != NULL) { for (signum=0; signum < NSIG; signum++) faulthandler_unregister(&user_signals[signum], signum); - free(user_signals); + PyMem_Free(user_signals); user_signals = NULL; } #endif diff -r 31a635303e55 -r 65f2c92ed079 Modules/main.c --- a/Modules/main.c Sun Jul 07 22:57:45 2013 +0200 +++ b/Modules/main.c Sun Jul 07 23:30:24 2013 +0200 @@ -544,7 +544,7 @@ Py_FatalError( "not enough memory to copy PYTHONWARNINGS"); strcpy(buf, p); - oldloc = strdup(setlocale(LC_ALL, NULL)); + oldloc = _PyMem_RawStrdup(setlocale(LC_ALL, NULL)); setlocale(LC_ALL, ""); for (p = strtok(buf, ","); p != NULL; p = strtok(NULL, ",")) { #ifdef __APPLE__ @@ -562,7 +562,7 @@ Py_DECREF(unicode); } setlocale(LC_ALL, oldloc); - free(oldloc); + PyMem_RawFree(oldloc); PyMem_RawFree(buf); } #endif diff -r 31a635303e55 -r 65f2c92ed079 Modules/python.c --- a/Modules/python.c Sun Jul 07 22:57:45 2013 +0200 +++ b/Modules/python.c Sun Jul 07 23:30:24 2013 +0200 @@ -43,12 +43,12 @@ fpsetmask(m & ~FP_X_OFL); #endif - oldloc = strdup(setlocale(LC_ALL, NULL)); + oldloc = _PyMem_RawStrdup(setlocale(LC_ALL, NULL)); setlocale(LC_ALL, ""); for (i = 0; i < argc; i++) { argv_copy[i] = _Py_char2wchar(argv[i], NULL); if (!argv_copy[i]) { - free(oldloc); + PyMem_RawFree(oldloc); fprintf(stderr, "Fatal Python error: " "unable to decode the command line argument #%i\n", i + 1); @@ -59,7 +59,7 @@ argv_copy2[argc] = argv_copy[argc] = NULL; setlocale(LC_ALL, oldloc); - free(oldloc); + PyMem_RawFree(oldloc); res = Py_Main(argc, argv_copy); for (i = 0; i < argc; i++) { PyMem_RawFree(argv_copy2[i]); diff -r 31a635303e55 -r 65f2c92ed079 Objects/obmalloc.c --- a/Objects/obmalloc.c Sun Jul 07 22:57:45 2013 +0200 +++ b/Objects/obmalloc.c Sun Jul 07 23:30:24 2013 +0200 @@ -294,6 +294,34 @@ _PyMem.free(_PyMem.ctx, ptr); } +char * +_PyMem_RawStrdup(const char *str) +{ + size_t size; + char *copy; + + size = strlen(str) + 1; + copy = PyMem_RawMalloc(size); + if (copy == NULL) + return NULL; + memcpy(copy, str, size); + return copy; +} + +char * +_PyMem_Strdup(const char *str) +{ + size_t size; + char *copy; + + size = strlen(str) + 1; + copy = PyMem_Malloc(size); + if (copy == NULL) + return NULL; + memcpy(copy, str, size); + return copy; +} + void * PyObject_Malloc(size_t size) { diff -r 31a635303e55 -r 65f2c92ed079 Python/pythonrun.c --- a/Python/pythonrun.c Sun Jul 07 22:57:45 2013 +0200 +++ b/Python/pythonrun.c Sun Jul 07 23:30:24 2013 +0200 @@ -174,7 +174,7 @@ name_utf8 = _PyUnicode_AsString(name); if (name_utf8 == NULL) goto error; - name_str = strdup(name_utf8); + name_str = _PyMem_RawStrdup(name_utf8); Py_DECREF(name); if (name_str == NULL) { PyErr_NoMemory(); @@ -626,7 +626,7 @@ /* reset file system default encoding */ if (!Py_HasFileSystemDefaultEncoding && Py_FileSystemDefaultEncoding) { - free((char*)Py_FileSystemDefaultEncoding); + PyMem_RawFree((char*)Py_FileSystemDefaultEncoding); Py_FileSystemDefaultEncoding = NULL; } @@ -1081,7 +1081,11 @@ encoding = Py_GETENV("PYTHONIOENCODING"); errors = NULL; if (encoding) { - encoding = strdup(encoding); + encoding = _PyMem_Strdup(encoding); + if (encoding == NULL) { + PyErr_NoMemory(); + goto error; + } errors = strchr(encoding, ':'); if (errors) { *errors = '\0'; @@ -1140,10 +1144,10 @@ when import.c tries to write to stderr in verbose mode. */ encoding_attr = PyObject_GetAttrString(std, "encoding"); if (encoding_attr != NULL) { - const char * encoding; - encoding = _PyUnicode_AsString(encoding_attr); - if (encoding != NULL) { - PyObject *codec_info = _PyCodec_Lookup(encoding); + const char * std_encoding; + std_encoding = _PyUnicode_AsString(encoding_attr); + if (std_encoding != NULL) { + PyObject *codec_info = _PyCodec_Lookup(std_encoding); Py_XDECREF(codec_info); } Py_DECREF(encoding_attr); @@ -1160,8 +1164,7 @@ status = -1; } - if (encoding) - free(encoding); + PyMem_Free(encoding); Py_XDECREF(bimod); Py_XDECREF(iomod); return status; /victor.stinner@gmail.com