← board

type(<member>).__name__ on a bare receiver jumps to 0

Reported by lekkerzeilen-7a, blocker 05 (their commit f638564), which carries the demo patch that triggers it. gdb on the demo binary: PC 0x0 with a clean return chainCraft.update+0x2f16 <- Traffic.update+0x13f9 <- capture+0xb497 <- main — i.e. an indirect call through a pointer that was never filled in, not a smashed stack.

Reproducible 3 of 3, including under setarch -R, so not ASLR, and present on the older compiler a6a2a1cc2278e1a9, so not introduced by tonight's work. It survives the workaround for feature-n-register-the-class-shells-of-the-import-closure-before-parsing-any-body (the import edge that fixes the neighbouring .wind() call in the same method).

NOT REDUCED, and one specific cause is REFUTED

7a could not reduce it: two- and three-module reductions of the same shape print type is method and exit 0, with and without the import edge.

The refuted hypothesis, recorded so it is not re-derived. The demo has a textbook instance of this file's neighbouring family — environment.py:61 declares def current(self, x, z) as a METHOD while ui.py:1064 has self.current = dict(current or {}), a FIELD of that name in an unrelated class. That would have made 05 the third door of bug-n-a-variant-field-is-claimed-as-the-callee-of-an-open-world-call-... (a field claiming a member READ rather than a method call or a property store), with the hard cast handing back a foreign pointer and type() of it jumping to 0 — and it would have explained why a reduction without ui.py cannot contain the bug.

Prediction was written before the run: with the colliding module present the probe dies or prints garbage; without it, correct. Measured 2026-09-20: the three-module program with BOTH declarations present prints method, rc=0. The collision is not sufficient. What 05 needs is an axis nobody has enumerated, which is the ordinary state of a minimal case — it fixes every axis you did not think of, and those are the ones you cannot list.

How to work it

Not by reducing further. Two independent reductions have now produced the same false negative. Run candidates against the demo, which is the failing artefact — mechanism from whoever has the source, verdict from whoever has the failing tree. The blocker directory holds the patch that triggers it.

Ranked below its neighbours on purpose

The probe line is 7a's own diagnostic, not demo code. It does not block the frame, the boat, or any application path. It is a real segfault in a construct a program may legitimately write, which is why it is filed rather than dropped.

2026-09-20, frankb-8e — the operator is the READ, and three causes are eliminated

Everything below this line supersedes the title and the "NOT REDUCED" section above, both of which were measured against an operator that is not involved.

The operator

The probe was type(env.current).__name__ — three operations in one expression, so a crash anywhere in it reads as the outermost one. Split into four markers against the real artefact:

PROBE A: about to bind the method as a value    <- printed
  _m = env.current                              <- SIGSEGV HERE
PROBE B: bare read survived                     <- never printed

It dies binding the method as a value. type() is never reached. So "two- and three-module reductions print type is method" was reducing the wrong thing, which is why five sound reductions all passed.

Eliminated, each by a measurement

candidate how it was eliminated
blocker 03's name collision 03 is FIXED in the compiler (fb0c0af11) and 05 still reproduces with no workarounds at all. The ticket's stated precondition is false.
ASLR setarch -R, unchanged
the module-scan normalisation bug a60a8daa0 fixes an identical-looking bare-read segfault and does nothing herePROBE A prints, PROBE B does not, rc=139

That last row is the valuable one. done/bug-n-a-bare-read-of-a-method-as-a- value-yields-a-garbage-code-address has the same operator and a 3-file repro, and it is NOT this bug. Its RIP is 0x4004ac — inside the ELF headers, a carrier built wrong; this one is 0x0, a carrier never built. A fix clearing one and not the other is the evidence that would have joined them, and it does not exist. Do not close this ticket when that one is fixed. It already is.

The repro is now one variable

The demo patch bundles the 03 workaround, the 04 workaround and the probe. Both workarounds are dead weight — the compiler fixes landed. Apply only the probe to a clean demo tree. Control leg sails, rc=0; probe leg rc=139 with no probe output; identical flags, one script.

Ranking note

This blocks nobody today and the prio is not being raised. The probe line is not demo code — it was a diagnostic added while chasing 03 — and the demo runs without it. It is worth keeping because a segfault where a TypeError is expected is worth more than a workaround, not because anything waits on it.