GV

GeezerVison

The World Wide Web, restored to 800 pixels of glory.

Home|About|Gaming cabinet|Archives|How it works|Starter sites

On this site

  • Sign in
  • ActionsCI/CD and automation
  • CodespacesCloud development environments
  • All Features
  • Documentation
  • Training
  • Certifications
  • Build with Copilot
  • Customize Copilot
  • Integrations
  • Trending repos
  • GitHub Sponsors
  • Developer articles
  • Enterprises

This view

  • Original page
  • New address

GeezerVison is showing github.com — gh-125286: Share the Main Refchain With Legacy Interpreters by ericsnowcurrently · Pull Request #125709 · python/cpython

Conversation

@ericsnowcurrently

@ericsnowcurrently ericsnowcurrently commented Oct 18, 2024 •
edited by bedevere-app Bot
Loading

Uh oh!

There was an error while loading. Please reload this page.

Copy link
Copy Markdown
Member

They used to be shared, before 3.12. Returning to sharing them resolves a failure on Py_TRACE_REFS builds.

  • Issue: test_audit_subinterpreter crashes with tracerefs enabled #125286

Sorry, something went wrong.

Uh oh!

There was an error while loading. Please reload this page.

All reactions
@ericsnowcurrently
Share the main refchain with legacy interpreters.
53cfb82
@ericsnowcurrently ericsnowcurrently added the skip news label Oct 18, 2024
@bedevere-app bedevere-app Bot mentioned this pull request Oct 18, 2024
test_audit_subinterpreter crashes with tracerefs enabled #125286
Closed
@bedevere-app bedevere-app Bot added the awaiting core review label Oct 18, 2024
@ericsnowcurrently ericsnowcurrently mentioned this pull request Oct 18, 2024
gh-125286: Bug fix for trace-refs logic and shared objects #125314
Closed
@nascheme

nascheme commented Oct 18, 2024

Copy link
Copy Markdown
Member

Rather than open-code the Py_RTFLAGS_USE_MAIN_OBMALLOC flag test in multiple places, I think a helper function is better, something like:

#ifdef Py_TRACE_REFS
// Return true if interpreter should have it's own refchain table.  Otherwise
// the refchain from the main interpreter is shared.
static inline bool
has_own_refchain(PyInterpreterState *interp)
{
    return (_Py_IsMainInterpreter(interp) ||
            !(interp->feature_flags & Py_RTFLAGS_USE_MAIN_OBMALLOC));
}
#endif

I was working on a similar patch but my approach was to copy the REFCHAIN pointer, e.g.

PyStatus
_PyObject_InitState(PyInterpreterState *interp)
{
#ifdef Py_TRACE_REFS
    if (has_own_refchain(interp)) {
        _Py_hashtable_allocator_t alloc = {
            // Don't use default PyMem_Malloc() and PyMem_Free() which
            // require the caller to hold the GIL.
            .malloc = PyMem_RawMalloc,
            .free = PyMem_RawFree,
        };
        REFCHAIN(interp) = _Py_hashtable_new_full(
            _Py_hashtable_hash_ptr, _Py_hashtable_compare_direct,
            NULL, NULL, &alloc);
        if (REFCHAIN(interp) == NULL) {
            return _PyStatus_NO_MEMORY();
        }
    }
    else {
        PyInterpreterState *main_interp = _PyInterpreterState_Main();
        REFCHAIN(interp) = main_interp->object_state.refchain;
    }

#endif
    return _PyStatus_OK();
}

void
_PyObject_FiniState(PyInterpreterState *interp)
{
#ifdef Py_TRACE_REFS
    if (has_own_refchain(interp)) {
        _Py_hashtable_destroy(REFCHAIN(interp));
    }
    REFCHAIN(interp) = NULL;
#endif
}

Is _Py_NormalizeImmortalReference still required now? I would think it can be removed. Overall I think this is a good approach.

ericsnowcurrently reacted with thumbs up emoji
All reactions
  • 👍 1 reaction

Sorry, something went wrong.

Uh oh!

There was an error while loading. Please reload this page.

@ericsnowcurrently
Add a has_own_refchain() helper function.
b2bf609
@ericsnowcurrently

ericsnowcurrently commented Oct 18, 2024

Copy link
Copy Markdown
Member Author

I think a helper function is better

+1 I'll do that.

my approach was to copy the REFCHAIN pointer

I'm unclear on how that's different from what I've done.

Is _Py_NormalizeImmortalReference still required now? I would think it can be removed.

I left it for the sake of the sanity check. Given the lingering pain in this area, especially related to immortal objects, I figured it might not hurt to preserve such checks.

Overall I think this is a good approach.

Thanks! Sorry if we ended up duplicating effort. I should have checked with you first.

