bpo-35214: MSan workarounds for socket, time, and test_faulthandler. (GH-11375)
Add Clang Memory Sanitizer build instrumentation to work around false positives from the socket and time modules as well as skipping a couple test_faulthandler tests.
This commit is contained in:
parent
387512c7ec
commit
b474e6774d
@ -5,6 +5,7 @@ import os
|
|||||||
import signal
|
import signal
|
||||||
import subprocess
|
import subprocess
|
||||||
import sys
|
import sys
|
||||||
|
import sysconfig
|
||||||
from test import support
|
from test import support
|
||||||
from test.support import script_helper, is_android
|
from test.support import script_helper, is_android
|
||||||
import tempfile
|
import tempfile
|
||||||
@ -19,6 +20,10 @@ except ImportError:
|
|||||||
|
|
||||||
TIMEOUT = 0.5
|
TIMEOUT = 0.5
|
||||||
MS_WINDOWS = (os.name == 'nt')
|
MS_WINDOWS = (os.name == 'nt')
|
||||||
|
MEMORY_SANITIZER = (
|
||||||
|
sysconfig.get_config_var("CONFIG_ARGS") and
|
||||||
|
("--with-memory-sanitizer" in sysconfig.get_config_var("CONFIG_ARGS"))
|
||||||
|
)
|
||||||
|
|
||||||
def expected_traceback(lineno1, lineno2, header, min_count=1):
|
def expected_traceback(lineno1, lineno2, header, min_count=1):
|
||||||
regex = header
|
regex = header
|
||||||
@ -252,6 +257,8 @@ class FaultHandlerTests(unittest.TestCase):
|
|||||||
3,
|
3,
|
||||||
'Segmentation fault')
|
'Segmentation fault')
|
||||||
|
|
||||||
|
@unittest.skipIf(MEMORY_SANITIZER,
|
||||||
|
"memory-sanizer builds change crashing process output.")
|
||||||
@skip_segfault_on_android
|
@skip_segfault_on_android
|
||||||
def test_enable_file(self):
|
def test_enable_file(self):
|
||||||
with temporary_filename() as filename:
|
with temporary_filename() as filename:
|
||||||
@ -267,6 +274,8 @@ class FaultHandlerTests(unittest.TestCase):
|
|||||||
|
|
||||||
@unittest.skipIf(sys.platform == "win32",
|
@unittest.skipIf(sys.platform == "win32",
|
||||||
"subprocess doesn't support pass_fds on Windows")
|
"subprocess doesn't support pass_fds on Windows")
|
||||||
|
@unittest.skipIf(MEMORY_SANITIZER,
|
||||||
|
"memory-sanizer builds change crashing process output.")
|
||||||
@skip_segfault_on_android
|
@skip_segfault_on_android
|
||||||
def test_enable_fd(self):
|
def test_enable_fd(self):
|
||||||
with tempfile.TemporaryFile('wb+') as fp:
|
with tempfile.TemporaryFile('wb+') as fp:
|
||||||
|
@ -0,0 +1,2 @@
|
|||||||
|
clang Memory Sanitizer build instrumentation was added to work around false
|
||||||
|
positives from socket, time, and test_faulthandler.
|
@ -102,6 +102,10 @@ Local naming conventions:
|
|||||||
#include "Python.h"
|
#include "Python.h"
|
||||||
#include "structmember.h"
|
#include "structmember.h"
|
||||||
|
|
||||||
|
#ifdef _Py_MEMORY_SANITIZER
|
||||||
|
# include <sanitizer/msan_interface.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
/* Socket object documentation */
|
/* Socket object documentation */
|
||||||
PyDoc_STRVAR(sock_doc,
|
PyDoc_STRVAR(sock_doc,
|
||||||
"socket(family=AF_INET, type=SOCK_STREAM, proto=0) -> socket object\n\
|
"socket(family=AF_INET, type=SOCK_STREAM, proto=0) -> socket object\n\
|
||||||
@ -6571,7 +6575,23 @@ socket_if_nameindex(PyObject *self, PyObject *arg)
|
|||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#ifdef _Py_MEMORY_SANITIZER
|
||||||
|
__msan_unpoison(ni, sizeof(ni));
|
||||||
|
__msan_unpoison(&ni[0], sizeof(ni[0]));
|
||||||
|
#endif
|
||||||
for (i = 0; ni[i].if_index != 0 && i < INT_MAX; i++) {
|
for (i = 0; ni[i].if_index != 0 && i < INT_MAX; i++) {
|
||||||
|
#ifdef _Py_MEMORY_SANITIZER
|
||||||
|
/* This one isn't the end sentinel, the next one must exist. */
|
||||||
|
__msan_unpoison(&ni[i+1], sizeof(ni[0]));
|
||||||
|
/* Otherwise Py_BuildValue internals are flagged by MSan when
|
||||||
|
they access the not-msan-tracked if_name string data. */
|
||||||
|
{
|
||||||
|
char *to_sanitize = ni[i].if_name;
|
||||||
|
do {
|
||||||
|
__msan_unpoison(to_sanitize, 1);
|
||||||
|
} while (*to_sanitize++ != '\0');
|
||||||
|
}
|
||||||
|
#endif
|
||||||
PyObject *ni_tuple = Py_BuildValue("IO&",
|
PyObject *ni_tuple = Py_BuildValue("IO&",
|
||||||
ni[i].if_index, PyUnicode_DecodeFSDefault, ni[i].if_name);
|
ni[i].if_index, PyUnicode_DecodeFSDefault, ni[i].if_name);
|
||||||
|
|
||||||
|
@ -34,6 +34,10 @@
|
|||||||
#endif /* MS_WINDOWS */
|
#endif /* MS_WINDOWS */
|
||||||
#endif /* !__WATCOMC__ || __QNX__ */
|
#endif /* !__WATCOMC__ || __QNX__ */
|
||||||
|
|
||||||
|
#ifdef _Py_MEMORY_SANITIZER
|
||||||
|
# include <sanitizer/msan_interface.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
#define SEC_TO_NS (1000 * 1000 * 1000)
|
#define SEC_TO_NS (1000 * 1000 * 1000)
|
||||||
|
|
||||||
/* Forward declarations */
|
/* Forward declarations */
|
||||||
@ -336,6 +340,9 @@ time_pthread_getcpuclockid(PyObject *self, PyObject *args)
|
|||||||
PyErr_SetFromErrno(PyExc_OSError);
|
PyErr_SetFromErrno(PyExc_OSError);
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
#ifdef _Py_MEMORY_SANITIZER
|
||||||
|
__msan_unpoison(&clk_id, sizeof(clk_id));
|
||||||
|
#endif
|
||||||
return PyLong_FromLong(clk_id);
|
return PyLong_FromLong(clk_id);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user