Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Commit 1a7425f

Browse files
committed
Issue #18203: Replace malloc() with PyMem_RawMalloc() at Python initialization
* Replace malloc() with PyMem_RawMalloc() * Replace PyMem_Malloc() with PyMem_RawMalloc() where the GIL is not held. * _Py_char2wchar() now returns a buffer allocated by PyMem_RawMalloc(), instead of PyMem_Malloc()
1 parent 51fa458 commit 1a7425f

8 files changed

Lines changed: 76 additions & 76 deletions

File tree

Modules/getpath.c

Lines changed: 9 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -343,7 +343,7 @@ search_for_prefix(wchar_t *argv0_path, wchar_t *home, wchar_t *_prefix)
343343
if (vpath != NULL) {
344344
wcscpy(prefix, argv0_path);
345345
joinpath(prefix, vpath);
346-
PyMem_Free(vpath);
346+
PyMem_RawFree(vpath);
347347
joinpath(prefix, L"Lib");
348348
joinpath(prefix, LANDMARK);
349349
if (ismodule(prefix))
@@ -554,8 +554,7 @@ calculate_path(void)
554554
}
555555
else
556556
progpath[0] = '\0';
557-
if (path_buffer != NULL)
558-
PyMem_Free(path_buffer);
557+
PyMem_RawFree(path_buffer);
559558
if (progpath[0] != SEP && progpath[0] != '\0')
560559
absolutize(progpath);
561560
wcsncpy(argv0_path, progpath, MAXPATHLEN);
@@ -597,7 +596,7 @@ calculate_path(void)
597596
/* Use the location of the library as the progpath */
598597
wcsncpy(argv0_path, wbuf, MAXPATHLEN);
599598
}
600-
PyMem_Free(wbuf);
599+
PyMem_RawFree(wbuf);
601600
}
602601
#endif
603602

@@ -808,11 +807,10 @@ calculate_path(void)
808807
else
809808
wcsncpy(exec_prefix, _exec_prefix, MAXPATHLEN);
810809

811-
PyMem_Free(_pythonpath);
812-
PyMem_Free(_prefix);
813-
PyMem_Free(_exec_prefix);
814-
if (rtpypath != NULL)
815-
PyMem_Free(rtpypath);
810+
PyMem_RawFree(_pythonpath);
811+
PyMem_RawFree(_prefix);
812+
PyMem_RawFree(_exec_prefix);
813+
PyMem_RawFree(rtpypath);
816814
}
817815

818816

