summaryrefslogtreecommitdiffstats
path: root/Modules
diff options
context:
space:
mode:
authorMiss Islington (bot) <31488909+miss-islington@users.noreply.github.com>2020-05-27 23:00:01 (GMT)
committerGitHub <noreply@github.com>2020-05-27 23:00:01 (GMT)
commit9e3c583954f75a6396d1935e000df85d89b78a3d (patch)
tree56c191b0ca8de9ab8a55ff5720c6a047f0b0b4e1 /Modules
parentbe240b857154078617cdd68fc63d1e48549e7a0b (diff)
downloadcpython-9e3c583954f75a6396d1935e000df85d89b78a3d.zip
cpython-9e3c583954f75a6396d1935e000df85d89b78a3d.tar.gz
cpython-9e3c583954f75a6396d1935e000df85d89b78a3d.tar.bz2
bpo-40795: ctypes calls unraisablehook with an exception (GH-20452)
If ctypes fails to convert the result of a callback or if a ctypes callback function raises an exception, sys.unraisablehook is now called with an exception set. Previously, the error was logged into stderr by PyErr_Print(). (cherry picked from commit 10228bad0452d94e66c964b625a0b61befa08e59) Co-authored-by: Victor Stinner <vstinner@python.org>
Diffstat (limited to 'Modules')
-rw-r--r--Modules/_ctypes/callbacks.c43
-rw-r--r--Modules/_ctypes/callproc.c2
2 files changed, 31 insertions, 14 deletions
diff --git a/Modules/_ctypes/callbacks.c b/Modules/_ctypes/callbacks.c
index 2b903c9..29e8fac 100644
--- a/Modules/_ctypes/callbacks.c
+++ b/Modules/_ctypes/callbacks.c
@@ -213,9 +213,6 @@ static void _CallPythonObject(void *mem,
pArgs++;
}
-#define CHECK(what, x) \
-if (x == NULL) _PyTraceback_Add(what, "_ctypes/callbacks.c", __LINE__ - 1), PyErr_Print()
-
if (flags & (FUNCFLAG_USE_ERRNO | FUNCFLAG_USE_LASTERROR)) {
error_object = _ctypes_get_errobj(&space);
if (error_object == NULL)
@@ -235,7 +232,10 @@ if (x == NULL) _PyTraceback_Add(what, "_ctypes/callbacks.c", __LINE__ - 1), PyEr
}
result = PyObject_CallObject(callable, arglist);
- CHECK("'calling callback function'", result);
+ if (result == NULL) {
+ _PyErr_WriteUnraisableMsg("on calling ctypes callback function",
+ callable);
+ }
#ifdef MS_WIN32
if (flags & FUNCFLAG_USE_LASTERROR) {
@@ -251,16 +251,17 @@ if (x == NULL) _PyTraceback_Add(what, "_ctypes/callbacks.c", __LINE__ - 1), PyEr
}
Py_XDECREF(error_object);
- if ((restype != &ffi_type_void) && result) {
- PyObject *keep;
+ if (restype != &ffi_type_void && result) {
assert(setfunc);
+
#ifdef WORDS_BIGENDIAN
- /* See the corresponding code in callproc.c, around line 961 */
- if (restype->type != FFI_TYPE_FLOAT && restype->size < sizeof(ffi_arg))
+ /* See the corresponding code in _ctypes_callproc():
+ in callproc.c, around line 1219. */
+ if (restype->type != FFI_TYPE_FLOAT && restype->size < sizeof(ffi_arg)) {
mem = (char *)mem + sizeof(ffi_arg) - restype->size;
+ }
#endif
- keep = setfunc(mem, result, 0);
- CHECK("'converting callback result'", keep);
+
/* keep is an object we have to keep alive so that the result
stays valid. If there is no such object, the setfunc will
have returned Py_None.
@@ -270,18 +271,32 @@ if (x == NULL) _PyTraceback_Add(what, "_ctypes/callbacks.c", __LINE__ - 1), PyEr
be the result. EXCEPT when restype is py_object - Python
itself knows how to manage the refcount of these objects.
*/
- if (keep == NULL) /* Could not convert callback result. */
- PyErr_WriteUnraisable(callable);
- else if (keep == Py_None) /* Nothing to keep */
+ PyObject *keep = setfunc(mem, result, 0);
+
+ if (keep == NULL) {
+ /* Could not convert callback result. */
+ _PyErr_WriteUnraisableMsg("on converting result "
+ "of ctypes callback function",
+ callable);
+ }
+ else if (keep == Py_None) {
+ /* Nothing to keep */
Py_DECREF(keep);
+ }
else if (setfunc != _ctypes_get_fielddesc("O")->setfunc) {
if (-1 == PyErr_WarnEx(PyExc_RuntimeWarning,
"memory leak in callback function.",
1))
- PyErr_WriteUnraisable(callable);
+ {
+ _PyErr_WriteUnraisableMsg("on converting result "
+ "of ctypes callback function",
+ callable);
+ }
}
}
+
Py_XDECREF(result);
+
Done:
Py_XDECREF(arglist);
PyGILState_Release(state);
diff --git a/Modules/_ctypes/callproc.c b/Modules/_ctypes/callproc.c
index 9bc28c2..af6e1e8 100644
--- a/Modules/_ctypes/callproc.c
+++ b/Modules/_ctypes/callproc.c
@@ -1231,7 +1231,9 @@ PyObject *_ctypes_callproc(PPROC pProc,
if (rtype->type != FFI_TYPE_FLOAT
&& rtype->type != FFI_TYPE_STRUCT
&& rtype->size < sizeof(ffi_arg))
+ {
resbuf = (char *)resbuf + sizeof(ffi_arg) - rtype->size;
+ }
#endif
#ifdef MS_WIN32