Skip to content

_lsprof: Memory leak in clearEntries() context chain not fully freed #145846

@raminfp

Description

@raminfp

Bug report

Bug description:

clearEntries() (Modules/_lsprof.c:284-299) only frees the top currentProfilerContext but does NOT walk the previous linked list. When clear() is called while profiling is active with nested calls, all contexts except the top one are leaked.

Affected code (Modules/_lsprof.c:289-292):

    if (pObj->currentProfilerContext) {
        PyMem_Free(pObj->currentProfilerContext);   // only frees the TOP
        pObj->currentProfilerContext = NULL;
    }

Should be a loop like freelistProfilerContext cleanup (lines 293-298):

    while (pObj->currentProfilerContext) {
        ProfilerContext *c = pObj->currentProfilerContext;
        pObj->currentProfilerContext = c->previous;
        PyMem_Free(c);
    }

Reproduction :

import _lsprof


def level3():
    # clear() while 3 levels deep:
    #   context chain: level1_ctx <- level2_ctx <- level3_ctx
    #   clearEntries frees level3_ctx (top), leaks level2_ctx and level1_ctx
    p.clear()


def level2():
    level3()


def level1():
    level2()


p = _lsprof.Profiler()
p.enable()

for i in range(100):
    level1()

p.disable()
del p

ASAN output:

=================================================================
==60895==ERROR: LeakSanitizer: detected memory leaks

Direct leak of 5600 byte(s) in 100 object(s) allocated from:
    #0 0x7d273b2fd9c7 in malloc ../../../../src/libsanitizer/asan/asan_malloc_linux.cpp:69
    #1 0x5cd10235e4e7 in _PyMem_RawMalloc ../Objects/obmalloc.c:65
    #2 0x5cd10235d8b8 in _PyMem_DebugRawAlloc ../Objects/obmalloc.c:3024
    #3 0x5cd10235d920 in _PyMem_DebugRawMalloc ../Objects/obmalloc.c:3057
    #4 0x5cd10235f2cf in _PyMem_DebugMalloc ../Objects/obmalloc.c:3222
    #5 0x5cd10238762c in PyMem_Malloc ../Objects/obmalloc.c:1178
    #6 0x7d273b02df75 in ptrace_enter_call ../Modules/_lsprof.c:387
    #7 0x7d273b02e065 in _lsprof_Profiler__pystart_callback_impl ../Modules/_lsprof.c:631
    #8 0x7d273b02e0d5 in _lsprof_Profiler__pystart_callback ../Modules/clinic/_lsprof.c.h:88
    #9 0x5cd10234736f in cfunction_vectorcall_FASTCALL ../Objects/methodobject.c:449
    #10 0x5cd10260fb68 in _PyObject_VectorcallTstate ../Include/internal/pycore_call.h:136
    #11 0x5cd10261004e in call_one_instrument ../Python/instrumentation.c:985
    #12 0x5cd1026126ed in call_instrumentation_vector ../Python/instrumentation.c:1174
    #13 0x5cd102615c8d in _Py_call_instrumentation ../Python/instrumentation.c:1212
    #14 0x5cd102539a90 in _PyEval_EvalFrameDefault ../Python/generated_cases.c.h:7472
    #15 0x5cd102555ab0 in _PyEval_EvalFrame ../Include/internal/pycore_ceval.h:118
    #16 0x5cd102555e16 in _PyEval_Vector ../Python/ceval.c:2132
    #17 0x5cd1025560cc in PyEval_EvalCode ../Python/ceval.c:680
    #18 0x5cd102659771 in run_eval_code_obj ../Python/pythonrun.c:1366
    #19 0x5cd102659ab7 in run_mod ../Python/pythonrun.c:1469
    #20 0x5cd10265a9ec in pyrun_file ../Python/pythonrun.c:1294
    #21 0x5cd10265d822 in _PyRun_SimpleFileObject ../Python/pythonrun.c:518
    #22 0x5cd10265dace in _PyRun_AnyFileObject ../Python/pythonrun.c:81
    #23 0x5cd1026b2df6 in pymain_run_file_obj ../Modules/main.c:410
    #24 0x5cd1026b3063 in pymain_run_file ../Modules/main.c:429
    #25 0x5cd1026b4861 in pymain_run_python ../Modules/main.c:691
    #26 0x5cd1026b4ef7 in Py_RunMain ../Modules/main.c:772
    #27 0x5cd1026b50e3 in pymain_main ../Modules/main.c:802
    #28 0x5cd1026b5468 in Py_BytesMain ../Modules/main.c:826
    #29 0x5cd10211a675 in main ../Programs/python.c:15

CPython versions tested on:

CPython main branch

Operating systems tested on:

Linux

Linked PRs

Metadata

Metadata

Assignees

No one assigned

    Labels

    extension-modulesC modules in the Modules dirtype-bugAn unexpected behavior, bug, or error

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions