Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

opcode cache for LOAD_GLOBAL emits false alarm in memory leak hunting #81327

Closed
vstinner opened this issue Jun 3, 2019 · 13 comments
Closed

opcode cache for LOAD_GLOBAL emits false alarm in memory leak hunting #81327

vstinner opened this issue Jun 3, 2019 · 13 comments
Assignees
Labels
3.9 only security fixes interpreter-core (Objects, Python, Grammar, and Parser dirs) type-bug An unexpected behavior, bug, or error

Comments

@vstinner
Copy link
Member

vstinner commented Jun 3, 2019

BPO 37146
Nosy @gvanrossum, @vstinner, @methane, @1st1, @pablogsal
PRs
  • bpo-37146: disable opcache when Py_DEBUG is defined #13787
  • bpo-37146: Allow to configure opcode cache and fix huntleaks by presetting it to 1 #13789
  • bpo-42093: Cleanup _PyDict_GetItemHint() #24582
  • bpo-37146: Deactivate opcode cache only when using huntrleaks in the test suite #24643
  • bpo-37146: Move _PyEval_DeactivateOpCache() to the internal C API #24786
  • Note: these values reflect the state of the issue at the time it was migrated and might not reflect the current state.

    Show more details

    GitHub fields:

    assignee = 'https://github.com/tiran'
    closed_at = <Date 2021-02-28.22:42:42.130>
    created_at = <Date 2019-06-03.20:34:43.896>
    labels = ['interpreter-core', 'type-bug', '3.9']
    title = 'opcode cache for LOAD_GLOBAL emits false alarm in memory leak hunting'
    updated_at = <Date 2021-03-08.21:56:41.259>
    user = 'https://github.com/vstinner'

    bugs.python.org fields:

    activity = <Date 2021-03-08.21:56:41.259>
    actor = 'vstinner'
    assignee = 'christian.heimes'
    closed = True
    closed_date = <Date 2021-02-28.22:42:42.130>
    closer = 'pablogsal'
    components = ['Interpreter Core']
    creation = <Date 2019-06-03.20:34:43.896>
    creator = 'vstinner'
    dependencies = []
    files = []
    hgrepos = []
    issue_num = 37146
    keywords = ['patch']
    message_count = 13.0
    messages = ['344469', '344485', '344486', '353666', '353700', '387335', '387338', '387339', '387361', '387368', '387400', '387820', '388311']
    nosy_count = 6.0
    nosy_names = ['gvanrossum', 'vstinner', 'methane', 'yselivanov', 'pablogsal', 'webstarnantes']
    pr_nums = ['13787', '13789', '24582', '24643', '24786']
    priority = 'normal'
    resolution = 'fixed'
    stage = 'resolved'
    status = 'closed'
    superseder = None
    type = 'behavior'
    url = 'https://bugs.python.org/issue37146'
    versions = ['Python 3.9']

    @vstinner
    Copy link
    Member Author

    vstinner commented Jun 3, 2019

    opcode cache for LOAD_GLOBAL introduced false alarm in memory leak hunting (python3 -m test -R 3:3 ...).

    => opcache: bpo-26219.

    Before the change:

    $ git checkout 91234a16367b56ca03ee289f7c03a34d4cfec4c8^
    $ make && ./python -m test -R 3:3 test_pprint 
    ...
    Tests result: SUCCESS

    After the change:

    $ git checkout 91234a16367b56ca03ee289f7c03a34d4cfec4c8
    $ make && ./python -m test -R 3:3 test_pprint 
    ...
    test_pprint leaked [4, 2, 4] memory blocks, sum=10
    ...

    The problem is that at each iteration of regrtest -R 3:3 (6 iterations), a few more code objects get this opcache allocated.

    There are different solutions to fix regrtest -R 3:3.

    (*) Always optimize:

    diff --git a/Python/ceval.c b/Python/ceval.c
    index 411ba3d73c..6cd148efba 100644
    --- a/Python/ceval.c
    +++ b/Python/ceval.c
    @@ -103,7 +103,7 @@ static long dxp[256];
     #endif
     
     /* per opcode cache */
    -#define OPCACHE_MIN_RUNS 1024  /* create opcache when code executed this time */
    +#define OPCACHE_MIN_RUNS 1  /* create opcache when code executed this time */
     #define OPCACHE_STATS 0  /* Enable stats */
     
     #if OPCACHE_STATS
    $ make && ./python -m test -R 3:3 test_pprint 
    ...
    Tests result: SUCCESS

    (*) Never optimmize: disable opcache until a better fix can be found

    diff --git a/Python/ceval.c b/Python/ceval.c
    index 411ba3d73c..3c85df6fea 100644
    --- a/Python/ceval.c
    +++ b/Python/ceval.c
    @@ -1230,6 +1230,7 @@ _PyEval_EvalFrameDefault(PyFrameObject *f, int throwflag)
         f->f_stacktop = NULL;       /* remains NULL unless yield suspends frame */
         f->f_executing = 1;
     
    +#if 0
         if (co->co_opcache_flag < OPCACHE_MIN_RUNS) {
             co->co_opcache_flag++;
             if (co->co_opcache_flag == OPCACHE_MIN_RUNS) {
    @@ -1244,6 +1245,7 @@ _PyEval_EvalFrameDefault(PyFrameObject *f, int throwflag)
     #endif
             }
         }
    +#endif
     
     #ifdef LLTRACE
         lltrace = _PyDict_GetItemId(f->f_globals, &PyId___ltrace__) != NULL;
    $ make && ./python -m test -R 3:3 test_pprint 
    ...
    Tests result: SUCCESS

    (*) Find a way to explicitly deoptimize all code objects

    Modules/gcmodule.c has a clear_freelists() function called by collect() if generation == NUM_GENERATIONS-1: on when gc.collect() is collected explicitly for example.

    Lib/test/libregrtest/refleak.py also has a dash_R_cleanup() function which clears many caches.

    Problem: currently, code objects are not explicitly tracked (for example, they are not tracked in a double linked list).

    (*) Add way more warmup iterations to regrtest in buildbots.

    I dislike this option. A build on a refleak buildbot worker already takes 2 to 3 hours. Adding more warmup would make a build even way more slower.

    @vstinner vstinner added interpreter-core (Objects, Python, Grammar, and Parser dirs) 3.8 only security fixes labels Jun 3, 2019
    @vstinner
    Copy link
    Member Author

    vstinner commented Jun 3, 2019

    New changeset eddef86 by Victor Stinner (Inada Naoki) in branch 'master':
    bpo-37146: disable opcache when Py_DEBUG is defined (GH-13787)
    eddef86

    @vstinner
    Copy link
    Member Author

    vstinner commented Jun 3, 2019

    INADA-san wrote PR 13787 to disable opcache when Python is compiled in debug mode. Pablo and me approved the change, so I merged it.

    Pablo wrote a more robust solution, PR 13789, to disable opcache only in regrtest, to look for memory leaks. But INADA-san had a good argument against this approach:
    #13789 (comment)

    "The code object will be optimized only when ++co->co_opcache_flag == opcacheminruns. So decreasing min_runs by _setopcacheminruns()will cause some hot codes will be not optimized forever. I don't want to expose such switch."

    I would prefer to keep this issue until a long term approach is designed.

    @vstinner
    Copy link
    Member Author

    vstinner commented Oct 1, 2019

    It seems like nobody came up with a solution for the debug mode since June. I close the issue. Reopen it if you would like to propose a solution.

    @vstinner vstinner closed this as completed Oct 1, 2019
    @1st1
    Copy link
    Member

    1st1 commented Oct 1, 2019

    It seems like nobody came up with a solution for the debug mode since June. I close the issue. Reopen it if you would like to propose a solution.

    I think the only solution is to have a flag to disable optimizations, inlcluding this one.

    @gvanrossum
    Copy link
    Member

    Please revert this and use a separate build flag (e.g. DISABLE_INLINE_CACHES) for the refleaks run. (Or perhaps provide an -X flag to disable it without the need to recompile.)

    I am developing new inline cache ideas and of course I need to run in debug mode, so I regularly end up wasting some time until I remember to add a patch that changes OPCACHE_MIN_RUNS back.

    @vstinner
    Copy link
    Member Author

    I reopen the issue (but I'm not interested by trying to fix it).

    @vstinner vstinner reopened this Feb 19, 2021
    @vstinner
    Copy link
    Member Author

    (Or perhaps provide an -X flag to disable it without the need to recompile.)

    Giving the ability to control the cache size, at least at Python startup, is one option.

    Or maybe need a generic -X flag to tell Python that libregrtest is tracking leaks, since we might need to change other parameters than only the opcode cache size.

    @1st1
    Copy link
    Member

    1st1 commented Feb 19, 2021

    Giving the ability to control the cache size, at least at Python startup, is one option.

    I'd really prefer not to allow users to control cache sizes. There's basically no point in that; the only practically useful thing is to enable or disable it.

    @pablogsal
    Copy link
    Member

    Or maybe need a generic -X flag to tell Python that libregrtest is tracking leaks, since we might need to change other parameters than only the opcode cache size.

    I think we should go this way, maybe even less "public". If we add a -X, then it will be too visible. Maybe some env variable?

    @webstarnantes
    Copy link
    Mannequin

    webstarnantes mannequin commented Feb 20, 2021

    dans cette version pour securité maximale

    SSLContext.wrap_socket()
    import socket
    import ssl
    
    hostname = 'www.python.org'
    context = ssl.create_default_context()
    
    with socket.create_connection((hostname, 443)) as sock:
        with context.wrap_socket(sock, server_hostname=hostname) as ssock:
            print(ssock.version())

    https://backlinkstrong.com/

    @webstarnantes webstarnantes mannequin added topic-SSL 3.9 only security fixes type-security A security issue and removed interpreter-core (Objects, Python, Grammar, and Parser dirs) 3.8 only security fixes labels Feb 20, 2021
    @webstarnantes webstarnantes mannequin changed the title opcode cache for LOAD_GLOBAL emits false alarm in memory leak hunting SSl Securité version 3.9.2 Feb 20, 2021
    @webstarnantes webstarnantes mannequin assigned tiran Feb 20, 2021
    @tiran tiran added interpreter-core (Objects, Python, Grammar, and Parser dirs) and removed topic-SSL labels Feb 20, 2021
    @tiran tiran changed the title SSl Securité version 3.9.2 opcode cache for LOAD_GLOBAL emits false alarm in memory leak hunting Feb 20, 2021
    @tiran tiran added type-bug An unexpected behavior, bug, or error and removed type-security A security issue labels Feb 20, 2021
    @pablogsal
    Copy link
    Member

    New changeset af5fa13 by Pablo Galindo in branch 'master':
    bpo-37146: Deactivate opcode cache only when using huntrleaks in the test suite (GH-24643)
    af5fa13

    @vstinner
    Copy link
    Member Author

    vstinner commented Mar 8, 2021

    New changeset 9f672a5 by Victor Stinner in branch 'master':
    bpo-37146: Move _PyEval_DeactivateOpCache() to the internal C API (GH-24786)
    9f672a5

    @ezio-melotti ezio-melotti transferred this issue from another repository Apr 10, 2022
    Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
    Labels
    3.9 only security fixes interpreter-core (Objects, Python, Grammar, and Parser dirs) type-bug An unexpected behavior, bug, or error
    Projects
    None yet
    Development

    No branches or pull requests

    5 participants