-
Notifications
You must be signed in to change notification settings - Fork 909
Description
While investigating pydantic/pydantic-core#451 I noticed that when running on a debug build of Python, the SchemaSerializer pyclass with gc protocol support raised a warning
ResourceWarning: Object of type pydantic_core._pydantic_core.SchemaSerializer is not untracked before destruction
and caused a segfault on debug build of Python only:
collected 3134 items / 3133 deselected / 1 selected
tests/validators/test_datetime.py
Program received signal SIGABRT, Aborted.
__pthread_kill_implementation (no_tid=0, signo=6, threadid=140737350287360) at ./nptl/pthread_kill.c:44
Download failed: Invalid argument. Continuing without source file ./nptl/./nptl/pthread_kill.c.
44 ./nptl/pthread_kill.c: No such file or directory.
(gdb) bt
#0 __pthread_kill_implementation (no_tid=0, signo=6, threadid=140737350287360) at ./nptl/pthread_kill.c:44
#1 __pthread_kill_internal (signo=6, threadid=140737350287360) at ./nptl/pthread_kill.c:78
#2 __GI___pthread_kill (threadid=140737350287360, signo=signo@entry=6) at ./nptl/pthread_kill.c:89
#3 0x00007ffff7c97476 in __GI_raise (sig=sig@entry=6) at ../sysdeps/posix/raise.c:26
#4 0x00007ffff7c7d7f3 in __GI_abort () at ./stdlib/abort.c:79
#5 0x00007ffff7c7d71b in __assert_fail_base (fmt=0x7ffff7e32150 "%s%s%s:%u: %s%sAssertion `%s' failed.\n%n", assertion=0x77bda9 "!_PyErr_Occurred(tstate)", file=0x78fc93 "../Objects/typeobject.c", line=1068, function=<optimized out>)
at ./assert/assert.c:92
#6 0x00007ffff7c8ee96 in __GI___assert_fail (assertion=assertion@entry=0x77bda9 "!_PyErr_Occurred(tstate)", file=file@entry=0x78fc93 "../Objects/typeobject.c", line=line@entry=1068,
function=function@entry=0x790510 <__PRETTY_FUNCTION__.30> "type_call") at ./assert/assert.c:101
#7 0x000000000052a1c8 in type_call (type=0xa21640 <_PyExc_ResourceWarning>, args=('Object of type pydantic_core._pydantic_core.SchemaValidator is not untracked before destruction',), kwds=0x0) at ../Objects/typeobject.c:1068
#8 0x00000000004b8b15 in _PyObject_MakeTpCall (tstate=tstate@entry=0xb46058 <_PyRuntime+166328>, callable=callable@entry=<type at remote 0xa21640>, args=args@entry=0x7fffffffbba8, nargs=<optimized out>, keywords=keywords@entry=0x0)
at ../Objects/call.c:214
#9 0x00000000004b8e91 in _PyObject_VectorcallTstate (tstate=0xb46058 <_PyRuntime+166328>, callable=<type at remote 0xa21640>, args=args@entry=0x7fffffffbba8, nargsf=<optimized out>, nargsf@entry=9223372036854775809,
kwnames=kwnames@entry=0x0) at ../Include/internal/pycore_call.h:90
#10 0x00000000004b8f4e in PyObject_CallOneArg (func=<optimized out>, arg=<optimized out>) at ../Objects/call.c:376
#11 0x000000000058e1fd in warn_explicit (tstate=0xb46058 <_PyRuntime+166328>, category=<type at remote 0xa21640>,
category@entry=<error reading variable: Dwarf Error: Cannot find DIE at 0x1c9 referenced from DIE at 0x3de638 [in module /root/code/pydantic-core/pydantic_core/_pydantic_core.cpython-311-x86_64-linux-gnu.so]>,
message=message@entry='Object of type pydantic_core._pydantic_core.SchemaValidator is not untracked before destruction', filename=filename@entry='gc', lineno=lineno@entry=0, module=module@entry='gc', registry=0x0, sourceline=0x0,
source=0x0) at ../Python/_warnings.c:671
#12 0x000000000058fe92 in PyErr_WarnExplicitFormat (category=<type at remote 0xa21640>, filename_str=<optimized out>, lineno=0, module_str=<optimized out>, registry=0x0, format=<optimized out>) at ../Python/_warnings.c:1286
Googling it leads us to apache/arrow#33765 (comment) which mentions PyObject_GC_UnTrack. According to its documentation
Remove the object
opfrom the set of container objects tracked by the collector. Note thatPyObject_GC_Track()can be called again on this object to add it back to the set of tracked objects. The deallocator (tp_deallochandler) should call this for the object before any of the fields used by thetp_traversehandler become invalid.
It seems that we should call it in our generated tp_dealloc handler for pyclasses that use the gc protocol?