FazBrowse GitHub Viewer | Trending |
URL:
| Home
Tools: [Download Repo ZIP]   [Original HTTPS Page]

gh-127604: Don't rely on `dprintf()` for faulthandler C stacks by ZeroIntensity · Pull Request #132800 · python/cpython · GitHub

/ cpython Public
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension .c  (2) .h  (1) All 2 file types selected
Viewed files
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Unified
Split
Hide whitespace
Diff view
Unified
Split
Hide whitespace
2 changes: 2 additions & 0 deletions Include/internal/pycore_fileutils.h
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode characters
Original file line number Diff line number Diff line change
Expand Up @@ -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,
Expand Down
26 changes: 26 additions & 0 deletions Python/fileutils.c
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode characters
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,8 @@
# include <windows.h>
# include <winioctl.h> // 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
Expand Down Expand Up @@ -2059,6 +2061,30 @@ _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, ...)
{
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);
if (res != 0) {
return -1;
}

return 0;
}

#ifdef HAVE_READLINK

/* Read value of symbolic link. Encode the path to the locale encoding, decode
Expand Down
16 changes: 8 additions & 8 deletions Python/traceback.c
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode characters
Original file line number Diff line number Diff line change
Expand Up @@ -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 '<unknown>' [%p]\n", array[i]);
_Py_fdprintf(fd, " Binary file '<unknown>' [%p]\n", array[i]);

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Choose a reason Spam Abuse Off Topic Outdated Duplicate Resolved Low Quality

It would be safer to not use printf family but use traceback.c functions to write directly into the fd.

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Choose a reason Spam Abuse Off Topic Outdated Duplicate Resolved Low Quality

Yeah, but then we have to deal with stack limits. I'll probably end up using those regardless, though.

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Choose a reason Spam Abuse Off Topic Outdated Duplicate Resolved Low Quality

I wrote #132854 to replace dprintf() with _Py_write_noraise().

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Choose a reason Spam Abuse Off Topic Outdated Duplicate Resolved Low Quality

Yeah, but then we have to deal with stack limits

Which stack limits? traceback.c code is designed to use little stack memory and be async-signal safe.

ZeroIntensity Apr 23, 2025
edited
Loading

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Choose a reason Spam Abuse Off Topic Outdated Duplicate Resolved Low Quality

I was thinking of a sprintf that would be incrementally printed. Your solution works a lot better.

continue;
}

Expand All @@ -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;
Expand All @@ -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]);
}
}
}
Expand Down

Back | FazBrowse Home | New Git URL