All reactions

Sorry, something went wrong.

Uh oh!

There was an error while loading. Please reload this page.

@nascheme

nascheme commented Oct 18, 2024

Copy link
Copy Markdown
Member

my approach was to copy the REFCHAIN pointer

I'm unclear on how that's different from what I've done.

I think it's a bit less code and would be a bit faster, since you can just use REFCHAIN() everywhere aside from the init/fini function. Since TraceRefs is has huge overhead anyhow I think it doesn't matter so it's just a code style decision. Your way works and you could argue that having the condition everytime you do something with the tracerefs is more clear.

Is _Py_NormalizeImmortalReference still required now? I would think it can be removed.

I left it for the sake of the sanity check. Given the lingering pain in this area, especially related to immortal objects, I figured it might not hurt to preserve such checks.

Hmm, I think it's a bit confusing to leave it since it really shouldn't be doing anything useful. Or, is there a reason we think it might do something? The second part of the function shouldn't do anything. If Py_RTFLAGS_USE_MAIN_OBMALLOC is set then both interpreters are using the same refchain hash table and you are adding/removing to the same table.

Overall I think this is a good approach.

Thanks! Sorry if we ended up duplicating effort. I should have checked with you first.

Your code runs without crashing, which is a plus. ;-) I'm glad you made a PR.

ericsnowcurrently reacted with thumbs up emoji
All reactions
  • 👍 1 reaction

Sorry, something went wrong.

Uh oh!

There was an error while loading. Please reload this page.

@nascheme

nascheme commented Oct 18, 2024

Copy link
Copy Markdown
Member

Oh, I missed this part of your code change:

REFCHAIN(interp) = REFCHAIN(main_interp);

That explains why you're unclear how my code is different. But if you do this in the init, I don't think the check for Py_RTFLAGS_USE_MAIN_OBMALLOC is needed elsewhere, you can just use REFCHAIN(interp) when you need to add or remove objects to the hash table.

All reactions

Sorry, something went wrong.

Uh oh!

There was an error while loading. Please reload this page.

@ericsnowcurrently

ericsnowcurrently commented Oct 21, 2024

Copy link
Copy Markdown
Member Author

I don't think the check for Py_RTFLAGS_USE_MAIN_OBMALLOC is needed elsewhere, you can just use REFCHAIN(interp) when you need to add or remove objects to the hash table.

Good point. I'll remove the superfluous calls.

All reactions

Sorry, something went wrong.

Uh oh!

There was an error while loading. Please reload this page.

@ericsnowcurrently

ericsnowcurrently commented Oct 21, 2024

Copy link
Copy Markdown
Member Author

Also, you're right about _Py_NormalizeImmortalReference(). I'll drop it.

All reactions

Sorry, something went wrong.

Uh oh!

There was an error while loading. Please reload this page.

ericsnowcurrently added 5 commits October 21, 2024 15:41
@ericsnowcurrently
Drop _Py_NormalizeImmortalReference().
203c112
@ericsnowcurrently
Drop has_own_refchain() calls where not needed.
ffe2633
@ericsnowcurrently
Call _PyObject_InitState() *after* computing the feature flags.
8d52258
@ericsnowcurrently
Revert "Call _PyObject_InitState() *after* computing the feature flags."
216dde2
This reverts commit 8d52258.
@ericsnowcurrently
Revert "Drop has_own_refchain() calls where not needed."
fbc4e2d
This reverts commit ffe2633.
@ericsnowcurrently

ericsnowcurrently commented Oct 21, 2024

Copy link
Copy Markdown
Member Author

I realized the problem with dropping all the extra has_own_refchain() sites. Here are the key steps of what we do currently:

  1. Py_NewInterpreterFromConfig(): calls _PyInterpreterState_New()
  2. _PyInterpreterState_New(): calls _PyObject_InitState()
  3. _PyObject_InitState(): sets the interpreter's refchain depending on interp->feature_flags
  4. _PyInterpreterState_New(): calls other initializers that create objects, which add to the refchain
  5. Py_NewInterpreterFromConfig(): sets interp->feature_flags

At step (3) we rely on the feature flags being set, but we don't set them until step (5).

Fixing this is a bit messy and may be too much to backport, so I'd like to merge this fix with the various has_own_refchain() calls in place (sort of), and then tackle the rest in a separate PR. It's not that simple, but you'll see what I mean.

All reactions

Sorry, something went wrong.

Uh oh!

There was an error while loading. Please reload this page.

