I read the discussion related to issue32374. That seems to be sure that other events that could cause the test to fail (i.e., the program executes successfully) are caught early, and/or ignored so that the program fails - and the test succeeds.
I am having trouble figuring out why the script below does not fail on AIX, and would appreciate your assistance in debugging what is happening, i.e., getting deeper. Many thanks! +270 @unittest.skipIf(not hasattr(sys, 'gettotalrefcount'), +271 '--with-pydebug has to be enabled for this test') +272 def test_bad_traverse(self): +273 ''' Issue #32374: Test that traverse fails when accessing per-module +274 state before Py_mod_exec was executed. +275 (Multiphase initialization modules only) +276 ''' +277 script = """if True: +278 try: +279 from test import support +280 import importlib.util as util +281 spec = util.find_spec('_testmultiphase') +282 spec.name = '_testmultiphase_with_bad_traverse' +283 +284 with support.SuppressCrashReport(): +285 m = spec.loader.create_module(spec) +286 except: +287 # Prevent Python-level exceptions from +288 # ending the process with non-zero status +289 # (We are testing for a crash in C-code) +290 pass""" +291 assert_python_failure("-c", script) To make sure the full debug info is loaded I added "-X dev", and for your reading added some additional print statements - and for speed run the command directly. Regardless of how I run it (calling as a test, or directly) the end-result is the same. # Note: I was not able to fine the default "loader.create_module() code" to add debugging statements. # Pointer for that is welcome! ./python -X dev '-X' 'faulthandler' '-I' '-c' "if True: try: from test import support import importlib.util as util spec = util.find_spec('_testmultiphase') spec.name = '_testmultiphase_with_bad_traverse' m = spec.loader.create_module(spec) print(m) print(dir(m)) print(m.__doc__) print(m.__loader__) print(m.__name__) print(m.__package__) print(m.__spec__) except: # Prevent Python-level exceptions from # ending the process with non-zero status # (We are testing for a crash in C-code) print('in except')" <module '_testmultiphase_with_bad_traverse'> ['__doc__', '__loader__', '__name__', '__package__', '__spec__'] Test module _testmultiphase_with_bad_traverse None _testmultiphase_with_bad_traverse None None root@x066:[/data/prj/python/git/Python3-3.8.0]echo $? 0 To get some additional idea of what is happening I added some fprintf statements: The additional debug info is: (see diff below) 1. bad_traverse:0 2. bad_traverse:0 1. bad_traverse:0 2. bad_traverse:0 1. bad_traverse:0 2. bad_traverse:0 *** To my SURPRISE *** only one routine with these print statements is ever called. I was expecting at more. (only bad_traverse(...) gets called, I was expecting both bad_traverse_test (Objects/moduleobject.c) and some kind of initialization of m_state->integer. Since the macro Py_VISIT includes a return() statement, and my debug statement always print the second line - I assume Py_VISIT(m_state->integer) is not doing anything (i.e., vret == 0) /* Utility macro to help write tp_traverse functions. * To use this macro, the tp_traverse function must name its arguments * "visit" and "arg". This is intended to keep tp_traverse functions * looking as much alike as possible. */ #define Py_VISIT(op) \ do { \ if (op) { \ int vret = visit((PyObject *)(op), arg); \ if (vret) \ return vret; \ } \ } while (0) Is this what it should be? root@x066:[/data/prj/python/git/Python3-3.8.0]git status On branch aix-pr Changes not staged for commit: (use "git add <file>..." to update what will be committed) (use "git checkout -- <file>..." to discard changes in working directory) modified: Modules/_testmultiphase.c modified: Objects/moduleobject.c no changes added to commit (use "git add" and/or "git commit -a") root@x066:[/data/prj/python/git/Python3-3.8.0]git diff root@x066:[/data/prj/python/git/Python3-3.8.0]git diff | cat diff --git a/Modules/_testmultiphase.c b/Modules/_testmultiphase.c index 5776df7d76..c28aef1455 100644 --- a/Modules/_testmultiphase.c +++ b/Modules/_testmultiphase.c @@ -622,23 +622,34 @@ PyInit__testmultiphase_exec_unreported_exception(PyObject *spec) static int bad_traverse(PyObject *self, visitproc visit, void *arg) { testmultiphase_state *m_state; +FILE *errmsg = fopen("/tmp/err", "a"); m_state = PyModule_GetState(self); +fprintf(errmsg,"1. bad_traverse:%ld\n", m_state->integer); Py_VISIT(m_state->integer); +fprintf(errmsg,"2. bad_traverse:%ld\n", m_state->integer); +fclose(errmsg); return 0; } static int execfunc_with_bad_traverse(PyObject *mod) { testmultiphase_state *m_state; +FILE *errmsg; +errmsg = fopen("/tmp/err", "a"); m_state = PyModule_GetState(mod); if (m_state == NULL) { +fprintf(errmsg,"0.execfunc:\n"); +fclose(errmsg); return -1; } m_state->integer = PyLong_FromLong(0x7fffffff); +fprintf(errmsg,"1.execfunc:%ld\n", m_state->integer); Py_INCREF(m_state->integer); +fprintf(errmsg,"2.execfunc:%ld\n", m_state->integer); +fclose(errmsg); return 0; } diff --git a/Objects/moduleobject.c b/Objects/moduleobject.c index ccf5f8e6d1..603611c686 100644 --- a/Objects/moduleobject.c +++ b/Objects/moduleobject.c @@ -27,6 +27,9 @@ static PyMemberDef module_members[] = { #ifdef Py_DEBUG static int bad_traverse_test(PyObject *self, void *arg) { +FILE *errmsg = fopen("/tmp/err","a"); +fprintf(errmsg,"bad_traverse_test: self!=NULL:%d\n", self != NULL); +fclose(errmsg); assert(self != NULL); return 0; } root@x066:[/data/prj/python/git/Python3-3.8.0] ~
signature.asc
Description: OpenPGP digital signature
_______________________________________________ Python-Dev mailing list Python-Dev@python.org https://mail.python.org/mailman/listinfo/python-dev Unsubscribe: https://mail.python.org/mailman/options/python-dev/archive%40mail-archive.com