Skip to content
Closed
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Prev Previous commit
Next Next commit
Don't skip current tstate + update tests
  • Loading branch information
sergey-miryanov committed Nov 2, 2025
commit 4491118b1168772a4dddb0d0b60c6adb9c43b35a
6 changes: 1 addition & 5 deletions Include/internal/pycore_traceback.h
Original file line number Diff line number Diff line change
Expand Up @@ -56,16 +56,12 @@ extern void _Py_DumpTraceback(
It is better to pass NULL to interp and current_tstate, the function tries
different options to retrieve this information.

If skip_current_tstate is 1 then first tstate (current_tstate) will be skiped.
This flag used in faulthandler_thread to skip self.

This function is signal safe. */

extern const char* _Py_DumpTracebackThreads(
int fd,
PyInterpreterState *interp,
PyThreadState *current_tstate,
int skip_current_tstate);
PyThreadState *current_tstate);

/* Write a Unicode object into the file descriptor fd. Encode the string to
ASCII using the backslashreplace error handler.
Expand Down
3 changes: 3 additions & 0 deletions Lib/test/test_faulthandler.py
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@
THREAD_HEADER = fr'{THREAD_ID} \(most recent call first\):'
CURRENT_THREAD_ID = fr'Current thread 0x[0-9a-f]+{THREAD_NAME}'
CURRENT_THREAD_HEADER = fr'{CURRENT_THREAD_ID} \(most recent call first\):'
THREAD_NO_PYTHON_FRAME = ' <no Python frame>'


def expected_traceback(lineno1, lineno2, header, min_count=1):
Expand Down Expand Up @@ -676,6 +677,8 @@ def func(timeout, repeat, cancel, file, loops):
if repeat:
count *= 2
header = (fr'Timeout \({timeout_str}\)!\n'
fr'{CURRENT_THREAD_HEADER}\n'
fr'{THREAD_NO_PYTHON_FRAME}\n\n'
fr'{THREAD_HEADER}\n')
regex = expected_traceback(17, 26, header, min_count=count)
self.assertRegex(trace, regex)
Expand Down
4 changes: 2 additions & 2 deletions Modules/faulthandler.c
Original file line number Diff line number Diff line change
Expand Up @@ -205,7 +205,7 @@ faulthandler_dump_traceback(int fd, int all_threads,
PyThreadState *tstate = PyGILState_GetThisThreadState();

if (all_threads == 1) {
(void)_Py_DumpTracebackThreads(fd, NULL, tstate, 0);
(void)_Py_DumpTracebackThreads(fd, NULL, tstate);
}
else {
if (all_threads == FT_IGNORE_ALL_THREADS) {
Expand Down Expand Up @@ -273,7 +273,7 @@ faulthandler_dump_traceback_py_impl(PyObject *module, PyObject *file,
/* gh-128400: Accessing other thread states while they're running
* isn't safe if those threads are running. */
_PyEval_StopTheWorld(interp);
errmsg = _Py_DumpTracebackThreads(fd, NULL, tstate, 0);
errmsg = _Py_DumpTracebackThreads(fd, NULL, tstate);
_PyEval_StartTheWorld(interp);
if (errmsg != NULL) {
PyErr_SetString(PyExc_RuntimeError, errmsg);
Expand Down
2 changes: 1 addition & 1 deletion Python/pylifecycle.c
Original file line number Diff line number Diff line change
Expand Up @@ -3139,7 +3139,7 @@ _Py_FatalError_DumpTracebacks(int fd, PyInterpreterState *interp,

/* display the current Python stack */
#ifndef Py_GIL_DISABLED
_Py_DumpTracebackThreads(fd, interp, tstate, 0);
_Py_DumpTracebackThreads(fd, interp, tstate);
#else
_Py_DumpTraceback(fd, tstate);
#endif
Expand Down
9 changes: 1 addition & 8 deletions Python/traceback.c
Original file line number Diff line number Diff line change
Expand Up @@ -1239,8 +1239,7 @@ write_thread_id(int fd, PyThreadState *tstate, int is_current)
handlers if signals were received. */
const char*
_Py_DumpTracebackThreads(int fd, PyInterpreterState *interp,
PyThreadState *current_tstate,
int skip_current_tstate)
PyThreadState *current_tstate)
{
if (current_tstate == NULL) {
/* _Py_DumpTracebackThreads() is called from signal handlers by
Expand Down Expand Up @@ -1290,12 +1289,6 @@ _Py_DumpTracebackThreads(int fd, PyInterpreterState *interp,
_Py_BEGIN_SUPPRESS_IPH
do
{
if (skip_current_tstate && current_tstate == tstate) {
tstate = PyThreadState_Next(tstate);
skip_current_tstate = 0;
continue;
}

if (nthreads != 0)
PUTS(fd, "\n");
if (nthreads >= MAX_NTHREADS) {
Expand Down