-
-
Notifications
You must be signed in to change notification settings - Fork 34.3k
Open
Labels
3.13bugs and security fixesbugs and security fixes3.14bugs and security fixesbugs and security fixes3.15new features, bugs and security fixesnew features, bugs and security fixesinterpreter-core(Objects, Python, Grammar, and Parser dirs)(Objects, Python, Grammar, and Parser dirs)type-crashA hard crash of the interpreter, possibly with a core dumpA hard crash of the interpreter, possibly with a core dump
Description
Crash report
What happened?
It's possible to cause assertion errors due to calls returning NULL on OOM in _zoneinfo.
Automated diagnosis:
Multiple PyMem_Malloc/PyMem_Calloc calls in load_data (including ts_to_local at line 2130) return NULL on OOM and goto error without setting an exception. The caller returns NULL without exception → assertion failure.
File: Modules/_zoneinfo.c, lines 1029-1137 (load_data), 2130 (ts_to_local)
MRE for load_data:
import _testcapi, sys
for mod in ["zoneinfo", "_zoneinfo"]:
if mod in sys.modules:
del sys.modules[mod]
for n in range(1, 50):
for mod in ["zoneinfo", "_zoneinfo"]:
if mod in sys.modules:
del sys.modules[mod]
print(n)
_testcapi.set_nomemory(n, 0)
try:
from zoneinfo import ZoneInfo
z = ZoneInfo("UTC")
_testcapi.remove_mem_hooks()
break
except MemoryError:
_testcapi.remove_mem_hooks()MRE for ts_to_local:
import _testcapi
from zoneinfo import ZoneInfo
# Warm up imports — we only want OOM during zone construction
_ = ZoneInfo("UTC")
del _
# Clear cache so America/New_York gets re-loaded from TZif data
ZoneInfo.clear_cache()
# Persistent failure from allocation #9 onward.
# Early allocs (import machinery, arg parsing) succeed;
# the PyMem_Malloc in load_data/ts_to_local fails.
_testcapi.set_nomemory(9, 0)
z = ZoneInfo("America/New_York") # crashes: assertion `obj != NULL'Backtrace:
python: ./Include/internal/pycore_stackref.h:554: _PyStackRef PyStackRef_FromPyObjectSteal(PyObject *): Assertion `obj != NULL' failed.
Program received signal SIGABRT, Aborted.
#0 __pthread_kill_implementation (threadid=<optimized out>, signo=6, no_tid=0) at ./nptl/pthread_kill.c:44
#1 __pthread_kill_internal (threadid=<optimized out>, signo=6) at ./nptl/pthread_kill.c:89
#2 __GI___pthread_kill (threadid=<optimized out>, signo=signo@entry=6) at ./nptl/pthread_kill.c:100
#3 0x00007ffff7c45e2e in __GI_raise (sig=sig@entry=6) at ../sysdeps/posix/raise.c:26
#4 0x00007ffff7c28888 in __GI_abort () at ./stdlib/abort.c:77
#5 0x00007ffff7c287f0 in __assert_fail_base (fmt=<optimized out>, assertion=<optimized out>, file=<optimized out>, line=<optimized out>, function=<optimized out>) at ./assert/assert.c:118
#6 0x00007ffff7c3c19f in __assert_fail (assertion=<optimized out>, file=<optimized out>, line=<optimized out>, function=<optimized out>) at ./assert/assert.c:127
#7 0x000055555587fd55 in PyStackRef_FromPyObjectSteal (obj=<optimized out>) at ./Include/internal/pycore_stackref.h:554
#8 0x0000555555842cd0 in _PyEval_EvalFrameDefault (tstate=tstate@entry=0x555555d99c08 <_PyRuntime+360664>, frame=<optimized out>, frame@entry=0x7ffff7fa70a0, throwflag=throwflag@entry=0)
at Python/generated_cases.c.h:292
#9 0x000055555583f08b in _PyEval_EvalFrame (tstate=0x555555d99c08 <_PyRuntime+360664>, frame=0x7ffff7fa70a0, throwflag=0) at ./Include/internal/pycore_ceval.h:118
#10 _PyEval_Vector (tstate=0x555555d99c08 <_PyRuntime+360664>, func=0x7ffff75e9190, locals=0x0, args=0x7fffffffb310, argcount=2, kwnames=0x0) at Python/ceval.c:2130
#11 0x00005555556a2ebe in _PyObject_VectorcallTstate (tstate=0x555555d99c08 <_PyRuntime+360664>, callable=callable@entry=0x7ffff75e9190, args=args@entry=0x7fffffffb310,
nargsf=nargsf@entry=2, kwnames=kwnames@entry=0x0) at ./Include/internal/pycore_call.h:144
#12 0x00005555556a625a in object_vacall (tstate=tstate@entry=0x555555d99c08 <_PyRuntime+360664>, base=base@entry=0x0, callable=callable@entry=0x7ffff75e9190,
vargs=vargs@entry=0x7fffffffb460) at Objects/call.c:823
#13 0x00005555556a5f0b in PyObject_CallMethodObjArgs (obj=0x7ffff75b08c0, name=0x555555d57470 <_PyRuntime+88384>) at Objects/call.c:960
#14 0x000055555595136b in import_find_and_load (tstate=tstate@entry=0x555555d99c08 <_PyRuntime+360664>, abs_name=abs_name@entry=0x7ffff74f86d0) at Python/import.c:4125
#15 0x0000555555950f66 in PyImport_ImportModuleLevelObject (name=name@entry=0x7ffff74f86d0, globals=globals@entry=0x7ffff746a4b0, locals=locals@entry=0x7ffff746a4b0,
fromlist=0x7ffff7477cf0, level=level@entry=0) at Python/import.c:4241
#16 0x00005555558f7265 in _PyEval_ImportNameWithImport (tstate=tstate@entry=0x555555d99c08 <_PyRuntime+360664>, import_func=0x7ffff75be9f0, globals=globals@entry=0x7ffff746a4b0,
locals=locals@entry=0x7ffff746a4b0, name=name@entry=0x7ffff74f86d0, fromlist=fromlist@entry=0x7ffff7477cf0, level=0x555555d49188 <_PyRuntime+30296>) at Python/ceval.c:2975
#17 0x00005555558848bf in _PyEval_ImportName (tstate=tstate@entry=0x555555d99c08 <_PyRuntime+360664>, builtins=0x7ffff75be930, globals=0x7ffff746a4b0, locals=0x7ffff746a4b0,
name=0x7ffff74f86d0, fromlist=0x7ffff7477cf0, level=0x555555d49188 <_PyRuntime+30296>) at Python/ceval.c:2954
#18 0x000055555586141a in _PyEval_EvalFrameDefault (tstate=tstate@entry=0x555555d99c08 <_PyRuntime+360664>, frame=<optimized out>, frame@entry=0x7ffff7fa7020, throwflag=throwflag@entry=0)
at Python/generated_cases.c.h:6460
#19 0x000055555583f08b in _PyEval_EvalFrame (tstate=0x555555d99c08 <_PyRuntime+360664>, frame=0x7ffff7fa7020, throwflag=0) at ./Include/internal/pycore_ceval.h:118
#20 _PyEval_Vector (tstate=tstate@entry=0x555555d99c08 <_PyRuntime+360664>, func=func@entry=0x7ffff7466690, locals=locals@entry=0x7ffff746a4b0, args=args@entry=0x0,
argcount=argcount@entry=0, kwnames=kwnames@entry=0x0) at Python/ceval.c:2130
#21 0x000055555583ee1e in PyEval_EvalCode (co=co@entry=0x555555f3baf0, globals=globals@entry=0x7ffff746a4b0, locals=locals@entry=0x7ffff746a4b0) at Python/ceval.c:686
#22 0x00005555559c8f8e in run_eval_code_obj (tstate=0x555555d99c08 <_PyRuntime+360664>, co=co@entry=0x555555f3baf0, globals=globals@entry=0x7ffff746a4b0, locals=locals@entry=0x7ffff746a4b0)
at Python/pythonrun.c:1368
#23 0x00005555559c8adb in run_mod (mod=mod@entry=0x555555f43b30, filename=filename@entry=0x7ffff74e8580, globals=globals@entry=0x7ffff746a4b0, locals=locals@entry=0x7ffff746a4b0,
flags=0x7fffffffc950, arena=arena@entry=0x7ffff74dad40, interactive_src=0x0, generate_new_source=0) at Python/pythonrun.c:1471
Found using cpython-review-toolkit with Claude Opus 4.6, using the /cpython-review-toolkit:explore Modules/_zoneinfo.c all deep command.
CPython versions tested on:
CPython main branch
Operating systems tested on:
Linux
Output from running 'python -VV' on the command line:
Python 3.15.0a7+ (heads/main:e0f7c1097e1, Mar 17 2026, 18:10:52) [Clang 21.1.2 (2ubuntu6)]
Linked PRs
- gh-146092: Fix error handling in _BINARY_OP_ADD_UNICODE opcode #146117
- [3.14] gh-146092: Fix error handling in _BINARY_OP_ADD_FLOAT opcode #146119
- gh-146092: Handle _PyFrame_GetFrameObject() failures properly #146124
- [3.14] gh-146092: Handle _PyFrame_GetFrameObject() failures properly (#146124) #146132
- [3.13] gh-146092: Handle _PyFrame_GetFrameObject() failures properly (GH-146124) (GH-146132) #146138
Reactions are currently unavailable
Metadata
Metadata
Assignees
Labels
3.13bugs and security fixesbugs and security fixes3.14bugs and security fixesbugs and security fixes3.15new features, bugs and security fixesnew features, bugs and security fixesinterpreter-core(Objects, Python, Grammar, and Parser dirs)(Objects, Python, Grammar, and Parser dirs)type-crashA hard crash of the interpreter, possibly with a core dumpA hard crash of the interpreter, possibly with a core dump