diff options
author | Kumar Aditya <59607654+kumaraditya303@users.noreply.github.com> | 2022-07-25 17:43:59 (GMT) |
---|---|---|
committer | GitHub <noreply@github.com> | 2022-07-25 17:43:59 (GMT) |
commit | 73ee5a6b865fbd2e89b5b1f0a33bd7bcc7176c21 (patch) | |
tree | 7569696566888b771821aae36a84065ef9a00a66 /Tools/scripts | |
parent | ac6a94c669cba8c8384a61b4304c87cc83728335 (diff) | |
download | cpython-73ee5a6b865fbd2e89b5b1f0a33bd7bcc7176c21.zip cpython-73ee5a6b865fbd2e89b5b1f0a33bd7bcc7176c21.tar.gz cpython-73ee5a6b865fbd2e89b5b1f0a33bd7bcc7176c21.tar.bz2 |
GH-94851: check refcnt of immortal objects after finalization (GH-95001)
Diffstat (limited to 'Tools/scripts')
-rw-r--r-- | Tools/scripts/generate_global_objects.py | 19 |
1 files changed, 19 insertions, 0 deletions
diff --git a/Tools/scripts/generate_global_objects.py b/Tools/scripts/generate_global_objects.py index 27e3530..f3a11f5 100644 --- a/Tools/scripts/generate_global_objects.py +++ b/Tools/scripts/generate_global_objects.py @@ -250,6 +250,7 @@ def generate_runtime_init(identifiers, strings): # Generate the file. with open_for_changes(filename, orig) as outfile: + immortal_objects = [] printer = Printer(outfile) printer.write(before) printer.write(START) @@ -259,31 +260,39 @@ def generate_runtime_init(identifiers, strings): with printer.block('.small_ints =', ','): for i in range(-nsmallnegints, nsmallposints): printer.write(f'_PyLong_DIGIT_INIT({i}),') + immortal_objects.append(f'(PyObject *)&_Py_SINGLETON(small_ints)[_PY_NSMALLNEGINTS + {i}]') printer.write('') # Global bytes objects. printer.write('.bytes_empty = _PyBytes_SIMPLE_INIT(0, 0),') + immortal_objects.append(f'(PyObject *)&_Py_SINGLETON(bytes_empty)') with printer.block('.bytes_characters =', ','): for i in range(256): printer.write(f'_PyBytes_CHAR_INIT({i}),') + immortal_objects.append(f'(PyObject *)&_Py_SINGLETON(bytes_characters)[{i}]') printer.write('') # Global strings. with printer.block('.strings =', ','): with printer.block('.literals =', ','): for literal, name in sorted(strings.items(), key=lambda x: x[1]): printer.write(f'INIT_STR({name}, "{literal}"),') + immortal_objects.append(f'(PyObject *)&_Py_STR({name})') with printer.block('.identifiers =', ','): for name in sorted(identifiers): assert name.isidentifier(), name printer.write(f'INIT_ID({name}),') + immortal_objects.append(f'(PyObject *)&_Py_ID({name})') with printer.block('.ascii =', ','): for i in range(128): printer.write(f'_PyASCIIObject_INIT("\\x{i:02x}"),') + immortal_objects.append(f'(PyObject *)&_Py_SINGLETON(strings).ascii[{i}]') with printer.block('.latin1 =', ','): for i in range(128, 256): printer.write(f'_PyUnicode_LATIN1_INIT("\\x{i:02x}"),') + immortal_objects.append(f'(PyObject *)&_Py_SINGLETON(strings).latin1[{i} - 128]') printer.write('') with printer.block('.tuple_empty =', ','): printer.write('.ob_base = _PyVarObject_IMMORTAL_INIT(&PyTuple_Type, 0)') + immortal_objects.append(f'(PyObject *)&_Py_SINGLETON(tuple_empty)') printer.write('') printer.write("static inline void") with printer.block("_PyUnicode_InitStaticStrings(void)"): @@ -293,6 +302,16 @@ def generate_runtime_init(identifiers, strings): # since iter_files() ignores .h files. printer.write(f'string = &_Py_ID({i});') printer.write(f'PyUnicode_InternInPlace(&string);') + printer.write('') + printer.write('#ifdef Py_DEBUG') + printer.write("static inline void") + with printer.block("_PyStaticObjects_CheckRefcnt(void)"): + for i in immortal_objects: + with printer.block(f'if (Py_REFCNT({i}) < _PyObject_IMMORTAL_REFCNT)', ';'): + printer.write(f'_PyObject_Dump({i});') + printer.write(f'Py_FatalError("immortal object has less refcnt than ' + 'expected _PyObject_IMMORTAL_REFCNT");') + printer.write('#endif') printer.write(END) printer.write(after) |