@@ -822,7 +820,7 @@ Py_SetPath(const wchar_t *path)
822820
{
823821
if (module_search_path != NULL) {
824822
if (module_search_path_malloced)
825-
PyMem_Free(module_search_path);
823+
PyMem_RawFree(module_search_path);
826824
module_search_path = NULL;
827825
module_search_path_malloced = 0;
828826
}
@@ -831,7 +829,7 @@ Py_SetPath(const wchar_t *path)
831829
wchar_t *prog = Py_GetProgramName();
832830
wcsncpy(progpath, prog, MAXPATHLEN);
833831
exec_prefix[0] = prefix[0] = L'\0';
834-
module_search_path = PyMem_Malloc((wcslen(path) + 1) * sizeof(wchar_t));
832+
module_search_path = PyMem_RawMalloc((wcslen(path) + 1) * sizeof(wchar_t));
835833
module_search_path_malloced = 1;
836834
if (module_search_path != NULL)
837835
wcscpy(module_search_path, path);

Modules/main.c

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -391,7 +391,7 @@ Py_Main(int argc, wchar_t **argv)
391391
command to interpret. */
392392

393393
len = wcslen(_PyOS_optarg) + 1 + 1;
394-
command = (wchar_t *)malloc(sizeof(wchar_t) * len);
394+
command = (wchar_t *)PyMem_RawMalloc(sizeof(wchar_t) * len);
395395
if (command == NULL)
396396
Py_FatalError(
397397
"not enough memory to copy -c argument");
@@ -520,7 +520,7 @@ Py_Main(int argc, wchar_t **argv)
520520
*wp != L'\0') {
521521
wchar_t *buf, *warning;
522522

523-
buf = (wchar_t *)malloc((wcslen(wp) + 1) * sizeof(wchar_t));
523+
buf = (wchar_t *)PyMem_RawMalloc((wcslen(wp) + 1) * sizeof(wchar_t));
524524
if (buf == NULL)
525525
Py_FatalError(
526526
"not enough memory to copy PYTHONWARNINGS");
@@ -530,7 +530,7 @@ Py_Main(int argc, wchar_t **argv)
530530
warning = wcstok(NULL, L",")) {
531531
PySys_AddWarnOption(warning);
532532
}
533-
free(buf);
533+
PyMem_RawFree(buf);
534534
}
535535
#else
536536
if ((p = Py_GETENV("PYTHONWARNINGS")) && *p != '\0') {
@@ -539,7 +539,7 @@ Py_Main(int argc, wchar_t **argv)
539539

540540
/* settle for strtok here as there's no one standard
541541
C89 wcstok */
542-
buf = (char *)malloc(strlen(p) + 1);
542+
buf = (char *)PyMem_RawMalloc(strlen(p) + 1);
543543
if (buf == NULL)
544544
Py_FatalError(
545545
"not enough memory to copy PYTHONWARNINGS");
@@ -563,7 +563,7 @@ Py_Main(int argc, wchar_t **argv)
563563
}
564564
setlocale(LC_ALL, oldloc);
565565
free(oldloc);
566-
free(buf);
566+
PyMem_RawFree(buf);
567567
}
568568
#endif
569569

@@ -633,7 +633,7 @@ Py_Main(int argc, wchar_t **argv)
633633
wchar_t* buffer;
634634
size_t len = strlen(p) + 1;
635635

