Skip Menu |
Report information
Id: 131870
Status: new
Priority: 0/
Queue: perl6

Owner: Nobody
Requestors: smls75 [at]

Severity: (no value)
Tag: (no value)
Platform: (no value)
Patch Status: (no value)
VM: (no value)

Date: Wed, 9 Aug 2017 21:29:24 +0200
To: Rakudo Bugtracker <rakudobug [...]>
From: Sam S <smls75 [...]>
Subject: [CONC] Capture lookup inside regexes is not threadsafe
Download (untitled) / with headers
text/plain 1.6k
When the same regex is used concurrently from multiple `start` threads, looking up already matched captures like $0 or $<foo> from an embedded code block *inside* that regex is unreliable: ➜ await do for ^10 -> $i { start { "A".match: /(“A”) { say "BOOM: $i) ", $0 if not $0 }/ } } BOOM: 2) Nil BOOM: 4) Nil BOOM: 2) 「A」 BOOM: 3) 「A」 BOOM: 6) Nil That example shouldn't print anything, because `$0` should always be a truthy `Match` object after the `(“A”)`. But in practice, it demonstrates the incorrect behavior shown above on most runs: *Some* iterations (different ones each time) seem to see `$0` as `Nil` or as a falsy `Match`. Additional failure modes that occur more rarely: - "Type check failed in binding to parameter '<anon>';" error - hanging indefinitely Increase the `^10` to `^1000` or so to guarantee failure. --- Bisect finds: However: ‎ ‎ <‎Zoffix‎>‎ It's not a regression tho ‎ ‎<‎Zoffix‎>‎ Or maybe it is. ‎ ‎<‎Zoffix‎>‎ It's just before that commit, it looks like the $/ was shared around, so it wasn't necesarily "not $0" ‎ ‎<‎Zoffix‎>‎ c: 08e39ee2653b1ae^ await ^100 .map: -> $i { $/ = 42; start { "$i".match: /(\d+)/; if $i != +$0 { say "Boom: $i $0" } } } ‎ ‎<‎committable6‎>‎ Zoffix, ‎ ‎<‎Zoffix‎>‎ Yup. --- This is Rakudo version 2017.07-136-gda4a0f50a built on MoarVM version 2017.07-318-g604da4d0 implementing Perl 6.c.
Download (untitled) / with headers
text/plain 263b
Also notable is that multiple iterations somehow see the same value for `$i` (as observed in the output listing above). I've sumbitted a separate issue for that (RT #131871), because the Capture-lookup bug of the current issue occurs even when removing the `$i`.
Download (untitled) / with headers
text/plain 466b
Heh, on further thought, they may be the same issue after all. In `/(...) { ... $i ... $0 ... }`, both the $i and the $0 (or $/ rather) are outer lexicals from the point of view of the curly block, right? So it might be a general problem with the way that *code blocks inside regexes* access outer lexicals. (It doesn't happen with code blocks *outside* of regexes, and as the other ticket demonstrates, also doesn't happen inside the regex-portion of regexes.)

This service is sponsored and maintained by Best Practical Solutions and runs on infrastructure.

For issues related to this RT instance (aka "perlbug"), please contact perlbug-admin at