ericsnowcurrently added 5 commits October 21, 2024 17:02
@ericsnowcurrently
has_own_refchain() -> maybe_fix_refchain()
cb06847
@ericsnowcurrently
Handle late runtime fini correctly.
7aa33a9
@ericsnowcurrently
Pass the interpreter config to init_interpreter().
3421a19
@ericsnowcurrently
Revert "Pass the interpreter config to init_interpreter()."
b276454
This reverts commit 3421a19.
@ericsnowcurrently
Move the _PyObject_InitState() call out of init_interpreter().
7ab086c
@ericsnowcurrently

ericsnowcurrently commented Oct 22, 2024

Copy link
Copy Markdown
Member Author

It wasn't as bad as I thought, so I believe I've got things in a good place here.

nascheme reacted with thumbs up emoji
All reactions
  • 👍 1 reaction

Sorry, something went wrong.

Uh oh!

There was an error while loading. Please reload this page.

@ericsnowcurrently

ericsnowcurrently commented Oct 22, 2024

Copy link
Copy Markdown
Member Author

!buildbot AMD64 Arch Linux TraceRefs

All reactions

Sorry, something went wrong.

Uh oh!

There was an error while loading. Please reload this page.

@bedevere-bot

bedevere-bot commented Oct 22, 2024

Copy link
Copy Markdown

🤖 New build scheduled with the buildbot fleet by @ericsnowcurrently for commit 7ab086c 🤖

The command will test the builders whose names match following regular expression: AMD64 Arch Linux TraceRefs

The builders matched are:

  • AMD64 Arch Linux TraceRefs PR
All reactions

Sorry, something went wrong.

Uh oh!

There was an error while loading. Please reload this page.

@encukou

encukou commented Oct 22, 2024

Copy link
Copy Markdown
Member

I think this change should have a What's New entry, which in turn needs documentation for sys.getobjects: ericsnowcurrently#39

All reactions

Sorry, something went wrong.

Uh oh!

There was an error while loading. Please reload this page.

@ericsnowcurrently

ericsnowcurrently commented Oct 22, 2024

Copy link
Copy Markdown
Member Author

I'm fine with that.

All reactions

Sorry, something went wrong.

Uh oh!

There was an error while loading. Please reload this page.

encukou and others added 2 commits October 22, 2024 14:32
@encukou @ericsnowcurrently
Add docs and a What's New entry
9d539f6
@ericsnowcurrently
Fix typos.
d80fe6a
@ericsnowcurrently
Do not try to destroy the refchain if it is NULL.
1360d86
@ericsnowcurrently

ericsnowcurrently commented Oct 22, 2024

Copy link
Copy Markdown
Member Author

!buildbot AMD64 Arch Linux TraceRefs

All reactions

Sorry, something went wrong.

Uh oh!

There was an error while loading. Please reload this page.

@bedevere-bot

bedevere-bot commented Oct 22, 2024

Copy link
Copy Markdown

🤖 New build scheduled with the buildbot fleet by @ericsnowcurrently for commit 1360d86 🤖

The command will test the builders whose names match following regular expression: AMD64 Arch Linux TraceRefs

The builders matched are:

  • AMD64 Arch Linux TraceRefs PR
All reactions

Sorry, something went wrong.

Uh oh!

There was an error while loading. Please reload this page.

@encukou
Docs: Link to the new sys.getobjects() docs
090b528
@encukou
encukou requested review from corona10 and erlend-aasland as code owners October 23, 2024 07:52
@encukou

encukou commented Oct 23, 2024

Copy link
Copy Markdown
Member

One more doc fix in a place where I couldn't add a GitHub suggestion. I hope you don't mind me pushing this directly to the PR.

The AMD64 Arch Linux TraceRefs PR buildbot run succeded: https://buildbot.python.org/#/builders/82/builds/1457

ericsnowcurrently reacted with thumbs up emoji
All reactions
  • 👍 1 reaction

Sorry, something went wrong.

Uh oh!

There was an error while loading. Please reload this page.

encukou
encukou approved these changes Oct 23, 2024
View reviewed changes

@encukou encukou left a comment

Copy link
Copy Markdown
Member

There was a problem hiding this comment.

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This looks great! Thank you @nascheme & @ericsnowcurrently!

Sorry, something went wrong.

Uh oh!

There was an error while loading. Please reload this page.

All reactions
@bedevere-app bedevere-app Bot added awaiting merge and removed awaiting core review labels Oct 23, 2024
@ericsnowcurrently
ericsnowcurrently merged commit 6f26d49 into python:main Oct 23, 2024
@bedevere-app bedevere-app Bot removed the awaiting merge label Oct 23, 2024
@ericsnowcurrently
ericsnowcurrently deleted the legacy-shared-refchain branch October 23, 2024 16:10
@ericsnowcurrently

ericsnowcurrently commented Oct 23, 2024

Copy link
Copy Markdown
Member Author

