summaryrefslogtreecommitdiffstats
path: root/Python
diff options
context:
space:
mode:
authorSteve Dower <steve.dower@python.org>2019-11-28 16:46:11 (GMT)
committerGitHub <noreply@github.com>2019-11-28 16:46:11 (GMT)
commitbea33f5e1db6e4a554919a82894f44568576e979 (patch)
tree37789378933d7091eb0012d6ad3277aa8685a979 /Python
parent02519f75d15b063914a11351da30178ca4ceb54b (diff)
downloadcpython-bea33f5e1db6e4a554919a82894f44568576e979.zip
cpython-bea33f5e1db6e4a554919a82894f44568576e979.tar.gz
cpython-bea33f5e1db6e4a554919a82894f44568576e979.tar.bz2
bpo-38920: Add audit hooks for when sys.excepthook and sys.unraisable hooks are invoked (GH-17392)
Also fixes some potential segfaults in unraisable hook handling.
Diffstat (limited to 'Python')
-rw-r--r--Python/errors.c70
-rw-r--r--Python/pythonrun.c8
-rw-r--r--Python/sysmodule.c4
3 files changed, 50 insertions, 32 deletions
diff --git a/Python/errors.c b/Python/errors.c
index 1783084..d65707e 100644
--- a/Python/errors.c
+++ b/Python/errors.c
@@ -1391,43 +1391,53 @@ _PyErr_WriteUnraisableMsg(const char *err_msg_str, PyObject *obj)
}
}
+ PyObject *hook_args = make_unraisable_hook_args(
+ tstate, exc_type, exc_value, exc_tb, err_msg, obj);
+ if (hook_args == NULL) {
+ err_msg_str = ("Exception ignored on building "
+ "sys.unraisablehook arguments");
+ goto error;
+ }
+
_Py_IDENTIFIER(unraisablehook);
PyObject *hook = _PySys_GetObjectId(&PyId_unraisablehook);
- if (hook != NULL && hook != Py_None) {
- PyObject *hook_args;
-
- hook_args = make_unraisable_hook_args(tstate, exc_type, exc_value,
- exc_tb, err_msg, obj);
- if (hook_args != NULL) {
- PyObject *res = _PyObject_CallOneArg(hook, hook_args);
- Py_DECREF(hook_args);
- if (res != NULL) {
- Py_DECREF(res);
- goto done;
- }
-
- err_msg_str = "Exception ignored in sys.unraisablehook";
- }
- else {
- err_msg_str = ("Exception ignored on building "
- "sys.unraisablehook arguments");
- }
+ if (hook == NULL) {
+ Py_DECREF(hook_args);
+ goto default_hook;
+ }
- Py_XDECREF(err_msg);
- err_msg = PyUnicode_FromString(err_msg_str);
- if (err_msg == NULL) {
- PyErr_Clear();
- }
+ if (PySys_Audit("sys.unraisablehook", "OO", hook, hook_args) < 0) {
+ Py_DECREF(hook_args);
+ err_msg_str = "Exception ignored in audit hook";
+ obj = NULL;
+ goto error;
+ }
- /* sys.unraisablehook failed: log its error using default hook */
- Py_XDECREF(exc_type);
- Py_XDECREF(exc_value);
- Py_XDECREF(exc_tb);
- _PyErr_Fetch(tstate, &exc_type, &exc_value, &exc_tb);
+ if (hook == Py_None) {
+ Py_DECREF(hook_args);
+ goto default_hook;
+ }
- obj = hook;
+ PyObject *res = _PyObject_CallOneArg(hook, hook_args);
+ Py_DECREF(hook_args);
+ if (res != NULL) {
+ Py_DECREF(res);
+ goto done;
}
+ /* sys.unraisablehook failed: log its error using default hook */
+ obj = hook;
+ err_msg_str = NULL;
+
+error:
+ /* err_msg_str and obj have been updated and we have a new exception */
+ Py_XSETREF(err_msg, PyUnicode_FromString(err_msg_str ?
+ err_msg_str : "Exception ignored in sys.unraisablehook"));
+ Py_XDECREF(exc_type);
+ Py_XDECREF(exc_value);
+ Py_XDECREF(exc_tb);
+ _PyErr_Fetch(tstate, &exc_type, &exc_value, &exc_tb);
+
default_hook:
/* Call the default unraisable hook (ignore failure) */
(void)write_unraisable_exc(tstate, exc_type, exc_value, exc_tb,
diff --git a/Python/pythonrun.c b/Python/pythonrun.c
index 77a95ce..b68a0b5 100644
--- a/Python/pythonrun.c
+++ b/Python/pythonrun.c
@@ -695,6 +695,14 @@ _PyErr_PrintEx(PyThreadState *tstate, int set_sys_last_vars)
}
}
hook = _PySys_GetObjectId(&PyId_excepthook);
+ if (PySys_Audit("sys.excepthook", "OOOO", hook ? hook : Py_None,
+ exception, v, tb) < 0) {
+ if (PyErr_ExceptionMatches(PyExc_RuntimeError)) {
+ PyErr_Clear();
+ goto done;
+ }
+ _PyErr_WriteUnraisableMsg("in audit hook", NULL);
+ }
if (hook) {
PyObject* stack[3];
PyObject *result;
diff --git a/Python/sysmodule.c b/Python/sysmodule.c
index 30c7e98..78b9d22 100644
--- a/Python/sysmodule.c
+++ b/Python/sysmodule.c
@@ -323,8 +323,8 @@ PySys_AddAuditHook(Py_AuditHookFunction hook, void *userData)
/* Cannot invoke hooks until we are initialized */
if (runtime->initialized) {
if (PySys_Audit("sys.addaudithook", NULL) < 0) {
- if (_PyErr_ExceptionMatches(tstate, PyExc_Exception)) {
- /* We do not report errors derived from Exception */
+ if (_PyErr_ExceptionMatches(tstate, PyExc_RuntimeError)) {
+ /* We do not report errors derived from RuntimeError */
_PyErr_Clear(tstate);
return 0;
}