self.assertEqual(cm.unraisable.exc_type, TypeError)
+ def test_crash_with_not_enough_args(self):
+ # gh-126220
+ import _lsprof
+
+ for profile in [_lsprof.Profiler(), cProfile.Profile()]:
+ for method in [
+ "_pystart_callback",
+ "_pyreturn_callback",
+ "_ccall_callback",
+ "_creturn_callback",
+ ]:
+ with self.subTest(profile=profile, method=method):
+ method_obj = getattr(profile, method)
+ with self.assertRaises(TypeError):
+ method_obj() # should not crash
+
def test_evil_external_timer(self):
# gh-120289
# Disabling profiler in external timer should not crash
PyObject* pystart_callback(ProfilerObject* self, PyObject *const *args, Py_ssize_t size)
{
+ if (size < 2) {
+ PyErr_Format(PyExc_TypeError,
+ "_pystart_callback expected 2 arguments, got %zd",
+ size);
+ return NULL;
+ }
PyObject* code = args[0];
ptrace_enter_call((PyObject*)self, (void *)code, (PyObject *)code);
PyObject* pyreturn_callback(ProfilerObject* self, PyObject *const *args, Py_ssize_t size)
{
+ if (size < 3) {
+ PyErr_Format(PyExc_TypeError,
+ "_pyreturn_callback expected 3 arguments, got %zd",
+ size);
+ return NULL;
+ }
PyObject* code = args[0];
ptrace_leave_call((PyObject*)self, (void *)code);
PyObject* ccall_callback(ProfilerObject* self, PyObject *const *args, Py_ssize_t size)
{
+ if (size < 4) {
+ PyErr_Format(PyExc_TypeError,
+ "_ccall_callback expected 4 arguments, got %zd",
+ size);
+ return NULL;
+ }
if (self->flags & POF_BUILTINS) {
PyObject* callable = args[2];
PyObject* self_arg = args[3];
PyObject* creturn_callback(ProfilerObject* self, PyObject *const *args, Py_ssize_t size)
{
+ if (size < 4) {
+ PyErr_Format(PyExc_TypeError,
+ "_creturn_callback expected 4 arguments, got %zd",
+ size);
+ return NULL;
+ }
if (self->flags & POF_BUILTINS) {
PyObject* callable = args[2];
PyObject* self_arg = args[3];