@nascheme, this should be backported to 3.13 (and 3.12), right?

All reactions

Sorry, something went wrong.

Uh oh!

There was an error while loading. Please reload this page.

@nascheme

nascheme commented Oct 23, 2024

Copy link
Copy Markdown
Member

For 3.12, this fix applies on top of GH-125205, which is not yet merged. For 3.13, GH-125204 is also not yet merged.

ericsnowcurrently reacted with thumbs up emoji
All reactions
  • 👍 1 reaction

Sorry, something went wrong.

Uh oh!

There was an error while loading. Please reload this page.

This was referenced Oct 23, 2024
[3.12] gh-116510: Fix a Crash Due to Shared Immortal Interned Strings (gh-124865) #125205
Merged
[3.13] gh-116510: Fix a Crash Due to Shared Immortal Interned Strings (gh-124865) #125204
Merged
encukou pushed a commit to miss-islington/cpython that referenced this pull request Nov 1, 2024
@ericsnowcurrently @encukou
[3.13] pythongh-125286: Share the Main Refchain With Legacy Interpret…
909f70e
…ers (pythongh-125709)

They used to be shared, before 3.12.  Returning to sharing them resolves a failure on Py_TRACE_REFS builds.
encukou pushed a commit that referenced this pull request Nov 12, 2024
@miss-islington @ericsnowcurrently
[3.13] gh-116510: Fix a Crash Due to Shared Immortal Interned Strings (…
02cd3ce
…gh-124865) (gh-125709) (GH-125204)

* gh-116510: Fix a Crash Due to Shared Immortal Interned Strings (gh-124865)

Fix a crash caused by immortal interned strings being shared between
sub-interpreters that use basic single-phase init. In that case, the string
can be used by an interpreter that outlives the interpreter that created and
interned it. For interpreters that share obmalloc state, also share the
interned dict with the main interpreter.

This is an un-revert of gh-124646 that then addresses the Py_TRACE_REFS
failures identified by gh-124785.
(cherry picked from commit f2cb399)

Co-authored-by: Eric Snow <[email protected]>

* [3.13] gh-125286: Share the Main Refchain With Legacy Interpreters (gh-125709)

They used to be shared, before 3.12.  Returning to sharing them resolves a failure on Py_TRACE_REFS builds.

---------

Co-authored-by: Eric Snow <[email protected]>
encukou pushed a commit to miss-islington/cpython that referenced this pull request Nov 13, 2024
@ericsnowcurrently @encukou
[3.12] pythongh-125286: Share the Main Refchain With Legacy Interpret…
cdb58a7
…ers (pythongh-125709)

They used to be shared, before 3.12.  Returning to sharing them resolves a failure on Py_TRACE_REFS builds.
ericsnowcurrently added a commit that referenced this pull request Dec 3, 2024
@miss-islington @ericsnowcurrently
[3.12] gh-116510: Fix a Crash Due to Shared Immortal Interned Strings (…
49da170
…gh-125205)

Fix a crash caused by immortal interned strings being shared between
sub-interpreters that use basic single-phase init. In that case, the string
can be used by an interpreter that outlives the interpreter that created and
interned it. For interpreters that share obmalloc state, also share the
interned dict with the main interpreter.

This is an un-revert of gh-124646 that then addresses the Py_TRACE_REFS
failures identified by gh-124785 (i.e. backporting gh-125709 too).

(cherry picked from commit f2cb399, AKA gh-124865)

Co-authored-by: Eric Snow <[email protected]>
ebonnal pushed a commit to ebonnal/cpython that referenced this pull request Jan 12, 2025
@ericsnowcurrently @encukou @ebonnal
pythongh-125286: Share the Main Refchain With Legacy Interpreters (py…
3135506
…thongh-125709)

They used to be shared, before 3.12.  Returning to sharing them resolves a failure on Py_TRACE_REFS builds.

Co-authored-by: Petr Viktorin <[email protected]>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Reviewers

@encukou encukou encukou approved these changes
@erlend-aasland erlend-aasland Awaiting requested review from erlend-aasland erlend-aasland is a code owner
@corona10 corona10 Awaiting requested review from corona10 corona10 is a code owner

Uh oh!

There was an error while loading. Please reload this page.

Assignees

No one assigned

Labels

skip news

Projects

None yet

Milestone

No milestone

Development

Successfully merging this pull request may close these issues.

Uh oh!

There was an error while loading. Please reload this page.

4 participants

@ericsnowcurrently @nascheme @bedevere-bot @encukou
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
You are visitor 01402503 — GeezerVison does not store the pages you look up.
Best viewed with Netscape Navigator 4.7 or Internet Explorer 6 at 800×600. No cookies required.