[issue38733] PyErr_Occurred(): tstate must be non-NULL

2019-11-07 Thread STINNER Victor


STINNER Victor  added the comment:

I merged my change, I close the issue.

The change is a little bit backward incompatible, so I prefer to not backport 
it. PyErr_Occurred() checks tstate==NULL for 9 years, there is no urgency to 
change it :-) It can wait for Python 3.9.

--
resolution:  -> fixed
stage: patch review -> resolved
status: open -> closed

___
Python tracker 

___
___
Python-bugs-list mailing list
Unsubscribe: 
https://mail.python.org/mailman/options/python-bugs-list/archive%40mail-archive.com



[issue38733] PyErr_Occurred(): tstate must be non-NULL

2019-11-07 Thread STINNER Victor


STINNER Victor  added the comment:

In 2018 with bpo-26558, I fixed Py_FatalError() to no longer access the current 
exception of the current Python thread state, if the current thread doesn't not 
hold the GIL:

commit 3a228ab17c2a9cffd1a2f15f30d6209768de20a6
Author: Victor Stinner 
Date:   Thu Nov 1 00:26:41 2018 +0100

bpo-26558: Fix Py_FatalError() with GIL released (GH-10267)

Don't call _Py_FatalError_PrintExc() nor flush_std_files() if the
current thread doesn't hold the GIL, or if the current thread
has no Python state thread.


Extract of Py_FatalError() code:

/* Check if the current thread has a Python thread state
   and holds the GIL.

   tss_tstate is NULL if Py_FatalError() is called from a C thread which
   has no Python thread state.

   tss_tstate != tstate if the current Python thread does not hold the GIL.
   */
PyThreadState *tss_tstate = PyGILState_GetThisThreadState();
int has_tstate_and_gil = (tss_tstate != NULL && tss_tstate == tstate);
if (has_tstate_and_gil) {
/* If an exception is set, print the exception with its traceback */
if (!_Py_FatalError_PrintExc(fd)) {
/* No exception is set, or an exception is set without traceback */
_Py_FatalError_DumpTracebacks(fd, interp, tss_tstate);
}
}
else {
_Py_FatalError_DumpTracebacks(fd, interp, tss_tstate);
}

--

___
Python tracker 

___
___
Python-bugs-list mailing list
Unsubscribe: 
https://mail.python.org/mailman/options/python-bugs-list/archive%40mail-archive.com



[issue38733] PyErr_Occurred(): tstate must be non-NULL

2019-11-07 Thread STINNER Victor


STINNER Victor  added the comment:


New changeset d12d0e7c0fe2b49c40ac4d66365147c619d6c475 by Victor Stinner in 
branch 'master':
bpo-38733: PyErr_Occurred() caller must hold the GIL (GH-17080)
https://github.com/python/cpython/commit/d12d0e7c0fe2b49c40ac4d66365147c619d6c475


--

___
Python tracker 

___
___
Python-bugs-list mailing list
Unsubscribe: 
https://mail.python.org/mailman/options/python-bugs-list/archive%40mail-archive.com



[issue38733] PyErr_Occurred(): tstate must be non-NULL

2019-11-07 Thread STINNER Victor


Change by STINNER Victor :


--
keywords: +patch
pull_requests: +16589
stage:  -> patch review
pull_request: https://github.com/python/cpython/pull/17080

___
Python tracker 

___
___
Python-bugs-list mailing list
Unsubscribe: 
https://mail.python.org/mailman/options/python-bugs-list/archive%40mail-archive.com



[issue38733] PyErr_Occurred(): tstate must be non-NULL

2019-11-07 Thread STINNER Victor


New submission from STINNER Victor :

bpo-3605 modified PyErr_Occurred() to return NULL if the current Python thread 
state ("tstate") is NULL:

commit 8e0bdfd1d473ddffaf3501768678f8a970019da8
Author: Jeffrey Yasskin 
Date:   Thu May 13 18:31:05 2010 +

Make PyErr_Occurred return NULL if there is no current thread.  Previously 
it
would Py_FatalError, which called PyErr_Occurred, resulting in a 
semi-infinite
recursion.

Fixes issue 3605.

This change made PyErr_Occurred() inefficient: PyErr_Occurred() was a simple 
attribute read (tstate->curexc_type), and now there is an additional if per 
call.

I recently added _PyErr_Occurred(tstate) which is similar to PyErr_Occurred() 
but requires to pass tstate explicitly. I expected this function to be as 
simple as:

static inline PyObject* _PyErr_Occurred(PyThreadState *tstate)
{
return tstate->curexc_type;
}

but the current implementation is:

static inline PyObject* _PyErr_Occurred(PyThreadState *tstate)
{
return tstate == NULL ? NULL : tstate->curexc_type;
}


--

PyErr_Occurred() is currently implemented as:

PyObject* _Py_HOT_FUNCTION
PyErr_Occurred(void)
{
PyThreadState *tstate = _PyThreadState_GET();
return _PyErr_Occurred(tstate);
}

_PyThreadState_GET() must only be called with the GIL hold. This macro is 
designed to be efficient: it doesn't check if tstate is NULL.

_PyThreadState_GET() is only NULL if the thread has no Python thread state yet, 
or if the GIL is released.

IMHO PyErr_Occurred() must not be called if the GIL is released.

--
components: Interpreter Core
messages: 356180
nosy: vstinner
priority: normal
severity: normal
status: open
title: PyErr_Occurred(): tstate must be non-NULL
versions: Python 3.9

___
Python tracker 

___
___
Python-bugs-list mailing list
Unsubscribe: 
https://mail.python.org/mailman/options/python-bugs-list/archive%40mail-archive.com