docs(D-W6.6): precise Class::MOP failure stack — Try::Tiny + _post_add_attribute#610
Open
docs(D-W6.6): precise Class::MOP failure stack — Try::Tiny + _post_add_attribute#610
Conversation
…dd_attribute
A `$SIG{__DIE__}` probe before `use Class::MOP` (gate disabled)
captured the exact failure stack:
main::__ANON__ at .../Try/Tiny.pm:139
(eval) at .../Try/Tiny.pm:140
Try::Tiny::try at .../Class/MOP/Class.pm:897
Class::MOP::Class::_post_add_attribute
at .../Class/MOP/Mixin/HasAttributes.pm:41
Class::MOP::Mixin::HasAttributes::add_attribute
at .../Class/MOP.pm:188
The chain: bootstrap calls `HasMethods->meta->add_attribute(...)`
with a HASH-form `reader => { name => CV }`. Inside `add_attribute`,
`_attach_attribute` weakens the back-ref, then `_post_add_attribute`
runs a `try { install_accessors } catch { remove_attribute; die }`.
`install_accessors` dies first because `$self->associated_class`
reads as undef. The catch tries `remove_attribute` which does
`$attr->associated_class()` — also undef — and produces the visible
"Can't call method 'get_method' on an undefined value" at line 475.
The first die is hidden by Try::Tiny's `local $SIG{__DIE__}`.
Adds reproducer src/test/resources/unit/refcount/drift/cmop_add_attr_loop.t
that exercises this exact shape. Both Perl 5 and PerlOnJava (gate
disabled) pass it — so the bug requires the *recursive* bootstrap
where `HasMethods->meta` is itself a Class::MOP::Class with a
multi-level @isa chain currently being built up.
Documents the next probe in moose_support.md: a Perl-side
`$SIG{__DIE__}` that prints `associated_class // UNDEF` immediately
before each die, to identify the specific scope-exit that took the
metaclass refCount to 0.
Generated with [Devin](https://cli.devin.ai/docs)
Co-Authored-By: Devin <158243242+devin-ai-integration[bot]@users.noreply.github.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
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.
Summary
D-W6.6 narrows the
Class::MOPdrift failure to the exact line in_post_add_attribute— and shows that the visible error is a CASCADEcaught by Try::Tiny.
What the failure stack actually shows
A
$SIG{__DIE__}probe beforeuse Class::MOP(gate disabled)captures:
So the bootstrap chain is:
The visible error ("Can't call method 'get_method' on an undefined
value at Attribute.pm line 475") is the SECOND failure — the catch
block's call to
remove_attribute → remove_accessors. The first dieis hidden by Try::Tiny's
local $SIG{__DIE__}.What landed
src/test/resources/unit/refcount/drift/cmop_add_attr_loop.t—the exact shape: 11 iterations of
_attach_attribute→_attribute_mapinsert →_post_add_attributewith HASH-formreader. Both Perl 5 and PerlOnJava (gate disabled) pass.try_tiny_weak.t— Try::Tiny + weakened back-ref alone(4 patterns). Pass.
So the simple shape isn't enough. The bug requires the recursive
bootstrap where
HasMethods->metais itself a Class::MOP::Classwith a multi-level
@ISAchain (Module, HasAttributes, HasMethods,HasOverloads) currently being built up.
Next concrete probe
A
$SIG{__DIE__}Perl-side probe that prints$self->associated_class // 'UNDEF'immediately before each die.The first die where
associated_classis'UNDEF'reveals theexact LAST PRIOR refCount-decrement step that took the metaclass to
0. That decrement's stack identifies the specific
linearized_isa/_method_maptraversal insideinstall_accessorsthat loses themetaclass strong hold during the partial-build state.
Test plan
make(build + unit tests) green.cmop_add_attr_loop.tpasses on master.cmop_add_attr_loop.tpasses with the gate disabled.try_tiny_weak.tpasses both ways.Open D-W6 PR backlog (cumulative)
feature/moose-phase-d-v2fix/d-w6-1-sub-install-driftfix/d-w6-2-closure-capture-driftfix/d-w6-4-pending-double-addfix/d-w6-pending-instrumentationfix/d-w6-function-hash-storefix/d-w6-bisect-cmopGenerated with Devin
Co-Authored-By: Devin <158243242+devin-ai-integration[bot]@users.noreply.github.com>