Skip to content

Commit

Permalink
tox: *-asan: Activate LeakSanitizer on recent CPython 3
Browse files Browse the repository at this point in the history
Background: in 2019 in 4dc1a7f0 (tox += ThreadSanitizer, AddressSanitizer,
Python debug builds) I've added ThreadSanitizer and AddressSanitizer to our
test build matrix. That was done in order to help catching concurrency issues
while doing quality assurance and it indeed worked well(*). However AddressSanitizer
was added with disabled memory leak detection, because at that time there were
tons of various allocations done by Python itself, that were not released on
Python shutdown. So leak reporting pass was disabled to avoid huge non-pygolang
related printouts.

5 years later Pygolang is used by various projects, including in XLTE, where, in
particular, it is used to organize 100Hz polling of Amarisoft eNodeB service to
retrieve information about flows on Data Radio Bearers:

https://lab.nexedi.com/kirr/xlte/-/commit/2a016d48
https://lab.nexedi.com/kirr/xlte/-/blob/8e606c64/amari/drb.py

And everything works relatively well except that recently Joanne approached me
with reports that xamari program, that does the polling, is leaking memory.

During investigation I could manually find at least two causes of the leakage,
and, while working on a fix, discovered third type of leak. Since all those
leaks happen inside Pygolang and at, or around, C level - most of the
time not visible through python objects and so not discoverable via e.g
objgraph, it raises the need to have robust quality assurance procedures
built into maintenance process to cover not only concurrency and memory
safety issues, but also to reliably detect low-level memory leaks.

