From dc39d9a470e01c75a14d24bde8456f5790f50b4c Mon Sep 17 00:00:00 2001 From: Peter Bierma Date: Tue, 22 Apr 2025 14:16:21 +0000 Subject: [PATCH 1/5] Don't rely on dprintf() for faulthandler C stacks --- Include/internal/pycore_fileutils.h | 2 ++ Python/fileutils.c | 16 ++++++++++++++++ Python/traceback.c | 16 ++++++++-------- 3 files changed, 26 insertions(+), 8 deletions(-) diff --git a/Include/internal/pycore_fileutils.h b/Include/internal/pycore_fileutils.h index 2c6d6daa01994e..2cf8860db591a9 100644 --- a/Include/internal/pycore_fileutils.h +++ b/Include/internal/pycore_fileutils.h @@ -132,6 +132,8 @@ PyAPI_FUNC(Py_ssize_t) _Py_write_noraise( const void *buf, size_t count); +extern int _Py_fdprintf(int fd, const char *fmt, ...); + #ifdef HAVE_READLINK extern int _Py_wreadlink( const wchar_t *path, diff --git a/Python/fileutils.c b/Python/fileutils.c index 78603d40704f14..7ac15791f1859a 100644 --- a/Python/fileutils.c +++ b/Python/fileutils.c @@ -14,6 +14,7 @@ # include # include // FILE_DEVICE_* constants # include "pycore_fileutils_windows.h" // FILE_STAT_BASIC_INFORMATION +# define fdopen _fdopen # if defined(MS_WINDOWS_GAMES) && !defined(MS_WINDOWS_DESKTOP) # define PATHCCH_ALLOW_LONG_PATHS 0x01 # else @@ -2059,6 +2060,21 @@ _Py_write_noraise(int fd, const void *buf, size_t count) return _Py_write_impl(fd, buf, count, 0); } +int +_Py_fdprintf(int fd, const char *fmt, ...) +{ + FILE *handle = fdopen(fd, "a"); + va_list vargs; + va_start(vargs, fmt); + int res = vfprintf(handle, fmt, vargs); + va_end(vargs); + if (res != 0) { + return -1; + } + + return 0; +} + #ifdef HAVE_READLINK /* Read value of symbolic link. Encode the path to the locale encoding, decode diff --git a/Python/traceback.c b/Python/traceback.c index 7319382f053eae..5d053283ff51eb 100644 --- a/Python/traceback.c +++ b/Python/traceback.c @@ -1210,7 +1210,7 @@ _Py_backtrace_symbols_fd(int fd, void *const *array, Py_ssize_t size) || info[i].dli_fname == NULL || info[i].dli_fname[0] == '\0' ) { - dprintf(fd, " Binary file '' [%p]\n", array[i]); + _Py_fdprintf(fd, " Binary file '' [%p]\n", array[i]); continue; } @@ -1222,9 +1222,9 @@ _Py_backtrace_symbols_fd(int fd, void *const *array, Py_ssize_t size) if (info[i].dli_sname == NULL && info[i].dli_saddr == 0) { - dprintf(fd, " Binary file \"%s\" [%p]\n", - info[i].dli_fname, - array[i]); + _Py_fdprintf(fd, " Binary file \"%s\" [%p]\n", + info[i].dli_fname, + array[i]); } else { char sign; @@ -1238,10 +1238,10 @@ _Py_backtrace_symbols_fd(int fd, void *const *array, Py_ssize_t size) offset = info[i].dli_saddr - array[i]; } const char *symbol_name = info[i].dli_sname != NULL ? info[i].dli_sname : ""; - dprintf(fd, " Binary file \"%s\", at %s%c%#tx [%p]\n", - info[i].dli_fname, - symbol_name, - sign, offset, array[i]); + _Py_fdprintf(fd, " Binary file \"%s\", at %s%c%#tx [%p]\n", + info[i].dli_fname, + symbol_name, + sign, offset, array[i]); } } } From b9520d5ef71bafbb1125e6931805feab9af86c36 Mon Sep 17 00:00:00 2001 From: Peter Bierma Date: Wed, 23 Apr 2025 07:27:18 -0400 Subject: [PATCH 2/5] Add fclose() --- Python/fileutils.c | 1 + 1 file changed, 1 insertion(+) diff --git a/Python/fileutils.c b/Python/fileutils.c index 7ac15791f1859a..fddacf014e2ffd 100644 --- a/Python/fileutils.c +++ b/Python/fileutils.c @@ -2068,6 +2068,7 @@ _Py_fdprintf(int fd, const char *fmt, ...) va_start(vargs, fmt); int res = vfprintf(handle, fmt, vargs); va_end(vargs); + fclose(handle); if (res != 0) { return -1; } From a3ded446acd0fa649d26cf72db70556a1a1eefba Mon Sep 17 00:00:00 2001 From: Peter Bierma Date: Wed, 23 Apr 2025 07:29:19 -0400 Subject: [PATCH 3/5] Add dup() --- Python/fileutils.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/Python/fileutils.c b/Python/fileutils.c index fddacf014e2ffd..5cdd575bf01b94 100644 --- a/Python/fileutils.c +++ b/Python/fileutils.c @@ -15,6 +15,7 @@ # include // FILE_DEVICE_* constants # include "pycore_fileutils_windows.h" // FILE_STAT_BASIC_INFORMATION # define fdopen _fdopen +# define dup _dup # if defined(MS_WINDOWS_GAMES) && !defined(MS_WINDOWS_DESKTOP) # define PATHCCH_ALLOW_LONG_PATHS 0x01 # else @@ -2063,7 +2064,8 @@ _Py_write_noraise(int fd, const void *buf, size_t count) int _Py_fdprintf(int fd, const char *fmt, ...) { - FILE *handle = fdopen(fd, "a"); + int newfd = dup(fd); + FILE *handle = fdopen(newfd, "a"); va_list vargs; va_start(vargs, fmt); int res = vfprintf(handle, fmt, vargs); From d8e1279d359635feac3ea0edd6cdeaa1e3872684 Mon Sep 17 00:00:00 2001 From: Peter Bierma Date: Wed, 23 Apr 2025 07:31:57 -0400 Subject: [PATCH 4/5] Add close() --- Python/fileutils.c | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/Python/fileutils.c b/Python/fileutils.c index 5cdd575bf01b94..041d6498accc42 100644 --- a/Python/fileutils.c +++ b/Python/fileutils.c @@ -16,6 +16,7 @@ # include "pycore_fileutils_windows.h" // FILE_STAT_BASIC_INFORMATION # define fdopen _fdopen # define dup _dup +# define close _close # if defined(MS_WINDOWS_GAMES) && !defined(MS_WINDOWS_DESKTOP) # define PATHCCH_ALLOW_LONG_PATHS 0x01 # else @@ -2065,12 +2066,20 @@ int _Py_fdprintf(int fd, const char *fmt, ...) { int newfd = dup(fd); + if (newfd < 0) { + return -1; + } FILE *handle = fdopen(newfd, "a"); + if (handle == NULL) { + close(newfd); + return -1; + } va_list vargs; va_start(vargs, fmt); int res = vfprintf(handle, fmt, vargs); va_end(vargs); fclose(handle); + close(newfd); if (res != 0) { return -1; } From 6f6444dfdb70fad0ef38f701e617d86c042cc628 Mon Sep 17 00:00:00 2001 From: Peter Bierma Date: Wed, 23 Apr 2025 07:42:53 -0400 Subject: [PATCH 5/5] Remove needless close() --- Python/fileutils.c | 2 -- 1 file changed, 2 deletions(-) diff --git a/Python/fileutils.c b/Python/fileutils.c index 041d6498accc42..b6ffbb313e6fef 100644 --- a/Python/fileutils.c +++ b/Python/fileutils.c @@ -16,7 +16,6 @@ # include "pycore_fileutils_windows.h" // FILE_STAT_BASIC_INFORMATION # define fdopen _fdopen # define dup _dup -# define close _close # if defined(MS_WINDOWS_GAMES) && !defined(MS_WINDOWS_DESKTOP) # define PATHCCH_ALLOW_LONG_PATHS 0x01 # else @@ -2079,7 +2078,6 @@ _Py_fdprintf(int fd, const char *fmt, ...) int res = vfprintf(handle, fmt, vargs); va_end(vargs); fclose(handle); - close(newfd); if (res != 0) { return -1; }