You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
Repository navigation
Error side tables key on the MESSAGE string's address but rekey by the ERROR's address — ERR_* code/syscall/errno/path dropped when the message relocates #9530
Pre-existing bug uncovered while regression-testing PR #9521's exception.rs reorder (a forced minor GC reproduces it; not fixed there).
The asymmetry
register_error_code_pub / error_code_for_message key their side tables on the message StringHeader address. The GC's GcMoveHookKind::ErrorSideTables rekey fires for the error object's address. Nothing rekeys the message-keyed entries — so the moment an error's message string is relocated by an evacuating scavenge, its ERR_* code, syscall, errno, path, dest and hostname are silently dropped.
User-visible shape: an fs/net error that was constructed with a full node-style code loses it before it is reported — err.code === undefined where node has "ENOENT", and the uncaught-error report prints without the code. Timing-dependent (needs a scavenge between construction and read), which is exactly the class of bug this campaign keeps finding behind "flaky" symptoms.
Fix shape
Either key the side tables by the error object's address (so the existing ErrorSideTables rekey covers them — check why the message was chosen; there may be construction-order reasons), or add the message key to the rekey hook. The first is structurally better: one rekey path instead of two that can drift.
Verification bar
Reproduced already with an explicit gc_collect_minor() between construction and read — that harness shape (from PR #9521's test work) is the starting point, with the positive control that the string actually moved (assert_ne!(before, after)); a test whose forced collection moves nothing passes on broken code, which was demonstrated on this exact machinery. Cover: err.code read after GC, the uncaught-error report path, and a node-shaped fs error (ENOENT with path) round-tripping through util.inspect.
Evidence and the two documented dead-end harness attempts: PR #9521's uncaught_native_error_report test comments.
Activity