So before we start fixing any of the leakages, let's activate LeakSanitizer
(https://github.com/google/sanitizers/wiki/AddressSanitizerLeakSanitizer) to be
present during tox runs, so that whenever we run something via ASAN in the end
tested process is checked for whether anything was leaked and if yes, which
codepath was used to allocate leaked memory.

Initially I though that it would be hard to have distilled reports, the ones
without much of added noise due to leaks on python side, but it turns out that
starting from py3.11 cpython codebase was improved to release on interpreter
shutdown most of what was allocated, and so with modest suppression rules we
can distill LeakSanitizer output to come with the issues that are relevant to
pygolang itself.

That builds the foundation for making sure there are no memory leaks done by
pygolang in the follow-up patches. The next patch will fix chan leakage in
pychan_from_raw, and there will be more fixes to come later.

For now ASAN builds become broken, but that is good that we can see the issues.
Please see the appendix for current LeakSanitizer output.

/cc ORS team (@jhuge, @lu.xu, @tomo, @xavier_thompson, @Daetalus)
/reviewed-by @jerome
/reviewed-on https://lab.nexedi.com/nexedi/pygolang/-/merge_requests/24

(*) at that time, besides discovering longstanding race-condition in Python itself
(https://bugs.python.org/issue38106, https://github.com/python/cpython/pull/16047),
several concurrency issues were found in pygolang codebase as well:

https://lab.nexedi.com/nexedi/pygolang/commit/dcf4ebd1
https://lab.nexedi.com/nexedi/pygolang/commit/65c43848
https://lab.nexedi.com/nexedi/pygolang/commit/5aa1e899
https://lab.nexedi.com/nexedi/pygolang/commit/fd2a6fab

--------

Appendix. List of errors currently emitted by LeakSanitizer when running Pygolang tests

```
==2061372==ERROR: LeakSanitizer: detected memory leaks

Direct leak of 241136 byte(s) in 28 object(s) allocated from:
    #0 0x7f27922f3bd7 in malloc ../../../../src/libsanitizer/asan/asan_malloc_linux.cpp:69
    #1 0x555687a6a9d2 in PyMem_RawMalloc Objects/obmalloc.c:662
    #2 0x555687a6a9d2 in _PyObject_Malloc Objects/obmalloc.c:1569
    #3 0x555687a649e3 in _PyObject_NewVar Objects/object.c:332
    #4 0x555687a0c16b in _PyCode_New Objects/codeobject.c:582
    #5 0x555687b12f84 in makecode Python/assemble.c:574
    #6 0x555687b12f84 in _PyAssemble_MakeCodeObject Python/assemble.c:598
    #7 0x555687b2bdbe in optimize_and_assemble_code_unit Python/compile.c:7707
    #8 0x555687b2bdbe in optimize_and_assemble Python/compile.c:7734
    #9 0x555687b3b1a8 in compiler_function_body Python/compile.c:2247
    #10 0x555687b3b1a8 in compiler_function Python/compile.c:2356
    #11 0x555687b3b787 in compiler_body Python/compile.c:1703
    #12 0x555687b3b917 in compiler_codegen Python/compile.c:1719
    #13 0x555687b3c5c3 in compiler_mod Python/compile.c:1747
    #14 0x555687b3c5c3 in _PyAST_Compile Python/compile.c:584
    #15 0x555687b1f9a0 in builtin_compile_impl Python/bltinmodule.c:820
    #16 0x555687b1f9a0 in builtin_compile Python/clinic/bltinmodule.c.h:383
    #17 0x5556879a5949 in _PyEval_EvalFrameDefault Python/bytecodes.c:2966
    #18 0x555687a0833e in _PyObject_FastCallDictTstate Objects/call.c:144
    #19 0x555687a0833e in _PyObject_Call_Prepend Objects/call.c:508
    #20 0x555687a8ba6c in slot_tp_call Objects/typeobject.c:8770
    #21 0x555687a05733 in _PyObject_MakeTpCall Objects/call.c:240
    #22 0x5556879a3252 in _PyEval_EvalFrameDefault Python/bytecodes.c:2706
    #23 0x555687a22c14 in _PyEval_EvalFrame Include/internal/pycore_ceval.h:89
    #24 0x555687a22c14 in gen_send_ex2 Objects/genobject.c:230
    #25 0x555687a22c14 in gen_iternext Objects/genobject.c:604
    #26 0x555687a37fd0 in list_extend Objects/listobject.c:944
    #27 0x5556879a3a9a in _PyEval_EvalFrameDefault Python/bytecodes.c:3085
    #28 0x555687a0833e in _PyObject_FastCallDictTstate Objects/call.c:144
    #29 0x555687a0833e in _PyObject_Call_Prepend Objects/call.c:508
    #30 0x555687a8ba6c in slot_tp_call Objects/typeobject.c:8770
    #31 0x555687a05733 in _PyObject_MakeTpCall Objects/call.c:240
    #32 0x5556879a3252 in _PyEval_EvalFrameDefault Python/bytecodes.c:2706
    #33 0x555687a0833e in _PyObject_FastCallDictTstate Objects/call.c:144
    #34 0x555687a0833e in _PyObject_Call_Prepend Objects/call.c:508
    #35 0x555687a8ba6c in slot_tp_call Objects/typeobject.c:8770
    #36 0x555687a05733 in _PyObject_MakeTpCall Objects/call.c:240
    #37 0x5556879a3252 in _PyEval_EvalFrameDefault Python/bytecodes.c:2706
    #38 0x555687b22926 in _PyEval_EvalFrame Include/internal/pycore_ceval.h:89
    #39 0x555687b22926 in _PyEval_Vector Python/ceval.c:1683
    #40 0x555687b22926 in PyEval_EvalCode Python/ceval.c:578
    #41 0x555687b1ebdf in builtin_exec_impl Python/bltinmodule.c:1096
    #42 0x555687b1ebdf in builtin_exec Python/clinic/bltinmodule.c.h:586
    #43 0x555687a613ae in cfunction_vectorcall_FASTCALL_KEYWORDS Objects/methodobject.c:438
    #44 0x555687a05fff in _PyObject_VectorcallTstate Include/internal/pycore_call.h:92
    #45 0x555687a05fff in PyObject_Vectorcall Objects/call.c:325
    #46 0x5556879a3252 in _PyEval_EvalFrameDefault Python/bytecodes.c:2706
    #47 0x555687ba84fa in pymain_run_module Modules/main.c:300
    #48 0x555687ba8cd9 in pymain_run_python Modules/main.c:623
    #49 0x555687ba96f9 in Py_RunMain Modules/main.c:709
    #50 0x555687ba96f9 in pymain_main Modules/main.c:739
    #51 0x555687ba96f9 in Py_BytesMain Modules/main.c:763
    #52 0x7f2791c46249 in __libc_start_call_main ../sysdeps/nptl/libc_start_call_main.h:58
    #53 0x7f2791c46304 in __libc_start_main_impl ../csu/libc-start.c:360
    #54 0x5556879aa030 in _start (/home/kirr/local/py3.12/bin/python3.12+0x10c030) (BuildId: 90994913e85aac5c35e9f04b53a6eeee5a04786d)

Direct leak of 235267 byte(s) in 25 object(s) allocated from:
    #0 0x7f27922f3bd7 in malloc ../../../../src/libsanitizer/asan/asan_malloc_linux.cpp:69
    #1 0x555687a6a9d2 in PyMem_RawMalloc Objects/obmalloc.c:662
    #2 0x555687a6a9d2 in _PyObject_Malloc Objects/obmalloc.c:1569
    #3 0x5556879faf23 in _PyBytes_FromSize Objects/bytesobject.c:102
    #4 0x5556879faf23 in _PyBytes_FromSize Objects/bytesobject.c:83
    #5 0x5556879faf23 in PyBytes_FromStringAndSize Objects/bytesobject.c:134
    #6 0x555687a0e210 in _PyCode_GetCode Objects/codeobject.c:1535
    #7 0x555687b70339 in w_complex_object Python/marshal.c:554
    #8 0x555687b70339 in w_object Python/marshal.c:375
    #9 0x555687b6fde4 in w_complex_object Python/marshal.c:479
    #10 0x555687b6fde4 in w_object Python/marshal.c:375
    #11 0x555687b703b5 in w_complex_object Python/marshal.c:566
    #12 0x555687b703b5 in w_object Python/marshal.c:375
    #13 0x555687b6f470 in PyMarshal_WriteObjectToString Python/marshal.c:1669
    #14 0x5556879a57c9 in _PyEval_EvalFrameDefault Python/bytecodes.c:2929
    #15 0x555687a0833e in _PyObject_FastCallDictTstate Objects/call.c:144
    #16 0x555687a0833e in _PyObject_Call_Prepend Objects/call.c:508
    #17 0x555687a8ba6c in slot_tp_call Objects/typeobject.c:8770
    #18 0x555687a05733 in _PyObject_MakeTpCall Objects/call.c:240
    #19 0x5556879a3252 in _PyEval_EvalFrameDefault Python/bytecodes.c:2706
    #20 0x555687a22c14 in _PyEval_EvalFrame Include/internal/pycore_ceval.h:89
    #21 0x555687a22c14 in gen_send_ex2 Objects/genobject.c:230
    #22 0x555687a22c14 in gen_iternext Objects/genobject.c:604
    #23 0x555687a37fd0 in list_extend Objects/listobject.c:944
    #24 0x5556879a3a9a in _PyEval_EvalFrameDefault Python/bytecodes.c:3085
    #25 0x555687a0833e in _PyObject_FastCallDictTstate Objects/call.c:144
    #26 0x555687a0833e in _PyObject_Call_Prepend Objects/call.c:508
    #27 0x555687a8ba6c in slot_tp_call Objects/typeobject.c:8770
    #28 0x555687a05733 in _PyObject_MakeTpCall Objects/call.c:240
    #29 0x5556879a3252 in _PyEval_EvalFrameDefault Python/bytecodes.c:2706
    #30 0x555687a0833e in _PyObject_FastCallDictTstate Objects/call.c:144
    #31 0x555687a0833e in _PyObject_Call_Prepend Objects/call.c:508
    #32 0x555687a8ba6c in slot_tp_call Objects/typeobject.c:8770
    #33 0x555687a05733 in _PyObject_MakeTpCall Objects/call.c:240
    #34 0x5556879a3252 in _PyEval_EvalFrameDefault Python/bytecodes.c:2706
    #35 0x555687b22926 in _PyEval_EvalFrame Include/internal/pycore_ceval.h:89
    #36 0x555687b22926 in _PyEval_Vector Python/ceval.c:1683
    #37 0x555687b22926 in PyEval_EvalCode Python/ceval.c:578
    #38 0x555687b1ebdf in builtin_exec_impl Python/bltinmodule.c:1096
    #39 0x555687b1ebdf in builtin_exec Python/clinic/bltinmodule.c.h:586
    #40 0x555687a613ae in cfunction_vectorcall_FASTCALL_KEYWORDS Objects/methodobject.c:438
    #41 0x555687a05fff in _PyObject_VectorcallTstate Include/internal/pycore_call.h:92
    #42 0x555687a05fff in PyObject_Vectorcall Objects/call.c:325
    #43 0x5556879a3252 in _PyEval_EvalFrameDefault Python/bytecodes.c:2706
    #44 0x555687ba84fa in pymain_run_module Modules/main.c:300
    #45 0x555687ba8cd9 in pymain_run_python Modules/main.c:623
    #46 0x555687ba96f9 in Py_RunMain Modules/main.c:709
    #47 0x555687ba96f9 in pymain_main Modules/main.c:739
    #48 0x555687ba96f9 in Py_BytesMain Modules/main.c:763
    #49 0x7f2791c46249 in __libc_start_call_main ../sysdeps/nptl/libc_start_call_main.h:58
    #50 0x7f2791c46304 in __libc_start_main_impl ../csu/libc-start.c:360
    #51 0x5556879aa030 in _start (/home/kirr/local/py3.12/bin/python3.12+0x10c030) (BuildId: 90994913e85aac5c35e9f04b53a6eeee5a04786d)

Direct leak of 22656 byte(s) in 9 object(s) allocated from:
    #0 0x7f27922f3bd7 in malloc ../../../../src/libsanitizer/asan/asan_malloc_linux.cpp:69
    #1 0x555687a6a9d2 in PyMem_RawMalloc Objects/obmalloc.c:662
    #2 0x555687a6a9d2 in _PyObject_Malloc Objects/obmalloc.c:1569
    #3 0x555687a649e3 in _PyObject_NewVar Objects/object.c:332
    #4 0x555687a0c16b in _PyCode_New Objects/codeobject.c:582
    #5 0x555687b12f84 in makecode Python/assemble.c:574
    #6 0x555687b12f84 in _PyAssemble_MakeCodeObject Python/assemble.c:598
    #7 0x555687b2bdbe in optimize_and_assemble_code_unit Python/compile.c:7707
    #8 0x555687b2bdbe in optimize_and_assemble Python/compile.c:7734
    #9 0x555687b3b1a8 in compiler_function_body Python/compile.c:2247
    #10 0x555687b3b1a8 in compiler_function Python/compile.c:2356
    #11 0x555687b3b787 in compiler_body Python/compile.c:1703
    #12 0x555687b3b917 in compiler_codegen Python/compile.c:1719
    #13 0x555687b3c5c3 in compiler_mod Python/compile.c:1747
    #14 0x555687b3c5c3 in _PyAST_Compile Python/compile.c:584
    #15 0x555687b1f9a0 in builtin_compile_impl Python/bltinmodule.c:820
    #16 0x555687b1f9a0 in builtin_compile Python/clinic/bltinmodule.c.h:383
    #17 0x5556879a5949 in _PyEval_EvalFrameDefault Python/bytecodes.c:2966
    #18 0x555687a061f5 in _PyObject_VectorcallTstate Include/internal/pycore_call.h:92
    #19 0x555687a061f5 in PyObject_CallOneArg Objects/call.c:401
    #20 0x555687a675f1 in _PyObject_GenericGetAttrWithDict Objects/object.c:1430
    #21 0x555687a6728d in PyObject_GetAttr Objects/object.c:1044
    #22 0x55568799fd39 in _PyEval_EvalFrameDefault Python/bytecodes.c:1794
    #23 0x555687a0833e in _PyObject_FastCallDictTstate Objects/call.c:144
    #24 0x555687a0833e in _PyObject_Call_Prepend Objects/call.c:508
    #25 0x555687a8ba6c in slot_tp_call Objects/typeobject.c:8770
    #26 0x555687a05733 in _PyObject_MakeTpCall Objects/call.c:240
    #27 0x5556879a3252 in _PyEval_EvalFrameDefault Python/bytecodes.c:2706
    #28 0x555687a22c14 in _PyEval_EvalFrame Include/internal/pycore_ceval.h:89
    #29 0x555687a22c14 in gen_send_ex2 Objects/genobject.c:230
    #30 0x555687a22c14 in gen_iternext Objects/genobject.c:604
    #31 0x555687a37fa5 in list_extend Objects/listobject.c:944
    #32 0x555687a14520 in method_vectorcall_O Objects/descrobject.c:482
    #33 0x555687a05fff in _PyObject_VectorcallTstate Include/internal/pycore_call.h:92
    #34 0x555687a05fff in PyObject_Vectorcall Objects/call.c:325
    #35 0x5556879a3252 in _PyEval_EvalFrameDefault Python/bytecodes.c:2706
    #36 0x555687a0833e in _PyObject_FastCallDictTstate Objects/call.c:144
    #37 0x555687a0833e in _PyObject_Call_Prepend Objects/call.c:508
    #38 0x555687a8ba6c in slot_tp_call Objects/typeobject.c:8770
    #39 0x555687a05733 in _PyObject_MakeTpCall Objects/call.c:240
    #40 0x5556879a3252 in _PyEval_EvalFrameDefault Python/bytecodes.c:2706
    #41 0x555687a0833e in _PyObject_FastCallDictTstate Objects/call.c:144
    #42 0x555687a0833e in _PyObject_Call_Prepend Objects/call.c:508
    #43 0x555687a8ba6c in slot_tp_call Objects/typeobject.c:8770
    #44 0x555687a05733 in _PyObject_MakeTpCall Objects/call.c:240
    #45 0x5556879a3252 in _PyEval_EvalFrameDefault Python/bytecodes.c:2706
    #46 0x555687b22926 in _PyEval_EvalFrame Include/internal/pycore_ceval.h:89
    #47 0x555687b22926 in _PyEval_Vector Python/ceval.c:1683
    #48 0x555687b22926 in PyEval_EvalCode Python/ceval.c:578
    #49 0x555687b1ebdf in builtin_exec_impl Python/bltinmodule.c:1096
    #50 0x555687b1ebdf in builtin_exec Python/clinic/bltinmodule.c.h:586
    #51 0x555687a613ae in cfunction_vectorcall_FASTCALL_KEYWORDS Objects/methodobject.c:438
    #52 0x555687a05fff in _PyObject_VectorcallTstate Include/internal/pycore_call.h:92
    #53 0x555687a05fff in PyObject_Vectorcall Objects/call.c:325
    #54 0x5556879a3252 in _PyEval_EvalFrameDefault Python/bytecodes.c:2706
    #55 0x555687ba84fa in pymain_run_module Modules/main.c:300
    #56 0x555687ba8cd9 in pymain_run_python Modules/main.c:623
    #57 0x555687ba96f9 in Py_RunMain Modules/main.c:709
    #58 0x555687ba96f9 in pymain_main Modules/main.c:739
    #59 0x555687ba96f9 in Py_BytesMain Modules/main.c:763
    #60 0x7f2791c46249 in __libc_start_call_main ../sysdeps/nptl/libc_start_call_main.h:58
    #61 0x7f2791c46304 in __libc_start_main_impl ../csu/libc-start.c:360
    #62 0x5556879aa030 in _start (/home/kirr/local/py3.12/bin/python3.12+0x10c030) (BuildId: 90994913e85aac5c35e9f04b53a6eeee5a04786d)

Direct leak of 21199 byte(s) in 9 object(s) allocated from:
    #0 0x7f27922f3bd7 in malloc ../../../../src/libsanitizer/asan/asan_malloc_linux.cpp:69
    #1 0x555687a6a9d2 in PyMem_RawMalloc Objects/obmalloc.c:662
    #2 0x555687a6a9d2 in _PyObject_Malloc Objects/obmalloc.c:1569
    #3 0x5556879faf23 in _PyBytes_FromSize Objects/bytesobject.c:102
    #4 0x5556879faf23 in _PyBytes_FromSize Objects/bytesobject.c:83
    #5 0x5556879faf23 in PyBytes_FromStringAndSize Objects/bytesobject.c:134
    #6 0x555687a0e210 in _PyCode_GetCode Objects/codeobject.c:1535
    #7 0x555687b70339 in w_complex_object Python/marshal.c:554
    #8 0x555687b70339 in w_object Python/marshal.c:375
    #9 0x555687b6fde4 in w_complex_object Python/marshal.c:479
    #10 0x555687b6fde4 in w_object Python/marshal.c:375
    #11 0x555687b703b5 in w_complex_object Python/marshal.c:566
    #12 0x555687b703b5 in w_object Python/marshal.c:375
    #13 0x555687b6f470 in PyMarshal_WriteObjectToString Python/marshal.c:1669
    #14 0x5556879a57c9 in _PyEval_EvalFrameDefault Python/bytecodes.c:2929
    #15 0x555687a061f5 in _PyObject_VectorcallTstate Include/internal/pycore_call.h:92
    #16 0x555687a061f5 in PyObject_CallOneArg Objects/call.c:401
    #17 0x555687a675f1 in _PyObject_GenericGetAttrWithDict Objects/object.c:1430
    #18 0x555687a6728d in PyObject_GetAttr Objects/object.c:1044
    #19 0x55568799fd39 in _PyEval_EvalFrameDefault Python/bytecodes.c:1794
    #20 0x555687a0833e in _PyObject_FastCallDictTstate Objects/call.c:144
    #21 0x555687a0833e in _PyObject_Call_Prepend Objects/call.c:508
    #22 0x555687a8ba6c in slot_tp_call Objects/typeobject.c:8770
    #23 0x555687a05733 in _PyObject_MakeTpCall Objects/call.c:240
    #24 0x5556879a3252 in _PyEval_EvalFrameDefault Python/bytecodes.c:2706
    #25 0x555687a22c14 in _PyEval_EvalFrame Include/internal/pycore_ceval.h:89
    #26 0x555687a22c14 in gen_send_ex2 Objects/genobject.c:230
    #27 0x555687a22c14 in gen_iternext Objects/genobject.c:604
    #28 0x555687a37fa5 in list_extend Objects/listobject.c:944
    #29 0x555687a14520 in method_vectorcall_O Objects/descrobject.c:482
    #30 0x555687a05fff in _PyObject_VectorcallTstate Include/internal/pycore_call.h:92
    #31 0x555687a05fff in PyObject_Vectorcall Objects/call.c:325
    #32 0x5556879a3252 in _PyEval_EvalFrameDefault Python/bytecodes.c:2706
    #33 0x555687a0833e in _PyObject_FastCallDictTstate Objects/call.c:144
    #34 0x555687a0833e in _PyObject_Call_Prepend Objects/call.c:508
    #35 0x555687a8ba6c in slot_tp_call Objects/typeobject.c:8770
    #36 0x555687a05733 in _PyObject_MakeTpCall Objects/call.c:240
    #37 0x5556879a3252 in _PyEval_EvalFrameDefault Python/bytecodes.c:2706
    #38 0x555687a0833e in _PyObject_FastCallDictTstate Objects/call.c:144
    #39 0x555687a0833e in _PyObject_Call_Prepend Objects/call.c:508
    #40 0x555687a8ba6c in slot_tp_call Objects/typeobject.c:8770
    #41 0x555687a05733 in _PyObject_MakeTpCall Objects/call.c:240
    #42 0x5556879a3252 in _PyEval_EvalFrameDefault Python/bytecodes.c:2706
    #43 0x555687b22926 in _PyEval_EvalFrame Include/internal/pycore_ceval.h:89
    #44 0x555687b22926 in _PyEval_Vector Python/ceval.c:1683
    #45 0x555687b22926 in PyEval_EvalCode Python/ceval.c:578
    #46 0x555687b1ebdf in builtin_exec_impl Python/bltinmodule.c:1096
    #47 0x555687b1ebdf in builtin_exec Python/clinic/bltinmodule.c.h:586
    #48 0x555687a613ae in cfunction_vectorcall_FASTCALL_KEYWORDS Objects/methodobject.c:438
    #49 0x555687a05fff in _PyObject_VectorcallTstate Include/internal/pycore_call.h:92
    #50 0x555687a05fff in PyObject_Vectorcall Objects/call.c:325
    #51 0x5556879a3252 in _PyEval_EvalFrameDefault Python/bytecodes.c:2706
    #52 0x555687ba84fa in pymain_run_module Modules/main.c:300
    #53 0x555687ba8cd9 in pymain_run_python Modules/main.c:623
    #54 0x555687ba96f9 in Py_RunMain Modules/main.c:709
    #55 0x555687ba96f9 in pymain_main Modules/main.c:739
    #56 0x555687ba96f9 in Py_BytesMain Modules/main.c:763
    #57 0x7f2791c46249 in __libc_start_call_main ../sysdeps/nptl/libc_start_call_main.h:58
    #58 0x7f2791c46304 in __libc_start_main_impl ../csu/libc-start.c:360
    #59 0x5556879aa030 in _start (/home/kirr/local/py3.12/bin/python3.12+0x10c030) (BuildId: 90994913e85aac5c35e9f04b53a6eeee5a04786d)

Direct leak of 8192 byte(s) in 1 object(s) allocated from:
    #0 0x7f27922f3bd7 in malloc ../../../../src/libsanitizer/asan/asan_malloc_linux.cpp:69
    #1 0x555687a6a9d2 in PyMem_RawMalloc Objects/obmalloc.c:662
    #2 0x555687a6a9d2 in _PyObject_Malloc Objects/obmalloc.c:1569
    #3 0x555687a70058 in set_table_resize Objects/setobject.c:274
    #4 0x555687a708c1 in set_add_key Objects/setobject.c:354
    #5 0x555687a708c1 in set_update_internal Objects/setobject.c:913
    #6 0x555687a708c1 in set_update_internal Objects/setobject.c:878
    #7 0x555687a70c4e in set_update Objects/setobject.c:933
    #8 0x555687a13046 in method_vectorcall_VARARGS Objects/descrobject.c:331
    #9 0x555687a05fff in _PyObject_VectorcallTstate Include/internal/pycore_call.h:92
    #10 0x555687a05fff in PyObject_Vectorcall Objects/call.c:325
    #11 0x5556879a3252 in _PyEval_EvalFrameDefault Python/bytecodes.c:2706
    #12 0x555687a23bc4 in _PyEval_EvalFrame Include/internal/pycore_ceval.h:89
    #13 0x555687a23bc4 in gen_send_ex2 Objects/genobject.c:230
    #14 0x555687a23bc4 in gen_send_ex Objects/genobject.c:274
    #15 0x555687a23bc4 in gen_send Objects/genobject.c:297
    #16 0x5556879a3a9a in _PyEval_EvalFrameDefault Python/bytecodes.c:3085
    #17 0x555687a0833e in _PyObject_FastCallDictTstate Objects/call.c:144
    #18 0x555687a0833e in _PyObject_Call_Prepend Objects/call.c:508
    #19 0x555687a8ba6c in slot_tp_call Objects/typeobject.c:8770
    #20 0x555687a05733 in _PyObject_MakeTpCall Objects/call.c:240
    #21 0x5556879a3252 in _PyEval_EvalFrameDefault Python/bytecodes.c:2706
    #22 0x555687a0833e in _PyObject_FastCallDictTstate Objects/call.c:144
    #23 0x555687a0833e in _PyObject_Call_Prepend Objects/call.c:508
    #24 0x555687a8ba6c in slot_tp_call Objects/typeobject.c:8770
    #25 0x555687a05733 in _PyObject_MakeTpCall Objects/call.c:240
    #26 0x5556879a3252 in _PyEval_EvalFrameDefault Python/bytecodes.c:2706
    #27 0x555687a0833e in _PyObject_FastCallDictTstate Objects/call.c:144
    #28 0x555687a0833e in _PyObject_Call_Prepend Objects/call.c:508
    #29 0x555687a8ba6c in slot_tp_call Objects/typeobject.c:8770
    #30 0x555687a05733 in _PyObject_MakeTpCall Objects/call.c:240
    #31 0x5556879a3252 in _PyEval_EvalFrameDefault Python/bytecodes.c:2706
    #32 0x555687b22926 in _PyEval_EvalFrame Include/internal/pycore_ceval.h:89
    #33 0x555687b22926 in _PyEval_Vector Python/ceval.c:1683
    #34 0x555687b22926 in PyEval_EvalCode Python/ceval.c:578
    #35 0x555687b1ebdf in builtin_exec_impl Python/bltinmodule.c:1096
    #36 0x555687b1ebdf in builtin_exec Python/clinic/bltinmodule.c.h:586
    #37 0x555687a613ae in cfunction_vectorcall_FASTCALL_KEYWORDS Objects/methodobject.c:438
    #38 0x555687a05fff in _PyObject_VectorcallTstate Include/internal/pycore_call.h:92
    #39 0x555687a05fff in PyObject_Vectorcall Objects/call.c:325
    #40 0x5556879a3252 in _PyEval_EvalFrameDefault Python/bytecodes.c:2706
    #41 0x555687ba84fa in pymain_run_module Modules/main.c:300
    #42 0x555687ba8cd9 in pymain_run_python Modules/main.c:623
    #43 0x555687ba96f9 in Py_RunMain Modules/main.c:709
    #44 0x555687ba96f9 in pymain_main Modules/main.c:739
    #45 0x555687ba96f9 in Py_BytesMain Modules/main.c:763
    #46 0x7f2791c46249 in __libc_start_call_main ../sysdeps/nptl/libc_start_call_main.h:58
    #47 0x7f2791c46304 in __libc_start_main_impl ../csu/libc-start.c:360
    #48 0x5556879aa030 in _start (/home/kirr/local/py3.12/bin/python3.12+0x10c030) (BuildId: 90994913e85aac5c35e9f04b53a6eeee5a04786d)

Direct leak of 4592 byte(s) in 5 object(s) allocated from:
    #0 0x7f27922f3bd7 in malloc ../../../../src/libsanitizer/asan/asan_malloc_linux.cpp:69
    #1 0x555687a6a9d2 in PyMem_RawMalloc Objects/obmalloc.c:662
    #2 0x555687a6a9d2 in _PyObject_Malloc Objects/obmalloc.c:1569
    #3 0x555687a4d4e8 in new_keys_object Objects/dictobject.c:641
    #4 0x555687a4d4e8 in dictresize Objects/dictobject.c:1449
    #5 0x555687a53277 in insertion_resize Objects/dictobject.c:1194
    #6 0x555687a53277 in insertdict Objects/dictobject.c:1261
    #7 0x5556879a7314 in _PyEval_EvalFrameDefault Python/bytecodes.c:1023
    #8 0x555687b22926 in _PyEval_EvalFrame Include/internal/pycore_ceval.h:89
    #9 0x555687b22926 in _PyEval_Vector Python/ceval.c:1683
    #10 0x555687b22926 in PyEval_EvalCode Python/ceval.c:578
    #11 0x555687b1ebdf in builtin_exec_impl Python/bltinmodule.c:1096
    #12 0x555687b1ebdf in builtin_exec Python/clinic/bltinmodule.c.h:586
    #13 0x5556879a5949 in _PyEval_EvalFrameDefault Python/bytecodes.c:2966
    #14 0x555687a0833e in _PyObject_FastCallDictTstate Objects/call.c:144
    #15 0x555687a0833e in _PyObject_Call_Prepend Objects/call.c:508
    #16 0x555687a8ba6c in slot_tp_call Objects/typeobject.c:8770
    #17 0x555687a05733 in _PyObject_MakeTpCall Objects/call.c:240
    #18 0x5556879a3252 in _PyEval_EvalFrameDefault Python/bytecodes.c:2706
    #19 0x555687a22c14 in _PyEval_EvalFrame Include/internal/pycore_ceval.h:89
    #20 0x555687a22c14 in gen_send_ex2 Objects/genobject.c:230
    #21 0x555687a22c14 in gen_iternext Objects/genobject.c:604
    #22 0x555687a37fd0 in list_extend Objects/listobject.c:944
    #23 0x5556879a3a9a in _PyEval_EvalFrameDefault Python/bytecodes.c:3085
    #24 0x555687a0833e in _PyObject_FastCallDictTstate Objects/call.c:144
    #25 0x555687a0833e in _PyObject_Call_Prepend Objects/call.c:508
    #26 0x555687a8ba6c in slot_tp_call Objects/typeobject.c:8770
    #27 0x555687a05733 in _PyObject_MakeTpCall Objects/call.c:240
    #28 0x5556879a3252 in _PyEval_EvalFrameDefault Python/bytecodes.c:2706
    #29 0x555687a0833e in _PyObject_FastCallDictTstate Objects/call.c:144
    #30 0x555687a0833e in _PyObject_Call_Prepend Objects/call.c:508
    #31 0x555687a8ba6c in slot_tp_call Objects/typeobject.c:8770
    #32 0x555687a05733 in _PyObject_MakeTpCall Objects/call.c:240
    #33 0x5556879a3252 in _PyEval_EvalFrameDefault Python/bytecodes.c:2706
    #34 0x555687b22926 in _PyEval_EvalFrame Include/internal/pycore_ceval.h:89
    #35 0x555687b22926 in _PyEval_Vector Python/ceval.c:1683
    #36 0x555687b22926 in PyEval_EvalCode Python/ceval.c:578
    #37 0x555687b1ebdf in builtin_exec_impl Python/bltinmodule.c:1096
    #38 0x555687b1ebdf in builtin_exec Python/clinic/bltinmodule.c.h:586
    #39 0x555687a613ae in cfunction_vectorcall_FASTCALL_KEYWORDS Objects/methodobject.c:438
    #40 0x555687a05fff in _PyObject_VectorcallTstate Include/internal/pycore_call.h:92
    #41 0x555687a05fff in PyObject_Vectorcall Objects/call.c:325
    #42 0x5556879a3252 in _PyEval_EvalFrameDefault Python/bytecodes.c:2706
    #43 0x555687ba84fa in pymain_run_module Modules/main.c:300
    #44 0x555687ba8cd9 in pymain_run_python Modules/main.c:623
    #45 0x555687ba96f9 in Py_RunMain Modules/main.c:709
    #46 0x555687ba96f9 in pymain_main Modules/main.c:739
    #47 0x555687ba96f9 in Py_BytesMain Modules/main.c:763
    #48 0x7f2791c46249 in __libc_start_call_main ../sysdeps/nptl/libc_start_call_main.h:58
    #49 0x7f2791c46304 in __libc_start_main_impl ../csu/libc-start.c:360
    #50 0x5556879aa030 in _start (/home/kirr/local/py3.12/bin/python3.12+0x10c030) (BuildId: 90994913e85aac5c35e9f04b53a6eeee5a04786d)

Direct leak of 4032 byte(s) in 2 object(s) allocated from:
    #0 0x7f27922f3bd7 in malloc ../../../../src/libsanitizer/asan/asan_malloc_linux.cpp:69
    #1 0x555687a6a9d2 in PyMem_RawMalloc Objects/obmalloc.c:662
    #2 0x555687a6a9d2 in _PyObject_Malloc Objects/obmalloc.c:1569
    #3 0x555687a4d4e8 in new_keys_object Objects/dictobject.c:641
    #4 0x555687a4d4e8 in dictresize Objects/dictobject.c:1449
    #5 0x555687a53277 in insertion_resize Objects/dictobject.c:1194
    #6 0x555687a53277 in insertdict Objects/dictobject.c:1261
    #7 0x5556879a4de2 in _PyEval_EvalFrameDefault Python/bytecodes.c:579
    #8 0x555687b22926 in _PyEval_EvalFrame Include/internal/pycore_ceval.h:89
    #9 0x555687b22926 in _PyEval_Vector Python/ceval.c:1683
    #10 0x555687b22926 in PyEval_EvalCode Python/ceval.c:578
    #11 0x555687b1ebdf in builtin_exec_impl Python/bltinmodule.c:1096
    #12 0x555687b1ebdf in builtin_exec Python/clinic/bltinmodule.c.h:586
    #13 0x555687a613ae in cfunction_vectorcall_FASTCALL_KEYWORDS Objects/methodobject.c:438
    #14 0x555687a05fff in _PyObject_VectorcallTstate Include/internal/pycore_call.h:92
    #15 0x555687a05fff in PyObject_Vectorcall Objects/call.c:325
    #16 0x5556879a3252 in _PyEval_EvalFrameDefault Python/bytecodes.c:2706
    #17 0x555687ba84fa in pymain_run_module Modules/main.c:300
    #18 0x555687ba8cd9 in pymain_run_python Modules/main.c:623
    #19 0x555687ba96f9 in Py_RunMain Modules/main.c:709
    #20 0x555687ba96f9 in pymain_main Modules/main.c:739
    #21 0x555687ba96f9 in Py_BytesMain Modules/main.c:763
    #22 0x7f2791c46249 in __libc_start_call_main ../sysdeps/nptl/libc_start_call_main.h:58
    #23 0x7f2791c46304 in __libc_start_main_impl ../csu/libc-start.c:360
    #24 0x5556879aa030 in _start (/home/kirr/local/py3.12/bin/python3.12+0x10c030) (BuildId: 90994913e85aac5c35e9f04b53a6eeee5a04786d)

Direct leak of 3264 byte(s) in 1 object(s) allocated from:
    #0 0x7f27922f3bd7 in malloc ../../../../src/libsanitizer/asan/asan_malloc_linux.cpp:69
    #1 0x555687a6a9d2 in PyMem_RawMalloc Objects/obmalloc.c:662
    #2 0x555687a6a9d2 in _PyObject_Malloc Objects/obmalloc.c:1569
    #3 0x555687a4d4e8 in new_keys_object Objects/dictobject.c:641
    #4 0x555687a4d4e8 in dictresize Objects/dictobject.c:1449
    #5 0x555687a53277 in insertion_resize Objects/dictobject.c:1194
    #6 0x555687a53277 in insertdict Objects/dictobject.c:1261
    #7 0x5556879a4de2 in _PyEval_EvalFrameDefault Python/bytecodes.c:579
    #8 0x555687a09b17 in _PyObject_VectorcallTstate Include/internal/pycore_call.h:92
    #9 0x555687a09b17 in method_vectorcall Objects/classobject.c:61
    #10 0x555687a07f9b in PyObject_Call (/home/kirr/local/py3.12/bin/python3.12+0x169f9b) (BuildId: 90994913e85aac5c35e9f04b53a6eeee5a04786d)
    #11 0x55568799e2ed in _PyEval_EvalFrameDefault Python/bytecodes.c:3254
    #12 0x555687a09a90 in _PyObject_VectorcallTstate Include/internal/pycore_call.h:92
    #13 0x555687a09a90 in method_vectorcall Objects/classobject.c:91
    #14 0x55568799e2ed in _PyEval_EvalFrameDefault Python/bytecodes.c:3254
    #15 0x555687a0833e in _PyObject_FastCallDictTstate Objects/call.c:144
    #16 0x555687a0833e in _PyObject_Call_Prepend Objects/call.c:508
    #17 0x555687a8ba6c in slot_tp_call Objects/typeobject.c:8770
    #18 0x555687a05733 in _PyObject_MakeTpCall Objects/call.c:240
    #19 0x5556879a3252 in _PyEval_EvalFrameDefault Python/bytecodes.c:2706
    #20 0x555687b22926 in _PyEval_EvalFrame Include/internal/pycore_ceval.h:89
    #21 0x555687b22926 in _PyEval_Vector Python/ceval.c:1683
    #22 0x555687b22926 in PyEval_EvalCode Python/ceval.c:578
    #23 0x555687b1ebdf in builtin_exec_impl Python/bltinmodule.c:1096
    #24 0x555687b1ebdf in builtin_exec Python/clinic/bltinmodule.c.h:586
    #25 0x555687a613ae in cfunction_vectorcall_FASTCALL_KEYWORDS Objects/methodobject.c:438
    #26 0x555687a05fff in _PyObject_VectorcallTstate Include/internal/pycore_call.h:92
    #27 0x555687a05fff in PyObject_Vectorcall Objects/call.c:325
    #28 0x5556879a3252 in _PyEval_EvalFrameDefault Python/bytecodes.c:2706
    #29 0x555687ba84fa in pymain_run_module Modules/main.c:300
    #30 0x555687ba8cd9 in pymain_run_python Modules/main.c:623
    #31 0x555687ba96f9 in Py_RunMain Modules/main.c:709
    #32 0x555687ba96f9 in pymain_main Modules/main.c:739
    #33 0x555687ba96f9 in Py_BytesMain Modules/main.c:763
    #34 0x7f2791c46249 in __libc_start_call_main ../sysdeps/nptl/libc_start_call_main.h:58
    #35 0x7f2791c46304 in __libc_start_main_impl ../csu/libc-start.c:360
    #36 0x5556879aa030 in _start (/home/kirr/local/py3.12/bin/python3.12+0x10c030) (BuildId: 90994913e85aac5c35e9f04b53a6eeee5a04786d)

Direct leak of 3168 byte(s) in 2 object(s) allocated from:
    #0 0x7f27922f2ad8 in realloc ../../../../src/libsanitizer/asan/asan_malloc_linux.cpp:85
    #1 0x555687a37ebc in list_resize Objects/listobject.c:82
    #2 0x555687a37ebc in list_extend Objects/listobject.c:892
    #3 0x5556879a3a9a in _PyEval_EvalFrameDefault Python/bytecodes.c:3085
    #4 0x555687a09a90 in _PyObject_VectorcallTstate Include/internal/pycore_call.h:92
    #5 0x555687a09a90 in method_vectorcall Objects/classobject.c:91
    #6 0x55568799e2ed in _PyEval_EvalFrameDefault Python/bytecodes.c:3254
    #7 0x555687a0833e in _PyObject_FastCallDictTstate Objects/call.c:144
    #8 0x555687a0833e in _PyObject_Call_Prepend Objects/call.c:508
    #9 0x555687a8ba6c in slot_tp_call Objects/typeobject.c:8770
    #10 0x555687a05733 in _PyObject_MakeTpCall Objects/call.c:240
    #11 0x5556879a3252 in _PyEval_EvalFrameDefault Python/bytecodes.c:2706
    #12 0x555687a0833e in _PyObject_FastCallDictTstate Objects/call.c:144
    #13 0x555687a0833e in _PyObject_Call_Prepend Objects/call.c:508
    #14 0x555687a8ba6c in slot_tp_call Objects/typeobject.c:8770
    #15 0x555687a05733 in _PyObject_MakeTpCall Objects/call.c:240
    #16 0x5556879a3252 in _PyEval_EvalFrameDefault Python/bytecodes.c:2706
    #17 0x555687a0833e in _PyObject_FastCallDictTstate Objects/call.c:144
    #18 0x555687a0833e in _PyObject_Call_Prepend Objects/call.c:508
    #19 0x555687a8ba6c in slot_tp_call Objects/typeobject.c:8770
    #20 0x555687a05733 in _PyObject_MakeTpCall Objects/call.c:240
    #21 0x5556879a3252 in _PyEval_EvalFrameDefault Python/bytecodes.c:2706
    #22 0x555687a0833e in _PyObject_FastCallDictTstate Objects/call.c:144
    #23 0x555687a0833e in _PyObject_Call_Prepend Objects/call.c:508
    #24 0x555687a8ba6c in slot_tp_call Objects/typeobject.c:8770
    #25 0x555687a05733 in _PyObject_MakeTpCall Objects/call.c:240
    #26 0x5556879a3252 in _PyEval_EvalFrameDefault Python/bytecodes.c:2706
    #27 0x555687b22926 in _PyEval_EvalFrame Include/internal/pycore_ceval.h:89
    #28 0x555687b22926 in _PyEval_Vector Python/ceval.c:1683
    #29 0x555687b22926 in PyEval_EvalCode Python/ceval.c:578
    #30 0x555687b1ebdf in builtin_exec_impl Python/bltinmodule.c:1096
    #31 0x555687b1ebdf in builtin_exec Python/clinic/bltinmodule.c.h:586
    #32 0x555687a613ae in cfunction_vectorcall_FASTCALL_KEYWORDS Objects/methodobject.c:438
    #33 0x555687a05fff in _PyObject_VectorcallTstate Include/internal/pycore_call.h:92
    #34 0x555687a05fff in PyObject_Vectorcall Objects/call.c:325
    #35 0x5556879a3252 in _PyEval_EvalFrameDefault Python/bytecodes.c:2706
    #36 0x555687ba84fa in pymain_run_module Modules/main.c:300
    #37 0x555687ba8cd9 in pymain_run_python Modules/main.c:623
    #38 0x555687ba96f9 in Py_RunMain Modules/main.c:709
    #39 0x555687ba96f9 in pymain_main Modules/main.c:739
    #40 0x555687ba96f9 in Py_BytesMain Modules/main.c:763
    #41 0x7f2791c46249 in __libc_start_call_main ../sysdeps/nptl/libc_start_call_main.h:58
    #42 0x7f2791c46304 in __libc_start_main_impl ../csu/libc-start.c:360
    #43 0x5556879aa030 in _start (/home/kirr/local/py3.12/bin/python3.12+0x10c030) (BuildId: 90994913e85aac5c35e9f04b53a6eeee5a04786d)

Direct leak of 3024 byte(s) in 2 object(s) allocated from:
    #0 0x7f27922f3bd7 in malloc ../../../../src/libsanitizer/asan/asan_malloc_linux.cpp:69
    #1 0x555687a6a9d2 in PyMem_RawMalloc Objects/obmalloc.c:662
    #2 0x555687a6a9d2 in _PyObject_Malloc Objects/obmalloc.c:1569
    #3 0x555687a649e3 in _PyObject_NewVar Objects/object.c:332
    #4 0x555687a0c16b in _PyCode_New Objects/codeobject.c:582
    #5 0x555687b12f84 in makecode Python/assemble.c:574
    #6 0x555687b12f84 in _PyAssemble_MakeCodeObject Python/assemble.c:598
    #7 0x555687b2bdbe in optimize_and_assemble_code_unit Python/compile.c:7707
    #8 0x555687b2bdbe in optimize_and_assemble Python/compile.c:7734
    #9 0x555687b3b1a8 in compiler_function_body Python/compile.c:2247
    #10 0x555687b3b1a8 in compiler_function Python/compile.c:2356
    #11 0x555687b3b787 in compiler_body Python/compile.c:1703
    #12 0x555687b3b917 in compiler_codegen Python/compile.c:1719
    #13 0x555687b3c5c3 in compiler_mod Python/compile.c:1747
    #14 0x555687b3c5c3 in _PyAST_Compile Python/compile.c:584
    #15 0x555687b1f9a0 in builtin_compile_impl Python/bltinmodule.c:820
    #16 0x555687b1f9a0 in builtin_compile Python/clinic/bltinmodule.c.h:383
    #17 0x5556879a5949 in _PyEval_EvalFrameDefault Python/bytecodes.c:2966
    #18 0x555687a0833e in _PyObject_FastCallDictTstate Objects/call.c:144
    #19 0x555687a0833e in _PyObject_Call_Prepend Objects/call.c:508
    #20 0x555687a8ba6c in slot_tp_call Objects/typeobject.c:8770
    #21 0x555687a05733 in _PyObject_MakeTpCall Objects/call.c:240
    #22 0x5556879a3252 in _PyEval_EvalFrameDefault Python/bytecodes.c:2706
    #23 0x555687a22c14 in _PyEval_EvalFrame Include/internal/pycore_ceval.h:89
    #24 0x555687a22c14 in gen_send_ex2 Objects/genobject.c:230
    #25 0x555687a22c14 in gen_iternext Objects/genobject.c:604
    #26 0x555687a37fa5 in list_extend Objects/listobject.c:944
    #27 0x5556879a3a9a in _PyEval_EvalFrameDefault Python/bytecodes.c:3085
    #28 0x555687a0833e in _PyObject_FastCallDictTstate Objects/call.c:144
    #29 0x555687a0833e in _PyObject_Call_Prepend Objects/call.c:508
    #30 0x555687a8ba6c in slot_tp_call Objects/typeobject.c:8770
    #31 0x555687a05733 in _PyObject_MakeTpCall Objects/call.c:240
    #32 0x5556879a3252 in _PyEval_EvalFrameDefault Python/bytecodes.c:2706
    #33 0x555687a0833e in _PyObject_FastCallDictTstate Objects/call.c:144
    #34 0x555687a0833e in _PyObject_Call_Prepend Objects/call.c:508
    #35 0x555687a8ba6c in slot_tp_call Objects/typeobject.c:8770
    #36 0x555687a05733 in _PyObject_MakeTpCall Objects/call.c:240
    #37 0x5556879a3252 in _PyEval_EvalFrameDefault Python/bytecodes.c:2706
    #38 0x555687b22926 in _PyEval_EvalFrame Include/internal/pycore_ceval.h:89
    #39 0x555687b22926 in _PyEval_Vector Python/ceval.c:1683
    #40 0x555687b22926 in PyEval_EvalCode Python/ceval.c:578
    #41 0x555687b1ebdf in builtin_exec_impl Python/bltinmodule.c:1096
    #42 0x555687b1ebdf in builtin_exec Python/clinic/bltinmodule.c.h:586
    #43 0x555687a613ae in cfunction_vectorcall_FASTCALL_KEYWORDS Objects/methodobject.c:438
    #44 0x555687a05fff in _PyObject_VectorcallTstate Include/internal/pycore_call.h:92
    #45 0x555687a05fff in PyObject_Vectorcall Objects/call.c:325
    #46 0x5556879a3252 in _PyEval_EvalFrameDefault Python/bytecodes.c:2706
    #47 0x555687ba84fa in pymain_run_module Modules/main.c:300
    #48 0x555687ba8cd9 in pymain_run_python Modules/main.c:623
    #49 0x555687ba96f9 in Py_RunMain Modules/main.c:709
    #50 0x555687ba96f9 in pymain_main Modules/main.c:739
    #51 0x555687ba96f9 in Py_BytesMain Modules/main.c:763
    #52 0x7f2791c46249 in __libc_start_call_main ../sysdeps/nptl/libc_start_call_main.h:58
    #53 0x7f2791c46304 in __libc_start_main_impl ../csu/libc-start.c:360
    #54 0x5556879aa030 in _start (/home/kirr/local/py3.12/bin/python3.12+0x10c030) (BuildId: 90994913e85aac5c35e9f04b53a6eeee5a04786d)

Direct leak of 2702 byte(s) in 2 object(s) allocated from:
    #0 0x7f27922f3bd7 in malloc ../../../../src/libsanitizer/asan/asan_malloc_linux.cpp:69
    #1 0x555687a6a9d2 in PyMem_RawMalloc Objects/obmalloc.c:662
    #2 0x555687a6a9d2 in _PyObject_Malloc Objects/obmalloc.c:1569
    #3 0x5556879faf23 in _PyBytes_FromSize Objects/bytesobject.c:102
    #4 0x5556879faf23 in _PyBytes_FromSize Objects/bytesobject.c:83
    #5 0x5556879faf23 in PyBytes_FromStringAndSize Objects/bytesobject.c:134
    #6 0x555687a0e210 in _PyCode_GetCode Objects/codeobject.c:1535
    #7 0x555687b70339 in w_complex_object Python/marshal.c:554
    #8 0x555687b70339 in w_object Python/marshal.c:375
    #9 0x555687b6fde4 in w_complex_object Python/marshal.c:479
    #10 0x555687b6fde4 in w_object Python/marshal.c:375
    #11 0x555687b703b5 in w_complex_object Python/marshal.c:566
    #12 0x555687b703b5 in w_object Python/marshal.c:375
    #13 0x555687b6f470 in PyMarshal_WriteObjectToString Python/marshal.c:1669
    #14 0x5556879a57c9 in _PyEval_EvalFrameDefault Python/bytecodes.c:2929
    #15 0x555687a0833e in _PyObject_FastCallDictTstate Objects/call.c:144
    #16 0x555687a0833e in _PyObject_Call_Prepend Objects/call.c:508
    #17 0x555687a8ba6c in slot_tp_call Objects/typeobject.c:8770
    #18 0x555687a05733 in _PyObject_MakeTpCall Objects/call.c:240
    #19 0x5556879a3252 in _PyEval_EvalFrameDefault Python/bytecodes.c:2706
    #20 0x555687a22c14 in _PyEval_EvalFrame Include/internal/pycore_ceval.h:89
    #21 0x555687a22c14 in gen_send_ex2 Objects/genobject.c:230
    #22 0x555687a22c14 in gen_iternext Objects/genobject.c:604
    #23 0x555687a37fa5 in list_extend Objects/listobject.c:944
    #24 0x5556879a3a9a in _PyEval_EvalFrameDefault Python/bytecodes.c:3085
    #25 0x555687a0833e in _PyObject_FastCallDictTstate Objects/call.c:144
    #26 0x555687a0833e in _PyObject_Call_Prepend Objects/call.c:508
    #27 0x555687a8ba6c in slot_tp_call Objects/typeobject.c:8770
    #28 0x555687a05733 in _PyObject_MakeTpCall Objects/call.c:240
    #29 0x5556879a3252 in _PyEval_EvalFrameDefault Python/bytecodes.c:2706
    #30 0x555687a0833e in _PyObject_FastCallDictTstate Objects/call.c:144
    #31 0x555687a0833e in _PyObject_Call_Prepend Objects/call.c:508
    #32 0x555687a8ba6c in slot_tp_call Objects/typeobject.c:8770
    #33 0x555687a05733 in _PyObject_MakeTpCall Objects/call.c:240
    #34 0x5556879a3252 in _PyEval_EvalFrameDefault Python/bytecodes.c:2706
    #35 0x555687b22926 in _PyEval_EvalFrame Include/internal/pycore_ceval.h:89
    #36 0x555687b22926 in _PyEval_Vector Python/ceval.c:1683
    #37 0x555687b22926 in PyEval_EvalCode Python/ceval.c:578
    #38 0x555687b1ebdf in builtin_exec_impl Python/bltinmodule.c:1096
    #39 0x555687b1ebdf in builtin_exec Python/clinic/bltinmodule.c.h:586
    #40 0x555687a613ae in cfunction_vectorcall_FASTCALL_KEYWORDS Objects/methodobject.c:438
    #41 0x555687a05fff in _PyObject_VectorcallTstate Include/internal/pycore_call.h:92
    #42 0x555687a05fff in PyObject_Vectorcall Objects/call.c:325
    #43 0x5556879a3252 in _PyEval_EvalFrameDefault Python/bytecodes.c:2706
    #44 0x555687ba84fa in pymain_run_module Modules/main.c:300
    #45 0x555687ba8cd9 in pymain_run_python Modules/main.c:623
    #46 0x555687ba96f9 in Py_RunMain Modules/main.c:709
    #47 0x555687ba96f9 in pymain_main Modules/main.c:739
    #48 0x555687ba96f9 in Py_BytesMain Modules/main.c:763
    #49 0x7f2791c46249 in __libc_start_call_main ../sysdeps/nptl/libc_start_call_main.h:58
    #50 0x7f2791c46304 in __libc_start_main_impl ../csu/libc-start.c:360
    #51 0x5556879aa030 in _start (/home/kirr/local/py3.12/bin/python3.12+0x10c030) (BuildId: 90994913e85aac5c35e9f04b53a6eeee5a04786d)

Direct leak of 2200 byte(s) in 1 object(s) allocated from:
    #0 0x7f27922f3bd7 in malloc ../../../../src/libsanitizer/asan/asan_malloc_linux.cpp:69
    #1 0x555687a6a9d2 in PyMem_RawMalloc Objects/obmalloc.c:662
    #2 0x555687a6a9d2 in _PyObject_Malloc Objects/obmalloc.c:1569
    #3 0x555687a4d4e8 in new_keys_object Objects/dictobject.c:641
    #4 0x555687a4d4e8 in dictresize Objects/dictobject.c:1449
    #5 0x555687a53277 in insertion_resize Objects/dictobject.c:1194
    #6 0x555687a53277 in insertdict Objects/dictobject.c:1261
    #7 0x555687c0ff1e in bounded_lru_cache_wrapper Modules/_functoolsmodule.c:1067
    #8 0x555687a05733 in _PyObject_MakeTpCall Objects/call.c:240
    #9 0x5556879a3252 in _PyEval_EvalFrameDefault Python/bytecodes.c:2706
    #10 0x555687a061f5 in _PyObject_VectorcallTstate Include/internal/pycore_call.h:92
    #11 0x555687a061f5 in PyObject_CallOneArg Objects/call.c:401
    #12 0x555687a675f1 in _PyObject_GenericGetAttrWithDict Objects/object.c:1430
    #13 0x555687a6728d in PyObject_GetAttr Objects/object.c:1044
    #14 0x55568799fd39 in _PyEval_EvalFrameDefault Python/bytecodes.c:1794
    #15 0x555687a22c14 in _PyEval_EvalFrame Include/internal/pycore_ceval.h:89
    #16 0x555687a22c14 in gen_send_ex2 Objects/genobject.c:230
    #17 0x555687a22c14 in gen_iternext Objects/genobject.c:604
    #18 0x555687a37fa5 in list_extend Objects/listobject.c:944
    #19 0x5556879a3a9a in _PyEval_EvalFrameDefault Python/bytecodes.c:3085
    #20 0x555687a0833e in _PyObject_FastCallDictTstate Objects/call.c:144
    #21 0x555687a0833e in _PyObject_Call_Prepend Objects/call.c:508
    #22 0x555687a8ba6c in slot_tp_call Objects/typeobject.c:8770
    #23 0x555687a05733 in _PyObject_MakeTpCall Objects/call.c:240
    #24 0x5556879a3252 in _PyEval_EvalFrameDefault Python/bytecodes.c:2706
    #25 0x555687a0833e in _PyObject_FastCallDictTstate Objects/call.c:144
    #26 0x555687a0833e in _PyObject_Call_Prepend Objects/call.c:508
    #27 0x555687a8ba6c in slot_tp_call Objects/typeobject.c:8770
    #28 0x555687a05733 in _PyObject_MakeTpCall Objects/call.c:240
    #29 0x5556879a3252 in _PyEval_EvalFrameDefault Python/bytecodes.c:2706
    #30 0x555687b22926 in _PyEval_EvalFrame Include/internal/pycore_ceval.h:89
    #31 0x555687b22926 in _PyEval_Vector Python/ceval.c:1683
    #32 0x555687b22926 in PyEval_EvalCode Python/ceval.c:578
    #33 0x555687b1ebdf in builtin_exec_impl Python/bltinmodule.c:1096
    #34 0x555687b1ebdf in builtin_exec Python/clinic/bltinmodule.c.h:586
    #35 0x555687a613ae in cfunction_vectorcall_FASTCALL_KEYWORDS Objects/methodobject.c:438
    #36 0x555687a05fff in _PyObject_VectorcallTstate Include/internal/pycore_call.h:92
    #37 0x555687a05fff in PyObject_Vectorcall Objects/call.c:325
    #38 0x5556879a3252 in _PyEval_EvalFrameDefault Python/bytecodes.c:2706
    #39 0x555687ba84fa in pymain_run_module Modules/main.c:300
    #40 0x555687ba8cd9 in pymain_run_python Modules/main.c:623
    #41 0x555687ba96f9 in Py_RunMain Modules/main.c:709
    #42 0x555687ba96f9 in pymain_main Modules/main.c:739
    #43 0x555687ba96f9 in Py_BytesMain Modules/main.c:763
    #44 0x7f2791c46249 in __libc_start_call_main ../sysdeps/nptl/libc_start_call_main.h:58
    #45 0x7f2791c46304 in __libc_start_main_impl ../csu/libc-start.c:360
    #46 0x5556879aa030 in _start (/home/kirr/local/py3.12/bin/python3.12+0x10c030) (BuildId: 90994913e85aac5c35e9f04b53a6eeee5a04786d)

Direct leak of 2048 byte(s) in 1 object(s) allocated from:
    #0 0x7f27922f3bd7 in malloc ../../../../src/libsanitizer/asan/asan_malloc_linux.cpp:69
    #1 0x555687a6a9d2 in PyMem_RawMalloc Objects/obmalloc.c:662
    #2 0x555687a6a9d2 in _PyObject_Malloc Objects/obmalloc.c:1569
    #3 0x555687a70058 in set_table_resize Objects/setobject.c:274
    #4 0x555687a70714 in set_add_key Objects/setobject.c:354
    #5 0x555687a70714 in set_add Objects/setobject.c:1840
    #6 0x5556879a3a9a in _PyEval_EvalFrameDefault Python/bytecodes.c:3085
    #7 0x555687a09a90 in _PyObject_VectorcallTstate Include/internal/pycore_call.h:92
    #8 0x555687a09a90 in method_vectorcall Objects/classobject.c:91
    #9 0x55568799e2ed in _PyEval_EvalFrameDefault Python/bytecodes.c:3254
    #10 0x555687a08293 in _PyObject_FastCallDictTstate Objects/call.c:133
    #11 0x555687a08293 in _PyObject_Call_Prepend Objects/call.c:508
    #12 0x555687a911ac in slot_tp_init Objects/typeobject.c:9014
    #13 0x555687a7e8d6 in type_call Objects/typeobject.c:1673
    #14 0x555687a05733 in _PyObject_MakeTpCall Objects/call.c:240
    #15 0x5556879a3252 in _PyEval_EvalFrameDefault Python/bytecodes.c:2706
    #16 0x555687a0833e in _PyObject_FastCallDictTstate Objects/call.c:144
    #17 0x555687a0833e in _PyObject_Call_Prepend Objects/call.c:508
    #18 0x555687a8ba6c in slot_tp_call Objects/typeobject.c:8770
    #19 0x555687a05733 in _PyObject_MakeTpCall Objects/call.c:240
    #20 0x5556879a3252 in _PyEval_EvalFrameDefault Python/bytecodes.c:2706
    #21 0x555687a0833e in _PyObject_FastCallDictTstate Objects/call.c:144
    #22 0x555687a0833e in _PyObject_Call_Prepend Objects/call.c:508
    #23 0x555687a8ba6c in slot_tp_call Objects/typeobject.c:8770
    #24 0x555687a05733 in _PyObject_MakeTpCall Objects/call.c:240
    #25 0x5556879a3252 in _PyEval_EvalFrameDefault Python/bytecodes.c:2706
    #26 0x555687b22926 in _PyEval_EvalFrame Include/internal/pycore_ceval.h:89
    #27 0x555687b22926 in _PyEval_Vector Python/ceval.c:1683
    #28 0x555687b22926 in PyEval_EvalCode Python/ceval.c:578
    #29 0x555687b1ebdf in builtin_exec_impl Python/bltinmodule.c:1096
    #30 0x555687b1ebdf in builtin_exec Python/clinic/bltinmodule.c.h:586
    #31 0x555687a613ae in cfunction_vectorcall_FASTCALL_KEYWORDS Objects/methodobject.c:438
    #32 0x555687a05fff in _PyObject_VectorcallTstate Include/internal/pycore_call.h:92
    #33 0x555687a05fff in PyObject_Vectorcall Objects/call.c:325
    #34 0x5556879a3252 in _PyEval_EvalFrameDefault Python/bytecodes.c:2706
    #35 0x555687ba84fa in pymain_run_module Modules/main.c:300
    #36 0x555687ba8cd9 in pymain_run_python Modules/main.c:623
    #37 0x555687ba96f9 in Py_RunMain Modules/main.c:709
    #38 0x555687ba96f9 in pymain_main Modules/main.c:739
    #39 0x555687ba96f9 in Py_BytesMain Modules/main.c:763
    #40 0x7f2791c46249 in __libc_start_call_main ../sysdeps/nptl/libc_start_call_main.h:58
    #41 0x7f2791c46304 in __libc_start_main_impl ../csu/libc-start.c:360
    #42 0x5556879aa030 in _start (/home/kirr/local/py3.12/bin/python3.12+0x10c030) (BuildId: 90994913e85aac5c35e9f04b53a6eeee5a04786d)

Direct leak of 1520 byte(s) in 1 object(s) allocated from:
    #0 0x7f27922f3bd7 in malloc ../../../../src/libsanitizer/asan/asan_malloc_linux.cpp:69
    #1 0x555687a6a9d2 in PyMem_RawMalloc Objects/obmalloc.c:662
    #2 0x555687a6a9d2 in _PyObject_Malloc Objects/obmalloc.c:1569
    #3 0x555687a4d4e8 in new_keys_object Objects/dictobject.c:641
    #4 0x555687a4d4e8 in dictresize Objects/dictobject.c:1449
    #5 0x555687a53277 in insertion_resize Objects/dictobject.c:1194
    #6 0x555687a53277 in insertdict Objects/dictobject.c:1261
    #7 0x555687a65e81 in _PyObject_GenericSetAttrWithDict Objects/object.c:1562
    #8 0x555687a65e81 in PyObject_GenericSetAttr Objects/object.c:1619
    #9 0x555687a67094 in PyObject_SetAttr Objects/object.c:1175
    #10 0x555687b1bbe6 in builtin_setattr_impl Python/bltinmodule.c:1547
    #11 0x555687b1bbe6 in builtin_setattr Python/clinic/bltinmodule.c.h:765
    #12 0x5556879a57c9 in _PyEval_EvalFrameDefault Python/bytecodes.c:2929
    #13 0x555687a08293 in _PyObject_FastCallDictTstate Objects/call.c:133
    #14 0x555687a08293 in _PyObject_Call_Prepend Objects/call.c:508
    #15 0x555687a911ac in slot_tp_init Objects/typeobject.c:9014
    #16 0x555687a7e8d6 in type_call Objects/typeobject.c:1673
    #17 0x555687a05733 in _PyObject_MakeTpCall Objects/call.c:240
    #18 0x5556879a3252 in _PyEval_EvalFrameDefault Python/bytecodes.c:2706
    #19 0x555687b22926 in _PyEval_EvalFrame Include/internal/pycore_ceval.h:89
    #20 0x555687b22926 in _PyEval_Vector Python/ceval.c:1683
    #21 0x555687b22926 in PyEval_EvalCode Python/ceval.c:578
    #22 0x555687b1ebdf in builtin_exec_impl Python/bltinmodule.c:1096
    #23 0x555687b1ebdf in builtin_exec Python/clinic/bltinmodule.c.h:586
    #24 0x555687a613ae in cfunction_vectorcall_FASTCALL_KEYWORDS Objects/methodobject.c:438
    #25 0x555687a05fff in _PyObject_VectorcallTstate Include/internal/pycore_call.h:92
    #26 0x555687a05fff in PyObject_Vectorcall Objects/call.c:325
    #27 0x5556879a3252 in _PyEval_EvalFrameDefault Python/bytecodes.c:2706
    #28 0x555687ba84fa in pymain_run_module Modules/main.c:300
    #29 0x555687ba8cd9 in pymain_run_python Modules/main.c:623
    #30 0x555687ba96f9 in Py_RunMain Modules/main.c:709
    #31 0x555687ba96f9 in pymain_main Modules/main.c:739
    #32 0x555687ba96f9 in Py_BytesMain Modules/main.c:763
    #33 0x7f2791c46249 in __libc_start_call_main ../sysdeps/nptl/libc_start_call_main.h:58
    #34 0x7f2791c46304 in __libc_start_main_impl ../csu/libc-start.c:360
    #35 0x5556879aa030 in _start (/home/kirr/local/py3.12/bin/python3.12+0x10c030) (BuildId: 90994913e85aac5c35e9f04b53a6eeee5a04786d)

Direct leak of 1520 byte(s) in 1 object(s) allocated from:
    #0 0x7f27922f3bd7 in malloc ../../../../src/libsanitizer/asan/asan_malloc_linux.cpp:69
    #1 0x555687a6a9d2 in PyMem_RawMalloc Objects/obmalloc.c:662
    #2 0x555687a6a9d2 in _PyObject_Malloc Objects/obmalloc.c:1569
    #3 0x555687a4d4e8 in new_keys_object Objects/dictobject.c:641
    #4 0x555687a4d4e8 in dictresize Objects/dictobject.c:1449
    #5 0x555687a53277 in insertion_resize Objects/dictobject.c:1194
    #6 0x555687a53277 in insertdict Objects/dictobject.c:1261
    #7 0x5556879a4de2 in _PyEval_EvalFrameDefault Python/bytecodes.c:579
    #8 0x555687a09a90 in _PyObject_VectorcallTstate Include/internal/pycore_call.h:92
    #9 0x555687a09a90 in method_vectorcall Objects/classobject.c:91
    #10 0x55568799e2ed in _PyEval_EvalFrameDefault Python/bytecodes.c:3254
    #11 0x555687a0833e in _PyObject_FastCallDictTstate Objects/call.c:144
    #12 0x555687a0833e in _PyObject_Call_Prepend Objects/call.c:508
    #13 0x555687a8ba6c in slot_tp_call Objects/typeobject.c:8770
    #14 0x555687a05733 in _PyObject_MakeTpCall Objects/call.c:240
    #15 0x5556879a3252 in _PyEval_EvalFrameDefault Python/bytecodes.c:2706
    #16 0x555687b22926 in _PyEval_EvalFrame Include/internal/pycore_ceval.h:89
    #17 0x555687b22926 in _PyEval_Vector Python/ceval.c:1683
    #18 0x555687b22926 in PyEval_EvalCode Python/ceval.c:578
    #19 0x555687b1ebdf in builtin_exec_impl Python/bltinmodule.c:1096
    #20 0x555687b1ebdf in builtin_exec Python/clinic/bltinmodule.c.h:586
    #21 0x555687a613ae in cfunction_vectorcall_FASTCALL_KEYWORDS Objects/methodobject.c:438
    #22 0x555687a05fff in _PyObject_VectorcallTstate Include/internal/pycore_call.h:92
    #23 0x555687a05fff in PyObject_Vectorcall Objects/call.c:325
    #24 0x5556879a3252 in _PyEval_EvalFrameDefault Python/bytecodes.c:2706
    #25 0x555687ba84fa in pymain_run_module Modules/main.c:300
    #26 0x555687ba8cd9 in pymain_run_python Modules/main.c:623
    #27 0x555687ba96f9 in Py_RunMain Modules/main.c:709
    #28 0x555687ba96f9 in pymain_main Modules/main.c:739
    #29 0x555687ba96f9 in Py_BytesMain Modules/main.c:763
    #30 0x7f2791c46249 in __libc_start_call_main ../sysdeps/nptl/libc_start_call_main.h:58
    #31 0x7f2791c46304 in __libc_start_main_impl ../csu/libc-start.c:360
    #32 0x5556879aa030 in _start (/home/kirr/local/py3.12/bin/python3.12+0x10c030) (BuildId: 90994913e85aac5c35e9f04b53a6eeee5a04786d)

Direct leak of 1520 byte(s) in 1 object(s) allocated from:
    #0 0x7f27922f3bd7 in malloc ../../../../src/libsanitizer/asan/asan_malloc_linux.cpp:69
    #1 0x555687a6a9d2 in PyMem_RawMalloc Objects/obmalloc.c:662
    #2 0x555687a6a9d2 in _PyObject_Malloc Objects/obmalloc.c:1569
    #3 0x555687a4d4e8 in new_keys_object Objects/dictobject.c:641
    #4 0x555687a4d4e8 in dictresize Objects/dictobject.c:1449
    #5 0x555687a53277 in insertion_resize Objects/dictobject.c:1194
    #6 0x555687a53277 in insertdict Objects/dictobject.c:1261
    #7 0x555687a65e81 in _PyObject_GenericSetAttrWithDict Objects/object.c:1562
    #8 0x555687a65e81 in PyObject_GenericSetAttr Objects/object.c:1619
    #9 0x555687a67094 in PyObject_SetAttr Objects/object.c:1175
    #10 0x555687b1bbe6 in builtin_setattr_impl Python/bltinmodule.c:1547
    #11 0x555687b1bbe6 in builtin_setattr Python/clinic/bltinmodule.c.h:765
    #12 0x5556879a57c9 in _PyEval_EvalFrameDefault Python/bytecodes.c:2929
    #13 0x555687b22926 in _PyEval_EvalFrame Include/internal/pycore_ceval.h:89
    #14 0x555687b22926 in _PyEval_Vector Python/ceval.c:1683
    #15 0x555687b22926 in PyEval_EvalCode Python/ceval.c:578
    #16 0x555687b1ebdf in builtin_exec_impl Python/bltinmodule.c:1096
    #17 0x555687b1ebdf in builtin_exec Python/clinic/bltinmodule.c.h:586
    #18 0x555687a613ae in cfunction_vectorcall_FASTCALL_KEYWORDS Objects/methodobject.c:438
    #19 0x555687a05fff in _PyObject_VectorcallTstate Include/internal/pycore_call.h:92
    #20 0x555687a05fff in PyObject_Vectorcall Objects/call.c:325
    #21 0x5556879a3252 in _PyEval_EvalFrameDefault Python/bytecodes.c:2706
    #22 0x555687ba84fa in pymain_run_module Modules/main.c:300
    #23 0x555687ba8cd9 in pymain_run_python Modules/main.c:623
    #24 0x555687ba96f9 in Py_RunMain Modules/main.c:709
    #25 0x555687ba96f9 in pymain_main Modules/main.c:739
    #26 0x555687ba96f9 in Py_BytesMain Modules/main.c:763
    #27 0x7f2791c46249 in __libc_start_call_main ../sysdeps/nptl/libc_start_call_main.h:58
    #28 0x7f2791c46304 in __libc_start_main_impl ../csu/libc-start.c:360
    #29 0x5556879aa030 in _start (/home/kirr/local/py3.12/bin/python3.12+0x10c030) (BuildId: 90994913e85aac5c35e9f04b53a6eeee5a04786d)

Direct leak of 1520 byte(s) in 1 object(s) allocated from:
    #0 0x7f27922f3bd7 in malloc ../../../../src/libsanitizer/asan/asan_malloc_linux.cpp:69
    #1 0x555687a6a9d2 in PyMem_RawMalloc Objects/obmalloc.c:662
    #2 0x555687a6a9d2 in _PyObject_Malloc Objects/obmalloc.c:1569
    #3 0x555687a4bc0b in clone_combined_dict_keys Objects/dictobject.c:799
    #4 0x555687a53e8f in dict_merge Objects/dictobject.c:2843
    #5 0x555687a56f71 in dict_update_common Objects/dictobject.c:2688
    #6 0x555687a56f71 in dict_update Objects/dictobject.c:2706
    #7 0x555687a13bdb in method_vectorcall_VARARGS_KEYWORDS Objects/descrobject.c:365
    #8 0x555687a05fff in _PyObject_VectorcallTstate Include/internal/pycore_call.h:92
    #9 0x555687a05fff in PyObject_Vectorcall Objects/call.c:325
    #10 0x5556879a3252 in _PyEval_EvalFrameDefault Python/bytecodes.c:2706
    #11 0x555687a09a90 in _PyObject_VectorcallTstate Include/internal/pycore_call.h:92
    #12 0x555687a09a90 in method_vectorcall Objects/classobject.c:91
    #13 0x55568799e2ed in _PyEval_EvalFrameDefault Python/bytecodes.c:3254
    #14 0x555687a0833e in _PyObject_FastCallDictTstate Objects/call.c:144
    #15 0x555687a0833e in _PyObject_Call_Prepend Objects/call.c:508
    #16 0x555687a8ba6c in slot_tp_call Objects/typeobject.c:8770
    #17 0x555687a05733 in _PyObject_MakeTpCall Objects/call.c:240
    #18 0x5556879a3252 in _PyEval_EvalFrameDefault Python/bytecodes.c:2706
    #19 0x555687b22926 in _PyEval_EvalFrame Include/internal/pycore_ceval.h:89
    #20 0x555687b22926 in _PyEval_Vector Python/ceval.c:1683
    #21 0x555687b22926 in PyEval_EvalCode Python/ceval.c:578
    #22 0x555687b1ebdf in builtin_exec_impl Python/bltinmodule.c:1096
    #23 0x555687b1ebdf in builtin_exec Python/clinic/bltinmodule.c.h:586
    #24 0x555687a613ae in cfunction_vectorcall_FASTCALL_KEYWORDS Objects/methodobject.c:438
    #25 0x555687a05fff in _PyObject_VectorcallTstate Include/internal/pycore_call.h:92
    #26 0x555687a05fff in PyObject_Vectorcall Objects/call.c:325
    #27 0x5556879a3252 in _PyEval_EvalFrameDefault Python/bytecodes.c:2706
    #28 0x555687ba84fa in pymain_run_module Modules/main.c:300
    #29 0x555687ba8cd9 in pymain_run_python Modules/main.c:623
    #30 0x555687ba96f9 in Py_RunMain Modules/main.c:709
    #31 0x555687ba96f9 in pymain_main Modules/main.c:739
    #32 0x555687ba96f9 in Py_BytesMain Modules/main.c:763
    #33 0x7f2791c46249 in __libc_start_call_main ../sysdeps/nptl/libc_start_call_main.h:58
    #34 0x7f2791c46304 in __libc_start_main_impl ../csu/libc-start.c:360
    #35 0x5556879aa030 in _start (/home/kirr/local/py3.12/bin/python3.12+0x10c030) (BuildId: 90994913e85aac5c35e9f04b53a6eeee5a04786d)

Direct leak of 1520 byte(s) in 1 object(s) allocated from:
    #0 0x7f27922f3bd7 in malloc ../../../../src/libsanitizer/asan/asan_malloc_linux.cpp:69
    #1 0x555687a6a9d2 in PyMem_RawMalloc Objects/obmalloc.c:662
    #2 0x555687a6a9d2 in _PyObject_Malloc Objects/obmalloc.c:1569
    #3 0x555687a4d4e8 in new_keys_object Objects/dictobject.c:641
    #4 0x555687a4d4e8 in dictresize Objects/dictobject.c:1449
    #5 0x555687a53277 in insertion_resize Objects/dictobject.c:1194
    #6 0x555687a53277 in insertdict Objects/dictobject.c:1261
    #7 0x5556879a7314 in _PyEval_EvalFrameDefault Python/bytecodes.c:1023
    #8 0x555687b22926 in _PyEval_EvalFrame Include/internal/pycore_ceval.h:89
    #9 0x555687b22926 in _PyEval_Vector Python/ceval.c:1683
    #10 0x555687b22926 in PyEval_EvalCode Python/ceval.c:578
    #11 0x555687b1ebdf in builtin_exec_impl Python/bltinmodule.c:1096
    #12 0x555687b1ebdf in builtin_exec Python/clinic/bltinmodule.c.h:586
    #13 0x5556879a5949 in _PyEval_EvalFrameDefault Python/bytecodes.c:2966
    #14 0x555687a061f5 in _PyObject_VectorcallTstate Include/internal/pycore_call.h:92
    #15 0x555687a061f5 in PyObject_CallOneArg Objects/call.c:401
    #16 0x555687a675f1 in _PyObject_GenericGetAttrWithDict Objects/object.c:1430
    #17 0x555687a6728d in PyObject_GetAttr Objects/object.c:1044
    #18 0x55568799fd39 in _PyEval_EvalFrameDefault Python/bytecodes.c:1794
    #19 0x555687a0833e in _PyObject_FastCallDictTstate Objects/call.c:144
    #20 0x555687a0833e in _PyObject_Call_Prepend Objects/call.c:508
    #21 0x555687a8ba6c in slot_tp_call Objects/typeobject.c:8770
    #22 0x555687a05733 in _PyObject_MakeTpCall Objects/call.c:240
    #23 0x5556879a3252 in _PyEval_EvalFrameDefault Python/bytecodes.c:2706
    #24 0x555687a22c14 in _PyEval_EvalFrame Include/internal/pycore_ceval.h:89
    #25 0x555687a22c14 in gen_send_ex2 Objects/genobject.c:230
    #26 0x555687a22c14 in gen_iternext Objects/genobject.c:604
    #27 0x555687a37fa5 in list_extend Objects/listobject.c:944
    #28 0x555687a14520 in method_vectorcall_O Objects/descrobject.c:482
    #29 0x555687a05fff in _PyObject_VectorcallTstate Include/internal/pycore_call.h:92
    #30 0x555687a05fff in PyObject_Vectorcall Objects/call.c:325
    #31 0x5556879a3252 in _PyEval_EvalFrameDefault Python/bytecodes.c:2706
    #32 0x555687a0833e in _PyObject_FastCallDictTstate Objects/call.c:144
    #33 0x555687a0833e in _PyObject_Call_Prepend Objects/call.c:508
    #34 0x555687a8ba6c in slot_tp_call Objects/typeobject.c:8770
    #35 0x555687a05733 in _PyObject_MakeTpCall Objects/call.c:240
    #36 0x5556879a3252 in _PyEval_EvalFrameDefault Python/bytecodes.c:2706
    #37 0x555687a0833e in _PyObject_FastCallDictTstate Objects/call.c:144
    #38 0x555687a0833e in _PyObject_Call_Prepend Objects/call.c:508
    #39 0x555687a8ba6c in slot_tp_call Objects/typeobject.c:8770
    #40 0x555687a05733 in _PyObject_MakeTpCall Objects/call.c:240
    #41 0x5556879a3252 in _PyEval_EvalFrameDefault Python/bytecodes.c:2706
    #42 0x555687b22926 in _PyEval_EvalFrame Include/internal/pycore_ceval.h:89
    #43 0x555687b22926 in _PyEval_Vector Python/ceval.c:1683
    #44 0x555687b22926 in PyEval_EvalCode Python/ceval.c:578
    #45 0x555687b1ebdf in builtin_exec_impl Python/bltinmodule.c:1096
    #46 0x555687b1ebdf in builtin_exec Python/clinic/bltinmodule.c.h:586
    #47 0x555687a613ae in cfunction_vectorcall_FASTCALL_KEYWORDS Objects/methodobject.c:438
    #48 0x555687a05fff in _PyObject_VectorcallTstate Include/internal/pycore_call.h:92
    #49 0x555687a05fff in PyObject_Vectorcall Objects/call.c:325
    #50 0x5556879a3252 in _PyEval_EvalFrameDefault Python/bytecodes.c:2706
    #51 0x555687ba84fa in pymain_run_module Modules/main.c:300
    #52 0x555687ba8cd9 in pymain_run_python Modules/main.c:623
    #53 0x555687ba96f9 in Py_RunMain Modules/main.c:709
    #54 0x555687ba96f9 in pymain_main Modules/main.c:739
    #55 0x555687ba96f9 in Py_BytesMain Modules/main.c:763
    #56 0x7f2791c46249 in __libc_start_call_main ../sysdeps/nptl/libc_start_call_main.h:58
    #57 0x7f2791c46304 in __libc_start_main_impl ../csu/libc-start.c:360
    #58 0x5556879aa030 in _start (/home/kirr/local/py3.12/bin/python3.12+0x10c030) (BuildId: 90994913e85aac5c35e9f04b53a6eeee5a04786d)

Direct leak of 1104 byte(s) in 1 object(s) allocated from:
    #0 0x7f27922f3bd7 in malloc ../../../../src/libsanitizer/asan/asan_malloc_linux.cpp:69
    #1 0x555687a6a9d2 in PyMem_RawMalloc Objects/obmalloc.c:662
    #2 0x555687a6a9d2 in _PyObject_Malloc Objects/obmalloc.c:1569
    #3 0x555687a4d4e8 in new_keys_object Objects/dictobject.c:641
    #4 0x555687a4d4e8 in dictresize Objects/dictobject.c:1449
    #5 0x555687a53277 in insertion_resize Objects/dictobject.c:1194
    #6 0x555687a53277 in insertdict Objects/dictobject.c:1261
    #7 0x5556879a4de2 in _PyEval_EvalFrameDefault Python/bytecodes.c:579
    #8 0x555687a0833e in _PyObject_FastCallDictTstate Objects/call.c:144
    #9 0x555687a0833e in _PyObject_Call_Prepend Objects/call.c:508
    #10 0x555687a8ba6c in slot_tp_call Objects/typeobject.c:8770
    #11 0x555687a05733 in _PyObject_MakeTpCall Objects/call.c:240
    #12 0x5556879a3252 in _PyEval_EvalFrameDefault Python/bytecodes.c:2706
    #13 0x555687a22c14 in _PyEval_EvalFrame Include/internal/pycore_ceval.h:89
    #14 0x555687a22c14 in gen_send_ex2 Objects/genobject.c:230
    #15 0x555687a22c14 in gen_iternext Objects/genobject.c:604
    #16 0x555687a37fa5 in list_extend Objects/listobject.c:944
    #17 0x5556879a3a9a in _PyEval_EvalFrameDefault Python/bytecodes.c:3085
    #18 0x555687a0833e in _PyObject_FastCallDictTstate Objects/call.c:144
    #19 0x555687a0833e in _PyObject_Call_Prepend Objects/call.c:508
    #20 0x555687a8ba6c in slot_tp_call Objects/typeobject.c:8770
    #21 0x555687a05733 in _PyObject_MakeTpCall Objects/call.c:240
    #22 0x5556879a3252 in _PyEval_EvalFrameDefault Python/bytecodes.c:2706
    #23 0x555687a0833e in _PyObject_FastCallDictTstate Objects/call.c:144
    #24 0x555687a0833e in _PyObject_Call_Prepend Objects/call.c:508
    #25 0x555687a8ba6c in slot_tp_call Objec…
  • Loading branch information
navytux committed Apr 19, 2024
1 parent cb7e3c1 commit f9e52cb
Show file tree
Hide file tree
Showing 6 changed files with 213 additions and 17 deletions.
124 changes: 124 additions & 0 deletions .lsan-ignore.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,124 @@
# .lsan-ignore.txt lists memory leak events that LeakSanitizer should not
# report when running pygolang tests.
#
# Many python allocations, whose lifetime coincides with python interpreter
# lifetime, and which are not explicitly freed on python shutdown, are
# reported as leaks by default. Disable leak reporting for those to avoid
# non-pygolang related printouts.


# >>> Everything created when initializing python, e.g. sys.stderr
# #0 0x7f21e74f3bd7 in malloc .../asan_malloc_linux.cpp:69
# #1 0x555f361ff9a4 in PyThread_allocate_lock Python/thread_pthread.h:385
# #2 0x555f3623f72a in _buffered_init Modules/_io/bufferedio.c:725
# #3 0x555f3623ff7e in _io_BufferedWriter___init___impl Modules/_io/bufferedio.c:1803
# #4 0x555f3623ff7e in _io_BufferedWriter___init__ Modules/_io/clinic/bufferedio.c.h:489
# #5 0x555f3610c086 in type_call Objects/typeobject.c:1103
# #6 0x555f3609cdcc in _PyObject_MakeTpCall Objects/call.c:214
# #7 0x555f3609d6a8 in _PyObject_VectorcallTstate Include/internal/pycore_call.h:90
# #8 0x555f3609d6a8 in _PyObject_VectorcallTstate Include/internal/pycore_call.h:77
# #9 0x555f3609d6a8 in _PyObject_CallFunctionVa Objects/call.c:536
# #10 0x555f3609e89c in _PyObject_CallFunction_SizeT Objects/call.c:590
# #11 0x555f3623a0df in _io_open_impl Modules/_io/_iomodule.c:407
# #12 0x555f3623a0df in _io_open Modules/_io/clinic/_iomodule.c.h:264
# #13 0x555f360f17da in cfunction_vectorcall_FASTCALL_KEYWORDS Objects/methodobject.c:443
# #14 0x555f3609d54c in _PyObject_VectorcallTstate Include/internal/pycore_call.h:92
# #15 0x555f3609d54c in _PyObject_CallFunctionVa Objects/call.c:536
# #16 0x555f3609ec34 in callmethod Objects/call.c:608
# #17 0x555f3609ec34 in _PyObject_CallMethod Objects/call.c:677
# #18 0x555f361e60cf in create_stdio Python/pylifecycle.c:2244
# #19 0x555f361e6523 in init_sys_streams Python/pylifecycle.c:2431
# #20 0x555f361e6523 in init_interp_main Python/pylifecycle.c:1154
# #21 0x555f361e7204 in pyinit_main Python/pylifecycle.c:1230
# #22 0x555f361e85ba in Py_InitializeFromConfig Python/pylifecycle.c:1261
# #23 0x555f3621010a in pymain_init Modules/main.c:67
# #24 0x555f362113de in pymain_main Modules/main.c:701
# #25 0x555f362113de in Py_BytesMain Modules/main.c:734
leak:^pymain_init$

# >>> Everything created when importing py modules, e.g.
# #0 0x7f18c86f3bd7 in malloc .../asan_malloc_linux.cpp:69
# #1 0x55b971430acf in PyMem_RawMalloc Objects/obmalloc.c:586
# #2 0x55b971430acf in _PyObject_Malloc Objects/obmalloc.c:2003
# #3 0x55b971430acf in _PyObject_Malloc Objects/obmalloc.c:1996
# #4 0x55b971415696 in new_keys_object Objects/dictobject.c:632
# #5 0x55b971415716 in dictresize Objects/dictobject.c:1429
# #6 0x55b97141961a in insertion_resize Objects/dictobject.c:1183
# #7 0x55b97141961a in insertdict Objects/dictobject.c:1248
# #8 0x55b97143eb7b in add_subclass Objects/typeobject.c:6547
# #9 0x55b97144ca52 in type_ready_add_subclasses Objects/typeobject.c:6345
# #10 0x55b97144ca52 in type_ready Objects/typeobject.c:6476
# #11 0x55b971451a1f in PyType_Ready Objects/typeobject.c:6508
# #12 0x55b971451a1f in type_new_impl Objects/typeobject.c:3189
# #13 0x55b971451a1f in type_new Objects/typeobject.c:3323
# #14 0x55b971443014 in type_call Objects/typeobject.c:1091
# #15 0x55b9713d3dcc in _PyObject_MakeTpCall Objects/call.c:214
# #16 0x55b9713d47bd in _PyObject_FastCallDictTstate Objects/call.c:141
# #17 0x55b9713d47bd in PyObject_VectorcallDict Objects/call.c:165
# #18 0x55b9714d14c2 in builtin___build_class__ Python/bltinmodule.c:209
# #19 0x55b9714287da in cfunction_vectorcall_FASTCALL_KEYWORDS Objects/methodobject.c:443
# #20 0x55b9713d4a7b in _PyObject_VectorcallTstate Include/internal/pycore_call.h:92
# #21 0x55b9713d4a7b in PyObject_Vectorcall Objects/call.c:299
# #22 0x55b97137666e in _PyEval_EvalFrameDefault Python/ceval.c:4769
# #23 0x55b9714d7e6b in _PyEval_EvalFrame Include/internal/pycore_ceval.h:73
# #24 0x55b9714d7e6b in _PyEval_Vector Python/ceval.c:6434
# #25 0x55b9714d7e6b in PyEval_EvalCode Python/ceval.c:1148
# #26 0x55b9714d2e1f in builtin_exec_impl Python/bltinmodule.c:1077
# #27 0x55b9714d2e1f in builtin_exec Python/clinic/bltinmodule.c.h:465
# #28 0x55b9714287da in cfunction_vectorcall_FASTCALL_KEYWORDS Objects/methodobject.c:443
# #29 0x55b971376dcb in do_call_core Python/ceval.c:7349
# #30 0x55b971376dcb in _PyEval_EvalFrameDefault Python/ceval.c:5376
# #31 0x55b9714d7faf in _PyEval_EvalFrame Include/internal/pycore_ceval.h:73
# #32 0x55b9714d7faf in _PyEval_Vector Python/ceval.c:6434
# #33 0x55b9713d436e in _PyObject_VectorcallTstate Include/internal/pycore_call.h:92
# #34 0x55b9713d436e in object_vacall Objects/call.c:819
# #35 0x55b9713d63cf in PyObject_CallMethodObjArgs Objects/call.c:879
# #36 0x55b9715080e1 in import_find_and_load Python/import.c:1748
# #37 0x55b9715080e1 in PyImport_ImportModuleLevelObject Python/import.c:1847
# #38 0x55b97137de9c in import_name Python/ceval.c:7422
# #39 0x55b97137de9c in _PyEval_EvalFrameDefault Python/ceval.c:3946
# #40 0x55b9714d7e6b in _PyEval_EvalFrame Include/internal/pycore_ceval.h:73
# #41 0x55b9714d7e6b in _PyEval_Vector Python/ceval.c:6434
# #42 0x55b9714d7e6b in PyEval_EvalCode Python/ceval.c:1148
# #43 0x55b9714d2e1f in builtin_exec_impl Python/bltinmodule.c:1077
# #44 0x55b9714d2e1f in builtin_exec Python/clinic/bltinmodule.c.h:465
# #45 0x55b9714287da in cfunction_vectorcall_FASTCALL_KEYWORDS Objects/methodobject.c:443
# #46 0x55b971376dcb in do_call_core Python/ceval.c:7349
# #47 0x55b971376dcb in _PyEval_EvalFrameDefault Python/ceval.c:5376
leak:^PyImport_Import
# importlib.import_module leads to
# #0 0x7f1951ef3bd7 in malloc ../../../../src/libsanitizer/asan/asan_malloc_linux.cpp:69
# #1 0x55f399e8cacf in PyMem_RawMalloc Objects/obmalloc.c:586
# #2 0x55f399e8cacf in _PyObject_Malloc Objects/obmalloc.c:2003
# #3 0x55f399e8cacf in _PyObject_Malloc Objects/obmalloc.c:1996
# #4 0x55f399e86344 in PyModule_ExecDef Objects/moduleobject.c:400
# #5 0x55f399f6178a in exec_builtin_or_dynamic Python/import.c:2345
# #6 0x55f399f6178a in _imp_exec_dynamic_impl Python/import.c:2419
# #7 0x55f399f6178a in _imp_exec_dynamic Python/clinic/import.c.h:474
# #8 0x55f399e8438a in cfunction_vectorcall_O Objects/methodobject.c:514
leak:^_imp_exec_dynamic


# >>> Everything allocated at DSO initialization, e.g.
# #0 0x7f35d2af46c8 in operator new(unsigned long) .../asan_new_delete.cpp:95
# #1 0x7f35ce897e9f in __static_initialization_and_destruction_0 golang/context.cpp:61
# #2 0x7f35ce8982ef in _GLOBAL__sub_I_context.cpp golang/context.cpp:380
# #3 0x7f35d32838bd in call_init elf/dl-init.c:90
# #4 0x7f35d32838bd in call_init elf/dl-init.c:27
# #5 0x7f35d32839a3 in _dl_init elf/dl-init.c:137
# #6 0x7f35d256e023 in __GI__dl_catch_exception elf/dl-error-skeleton.c:182
# #7 0x7f35d328a09d in dl_open_worker elf/dl-open.c:808
# #8 0x7f35d256dfc9 in __GI__dl_catch_exception elf/dl-error-skeleton.c:208
# #9 0x7f35d328a437 in _dl_open elf/dl-open.c:884
# #10 0x7f35d24a4437 in dlopen_doit dlfcn/dlopen.c:56
# #11 0x7f35d256dfc9 in __GI__dl_catch_exception elf/dl-error-skeleton.c:208
# #12 0x7f35d256e07e in __GI__dl_catch_error elf/dl-error-skeleton.c:227
# #13 0x7f35d24a3f26 in _dlerror_run dlfcn/dlerror.c:138
# #14 0x7f35d24a44e8 in dlopen_implementation dlfcn/dlopen.c:71
# #15 0x7f35d24a44e8 in ___dlopen dlfcn/dlopen.c:81
# #16 0x7f35d2a77ff9 in dlopen .../sanitizer_common_interceptors.inc:6341
leak:^_GLOBAL_


# global<> does not deallocate its reference on purpose
leak:^_test_global()$
2 changes: 1 addition & 1 deletion MANIFEST.in
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
include COPYING README.rst CHANGELOG.rst tox.ini pyproject.toml trun .nxdtest
include COPYING README.rst CHANGELOG.rst tox.ini pyproject.toml trun .lsan-ignore.txt .nxdtest conftest.py
include golang/libgolang.h
include golang/runtime/libgolang.cpp
include golang/runtime/libpyxruntime.cpp
Expand Down
28 changes: 28 additions & 0 deletions conftest.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
# pygolang | pytest config
# Copyright (C) 2021-2024 Nexedi SA and Contributors.
# Kirill Smelkov <kirr@nexedi.com>
#
# This program is free software: you can Use, Study, Modify and Redistribute
# it under the terms of the GNU General Public License version 3, or (at your
# option) any later version, as published by the Free Software Foundation.
#
# You can also Link and Combine this program with other software covered by
# the terms of any of the Free Software licenses or any of the Open Source
# Initiative approved licenses and Convey the resulting work. Corresponding
# source of such a combination shall include the source code for all other
# software used.
#
# This program is distributed WITHOUT ANY WARRANTY; without even the implied
# warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
#
# See COPYING file for full licensing terms.
# See https://www.nexedi.com/licensing for rationale and options.

from __future__ import print_function, absolute_import

import gc


# Do full GC before pytest exits, to avoid false positives in the leak detector.
def pytest_unconfigure():
gc.collect()
10 changes: 8 additions & 2 deletions golang/golang_test.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
# -*- coding: utf-8 -*-
# Copyright (C) 2018-2023 Nexedi SA and Contributors.
# Copyright (C) 2018-2024 Nexedi SA and Contributors.
# Kirill Smelkov <kirr@nexedi.com>
#
# This program is free software: you can Use, Study, Modify and Redistribute
Expand Down Expand Up @@ -74,7 +74,8 @@ def _(b, func=getattr(mod, f)):
# leaked goroutine behaviour check: done in separate process because we need
# to test process termination exit there.
def test_go_leaked():
pyrun([dir_testprog + "/golang_test_goleaked.py"])
pyrun([dir_testprog + "/golang_test_goleaked.py"],
lsan=False) # there are on-purpose leaks in this test

# benchmark go+join a thread/coroutine.
# pyx/nogil mirror is in _golang_test.pyx
Expand Down Expand Up @@ -1756,6 +1757,11 @@ def _pyrun(argv, stdin=None, stdout=None, stderr=None, **kw): # -> retcode, st
assert len(enc) == 1
env['PYTHONIOENCODING'] = enc.pop()

# disable LeakSanitizer if requested, e.g. when test is known to leak something on purpose
lsan = kw.pop('lsan', True)
if not lsan:
env['ASAN_OPTIONS'] = env.get('ASAN_OPTIONS', '') + ',detect_leaks=0'

p = Popen(argv, stdin=(PIPE if stdin else None), stdout=stdout, stderr=stderr, env=env, **kw)
stdout, stderr = p.communicate(stdin)

Expand Down
11 changes: 6 additions & 5 deletions golang/pyx/build_test.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
# -*- coding: utf-8 -*-
# Copyright (C) 2019 Nexedi SA and Contributors.
# Kirill Smelkov <kirr@nexedi.com>
# Copyright (C) 2019-2024 Nexedi SA and Contributors.
# Kirill Smelkov <kirr@nexedi.com>
#
# This program is free software: you can Use, Study, Modify and Redistribute
# it under the terms of the GNU General Public License version 3, or (at your
Expand Down Expand Up @@ -28,7 +28,8 @@
# verify that we can build/run external package that uses pygolang in pyx mode.
def test_pyx_build():
pyxuser = testprog + "/golang_pyx_user"
pyrun(["setup.py", "build_ext", "-i"], cwd=pyxuser)
pyrun(["setup.py", "build_ext", "-i"], cwd=pyxuser,
lsan=False) # gcc leaks

# run built test.
_ = pyout(["-c",
Expand All @@ -44,8 +45,8 @@ def test_pyx_build():
# verify that we can build/run external dso that uses libgolang.
def test_dso_build():
dsouser = testprog + "/golang_dso_user"
pyrun(["setup.py", "build_dso", "-i"], cwd=dsouser)
pyrun(["setup.py", "build_ext", "-i"], cwd=dsouser)
pyrun(["setup.py", "build_dso", "-i"], cwd=dsouser, lsan=False) # gcc leaks
pyrun(["setup.py", "build_ext", "-i"], cwd=dsouser, lsan=False) # gcc leaks

# run built test.
_ = pyout(["-c",
Expand Down
55 changes: 46 additions & 9 deletions trun
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
#!/usr/bin/env python
# -*- coding: utf-8 -*-
# Copyright (C) 2019-2024 Nexedi SA and Contributors.
# Kirill Smelkov <kirr@nexedi.com>
#
Expand Down Expand Up @@ -34,7 +35,7 @@ trun cares to run python with LD_PRELOAD set appropriately to /path/to/libtsan.s

from __future__ import print_function, absolute_import

import os, sys, re, subprocess, types
import os, os.path, sys, re, subprocess, platform, types
PY3 = (bytes is not str)
if PY3:
from importlib import machinery as imp_machinery
Expand Down Expand Up @@ -87,6 +88,7 @@ def main():

# determine if _golang.so is linked to a sanitizer, and if yes, to which
# particular sanitizer DSO. Set LD_PRELOAD appropriately.
libxsan = None
ld_preload = None
if 'linux' in sys.platform:
p = subprocess.Popen(["ldd", _golang_so.path], stdout=subprocess.PIPE)
Expand Down Expand Up @@ -127,7 +129,8 @@ def main():

_ = grep1("DYLD_INSERT_LIBRARIES=(.*)$", err)
if _ is not None:
ld_preload = ("DYLD_INSERT_LIBRARIES", _.group(1))
libxsan = _.group(1)
ld_preload = ("DYLD_INSERT_LIBRARIES", libxsan)
else:
print("trun %r: `import golang` failed with unexpected error:" % sys.argv[1:], file=sys.stderr)
print(err, file=sys.stderr)
Expand All @@ -144,23 +147,57 @@ def main():
env_prepend("TSAN_OPTIONS", "halt_on_error=1")
env_prepend("ASAN_OPTIONS", "halt_on_error=1")

# tweak TSAN/ASAN defaults:
# tweak TSAN/ASAN/LSAN defaults:

# enable TSAN deadlock detector
# (unfortunately it caughts only few _potential_ deadlocks and actually
# gets stuck on any real deadlock)
env_prepend("TSAN_OPTIONS", "detect_deadlocks=1")
env_prepend("TSAN_OPTIONS", "second_deadlock_stack=1")

# many python allocations, whose lifetime coincides with python interpreter
# lifetime and which are not explicitly freed on python shutdown, are
# reported as leaks. Disable leak reporting to avoid huge non-pygolang
# related printouts.
env_prepend("ASAN_OPTIONS", "detect_leaks=0")

# tune ASAN to check more aggressively by default
env_prepend("ASAN_OPTIONS", "detect_stack_use_after_return=1")

# enable ASAN/LSAN leak detector.
#
# Do it only on CPython ≥ 3.11 because on py2 and on earlier py3 versions
# there are many many python allocations, whose lifetime coincide with
# python interpreter lifetime, and which are not explicitly freed on python
# shutdown. For py3 they significantly improved this step by step and
# starting from 3.11 it becomes practical to silence some still-leaks with
# suppressions, while for earlier py3 versions and especially for py2 it
# is, unfortunately, not manageable. Do not spend engineering time with
# activating LSAN on PyPy as that is tier 2 platform and bug tail history
# of memory leaks is very long even only on cpython.
if sys.version_info < (3,11):
env_prepend("ASAN_OPTIONS", "detect_leaks=0")
if libxsan is not None:
if 'asan' in libxsan.lower():
print("W: trun %r: asan: leak detection deactivated on %s %s" % (
sys.argv[1:], platform.python_implementation(), platform.python_version()),
file=sys.stderr)
else:
env_prepend("ASAN_OPTIONS", "detect_leaks=1")
env_prepend("LSAN_OPTIONS", "suppressions=%s" % os.path.abspath(os.path.join(
os.path.dirname(__file__), ".lsan-ignore.txt")))
# do not print statistics for suppressed leaks - else it breaks tests that verify program output
env_prepend("LSAN_OPTIONS", "print_suppressions=0")

# enable DWARF-based unwinding.
# else, if python is not compiled with -fno-omit-frame-pointer, it can show
# the whole traceback as e.g. just
# Direct leak of 32 byte(s) in 1 object(s) allocated from:
# #0 0x7f88522f3bd7 in malloc ../../../../src/libsanitizer/asan/asan_malloc_linux.cpp:69
# #1 0x55f910a3d9a4 in PyThread_allocate_lock Python/thread_pthread.h:385
# and our leak suppressions won't work.
# this is slower compared to default frame-pointer based unwinding, but
# still works reasonably timely when run with just tests.
env_prepend("ASAN_OPTIONS", "fast_unwind_on_malloc=0")
# leak suppression also needs full tracebacks to work correctly, since with
# python there are many levels of call nesting at C level, and to filter-out e.g.
# top-level PyImport_Import we need to go really deep.
env_prepend("ASAN_OPTIONS", "malloc_context_size=255")

# exec `...`
os.execvp(sys.argv[1], sys.argv[1:])

Expand Down

0 comments on commit f9e52cb

Please sign in to comment.