636-
buffer = malloc(len * sizeof(wchar_t));
636+
buffer = PyMem_RawMalloc(len * sizeof(wchar_t));
637637
if (buffer == NULL) {
638638
Py_FatalError(
639639
"not enough memory to copy PYTHONEXECUTABLE");
@@ -707,7 +707,7 @@ Py_Main(int argc, wchar_t **argv)
707707

708708
if (command) {
709709
sts = run_command(command, &cf);
710-
free(command);
710+
PyMem_RawFree(command);
711711
} else if (module) {
712712
sts = (RunModule(module, 1) != 0);
713713
}

Modules/python.c

Lines changed: 14 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -18,11 +18,19 @@ wmain(int argc, wchar_t **argv)
1818
int
1919
main(int argc, char **argv)
2020
{
21-
wchar_t **argv_copy = (wchar_t **)PyMem_Malloc(sizeof(wchar_t*)*(argc+1));
21+
wchar_t **argv_copy;
2222
/* We need a second copies, as Python might modify the first one. */
23-
wchar_t **argv_copy2 = (wchar_t **)PyMem_Malloc(sizeof(wchar_t*)*(argc+1));
23+
wchar_t **argv_copy2;
2424
int i, res;
2525
char *oldloc;
26+
27+
argv_copy = (wchar_t **)PyMem_RawMalloc(sizeof(wchar_t*) * (argc+1));
28+
argv_copy2 = (wchar_t **)PyMem_RawMalloc(sizeof(wchar_t*) * (argc+1));
29+
if (!argv_copy || !argv_copy2) {
30+
fprintf(stderr, "out of memory\n");
31+
return 1;
32+
}
33+
2634
/* 754 requires that FP exceptions run in "no stop" mode by default,
2735
* and until C vendors implement C99's ways to control FP exceptions,
2836
* Python requires non-stop mode. Alas, some platforms enable FP
@@ -34,10 +42,7 @@ main(int argc, char **argv)
3442
m = fpgetmask();
3543
fpsetmask(m & ~FP_X_OFL);
3644
#endif
37-
if (!argv_copy || !argv_copy2) {
38-
fprintf(stderr, "out of memory\n");
39-
return 1;
40-
}
45+
4146
oldloc = strdup(setlocale(LC_ALL, NULL));
4247
setlocale(LC_ALL, "");
4348
for (i = 0; i < argc; i++) {
@@ -57,10 +62,10 @@ main(int argc, char **argv)
5762
free(oldloc);
5863
res = Py_Main(argc, argv_copy);
5964
for (i = 0; i < argc; i++) {
60-
PyMem_Free(argv_copy2[i]);
65+
PyMem_RawFree(argv_copy2[i]);
6166
}
62-
PyMem_Free(argv_copy);
63-
PyMem_Free(argv_copy2);
67+
PyMem_RawFree(argv_copy);
68+
PyMem_RawFree(argv_copy2);
6469
return res;
6570
}
6671
#endif

Objects/unicodeobject.c

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -3316,7 +3316,7 @@ PyUnicode_EncodeLocale(PyObject *unicode, const char *errors)
33163316
wstr = _Py_char2wchar(errmsg, &errlen);
33173317
if (wstr != NULL) {
33183318
reason = PyUnicode_FromWideChar(wstr, errlen);
3319-
PyMem_Free(wstr);
3319+
PyMem_RawFree(wstr);
33203320
} else
33213321
errmsg = NULL;
33223322
}
@@ -3535,7 +3535,7 @@ PyUnicode_DecodeLocaleAndSize(const char *str, Py_ssize_t len,
35353535
}
35363536

35373537
unicode = PyUnicode_FromWideChar(wstr, wlen);
3538-
PyMem_Free(wstr);
3538+
PyMem_RawFree(wstr);
35393539
}
35403540
else {
35413541
/* strict mode */
@@ -3583,7 +3583,7 @@ PyUnicode_DecodeLocaleAndSize(const char *str, Py_ssize_t len,
35833583
wstr = _Py_char2wchar(errmsg, &errlen);
35843584
if (wstr != NULL) {
35853585
reason = PyUnicode_FromWideChar(wstr, errlen);
3586-
PyMem_Free(wstr);
3586+
PyMem_RawFree(wstr);
35873587
} else
35883588
errmsg = NULL;
35893589
}

PC/getpathp.c

Lines changed: 18 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -245,9 +245,9 @@ getpythonregpath(HKEY keyBase, int skipcore)
245245
/* Tried to use sysget("winver") but here is too early :-( */
246246
versionLen = strlen(PyWin_DLLVersionString);
247247
/* Space for all the chars, plus one \0 */
248-
keyBuf = keyBufPtr = malloc(sizeof(keyPrefix) +
249-
sizeof(WCHAR)*(versionLen-1) +
250-
sizeof(keySuffix));
248+
keyBuf = keyBufPtr = PyMem_RawMalloc(sizeof(keyPrefix) +
249+
sizeof(WCHAR)*(versionLen-1) +
250+
sizeof(keySuffix));
251251
if (keyBuf==NULL) goto done;
252252

253253
memcpy(keyBufPtr, keyPrefix, sizeof(keyPrefix)-sizeof(WCHAR));
@@ -271,7 +271,7 @@ getpythonregpath(HKEY keyBase, int skipcore)
271271
/* Allocate a temp array of char buffers, so we only need to loop
272272
reading the registry once
273273
*/
274-
ppPaths = malloc( sizeof(WCHAR *) * numKeys );
274+
ppPaths = PyMem_RawMalloc( sizeof(WCHAR *) * numKeys );
275275
if (ppPaths==NULL) goto done;
276276
memset(ppPaths, 0, sizeof(WCHAR *) * numKeys);
277277
/* Loop over all subkeys, allocating a temp sub-buffer. */
@@ -293,7 +293,7 @@ getpythonregpath(HKEY keyBase, int skipcore)
293293
/* Find the value of the buffer size, malloc, then read it */
294294
RegQueryValueExW(subKey, NULL, 0, NULL, NULL, &reqdSize);
295295
if (reqdSize) {
296-
ppPaths[index] = malloc(reqdSize);
296+
ppPaths[index] = PyMem_RawMalloc(reqdSize);
297297
if (ppPaths[index]) {
298298
RegQueryValueExW(subKey, NULL, 0, NULL,
299299
(LPBYTE)ppPaths[index],
@@ -308,7 +308,7 @@ getpythonregpath(HKEY keyBase, int skipcore)
308308
if (dataSize == 0) goto done;
309309

310310
/* original datasize from RegQueryInfo doesn't include the \0 */
311-
dataBuf = malloc((dataSize+1) * sizeof(WCHAR));
311+
dataBuf = PyMem_RawMalloc((dataSize+1) * sizeof(WCHAR));
312312
if (dataBuf) {
313313
WCHAR *szCur = dataBuf;
314314
DWORD reqdSize = dataSize;
@@ -346,14 +346,13 @@ getpythonregpath(HKEY keyBase, int skipcore)
346346
done:
347347
/* Loop freeing my temp buffers */
348348
if (ppPaths) {
349-
for(index=0;index<numKeys;index++)
350-
if (ppPaths[index]) free(ppPaths[index]);
351-
free(ppPaths);
349+
for(index=0; index<numKeys; index++)
350+
PyMem_RawFree(ppPaths[index]);
351+
PyMem_RawFree(ppPaths);
352352
}
353353
if (newKey)
354354
RegCloseKey(newKey);
355-
if (keyBuf)
356-
free(keyBuf);
355+
PyMem_RawFree(keyBuf);
357356
return retval;
358357
}
359358
#endif /* Py_ENABLE_SHARED */
@@ -616,7 +615,7 @@ calculate_path(void)
616615
if (envpath != NULL)
617616
bufsz += wcslen(envpath) + 1;
618617

619-
module_search_path = buf = malloc(bufsz*sizeof(wchar_t));
618+
module_search_path = buf = PyMem_RawMalloc(bufsz*sizeof(wchar_t));
620619
if (buf == NULL) {
621620
/* We can't exit, so print a warning and limp along */
622621
fprintf(stderr, "Can't malloc dynamic PYTHONPATH.\n");
@@ -629,10 +628,8 @@ calculate_path(void)
629628
module_search_path = PYTHONPATH;
630629
}
631630
#ifdef MS_WINDOWS
632-
if (machinepath)
633-
free(machinepath);
634-
if (userpath)
635-
free(userpath);
631+
PyMem_RawFree(machinepath);
632+
PyMem_RawFree(userpath);
636633
#endif /* MS_WINDOWS */
637634
return;
638635
}
@@ -652,13 +649,13 @@ calculate_path(void)
652649
wcscpy(buf, userpath);
653650
buf = wcschr(buf, L'\0');
654651
*buf++ = DELIM;
655-
free(userpath);
652+
PyMem_RawFree(userpath);
656653
}
657654
if (machinepath) {
658655
wcscpy(buf, machinepath);
659656
buf = wcschr(buf, L'\0');
660657
*buf++ = DELIM;
661-
free(machinepath);
658+
PyMem_RawFree(machinepath);
662659
}
663660
if (pythonhome == NULL) {
664661
if (!skipdefault) {
@@ -745,18 +742,18 @@ void
745742
Py_SetPath(const wchar_t *path)
746743
{
747744
if (module_search_path != NULL) {
748-
free(module_search_path);
745+
PyMem_RawFree(module_search_path);
749746
module_search_path = NULL;
750747
}
751748
if (path != NULL) {
752749
extern wchar_t *Py_GetProgramName(void);
753750
wchar_t *prog = Py_GetProgramName();
754751
wcsncpy(progpath, prog, MAXPATHLEN);
755752
prefix[0] = L'\0';
756-
module_search_path = malloc((wcslen(path) + 1) * sizeof(wchar_t));
753+
module_search_path = PyMem_RawMalloc((wcslen(path) + 1) * sizeof(wchar_t));
757754
if (module_search_path != NULL)
758755
wcscpy(module_search_path, path);
759-
}
756+
}
760757
}
761758

762759
wchar_t *

0 commit comments

Comments
 (0)