Bug 18691 – assigning a std.regex.Captures with 3 or more groups causes double free
Status
RESOLVED
Resolution
FIXED
Severity
regression
Priority
P1
Component
phobos
Product
D
Version
D2
Platform
x86_64
OS
Linux
Creation time
2018-03-29T02:00:44Z
Last change time
2018-04-06T19:37:11Z
Keywords
pull
Assigned to
No Owner
Creator
Martin Dorey
Comments
Comment #0 by martin.dorey — 2018-03-29T02:00:44Z
This minimal test case crashes:
martind@swiftboat:~/tmp/D134366$ cat utilimal.d
import std.regex;
void main() {
auto rx = regex("()()()");
auto ma = "".matchFirst(rx);
ma = "".matchFirst(rx);
}
martind@swiftboat:~/tmp/D134366$ ~/download/d/dmd/generated/linux/release/64/dmd -g utilimal.d && valgrind ./utilimal
...
==655== Invalid free() / delete / delete[] / realloc()
==655== at 0x4C29E90: free (vg_replace_malloc.c:473)
==655== by 0x4C1E26: _D3std5regex__T8CapturesTAyaZQo6__dtorMFNbNiNeZv (/home/martind/download/d/dmd/generated/linux/release/64/../../../../../phobos/std/regex/package.d:565)
==655== by 0x48A1CB: _Dmain (utilimal.d:5)
==655== by 0x4C6F5F: _D2rt6dmain211_d_run_mainUiPPaPUAAaZiZ6runAllMFZ9__lambda1MFZv (in /home/martind/tmp/D134366/utilimal)
==655== by 0x4C6DEF: _D2rt6dmain211_d_run_mainUiPPaPUAAaZiZ7tryExecMFMDFZvZv (in /home/martind/tmp/D134366/utilimal)
==655== by 0x4C6ECE: _D2rt6dmain211_d_run_mainUiPPaPUAAaZiZ6runAllMFZv (in /home/martind/tmp/D134366/utilimal)
==655== by 0x4C6DEF: _D2rt6dmain211_d_run_mainUiPPaPUAAaZiZ7tryExecMFMDFZvZv (in /home/martind/tmp/D134366/utilimal)
==655== by 0x4C6D5A: _d_run_main (in /home/martind/tmp/D134366/utilimal)
==655== by 0x4C303D: main (in /home/martind/tmp/D134366/utilimal)
==655== Address 0x5d2be50 is 0 bytes inside a block of size 64 free'd
==655== at 0x4C29E90: free (vg_replace_malloc.c:473)
==655== by 0x4C1E26: _D3std5regex__T8CapturesTAyaZQo6__dtorMFNbNiNeZv (/home/martind/download/d/dmd/generated/linux/release/64/../../../../../phobos/std/regex/package.d:565)
==655== by 0x4C2D2F: _D3std5regex__T8CapturesTAyaZQo__T8opAssignZQkMFNbNiNeSQCbQCa__TQBxTQBrZQCfZQw (/home/martind/download/d/dmd/generated/linux/release/64/../../../../../phobos/std/regex/package.d:685)
==655== by 0x48A181: _Dmain (utilimal.d:6)
==655== by 0x4C6F5F: _D2rt6dmain211_d_run_mainUiPPaPUAAaZiZ6runAllMFZ9__lambda1MFZv (in /home/martind/tmp/D134366/utilimal)
==655== by 0x4C6DEF: _D2rt6dmain211_d_run_mainUiPPaPUAAaZiZ7tryExecMFMDFZvZv (in /home/martind/tmp/D134366/utilimal)
==655== by 0x4C6ECE: _D2rt6dmain211_d_run_mainUiPPaPUAAaZiZ6runAllMFZv (in /home/martind/tmp/D134366/utilimal)
==655== by 0x4C6DEF: _D2rt6dmain211_d_run_mainUiPPaPUAAaZiZ7tryExecMFMDFZvZv (in /home/martind/tmp/D134366/utilimal)
==655== by 0x4C6D5A: _d_run_main (in /home/martind/tmp/D134366/utilimal)
==655== by 0x4C303D: main (in /home/martind/tmp/D134366/utilimal)
My testing suggests that this is a regression in 2.079.0 over 2.078.3-0. I might risk a guess that it's due to the addition of opAssign to the Captures struct in:
https://github.com/dlang/phobos/commit/59520969ef73eaf0691972ee00b389e5bbc4c8fb#diff-4715499b2ff2d74e4eb3c6f3909c611c in an attempt by @MartinNowak to "fix Issue 18114 - regex performance regression". Do we now have big_matches in two Captures objects referring to the same calloc/free memory but each with their own _refcount? Have we also leaked any old memory that (lhs) big_matches owned?
Comment #1 by greensunny12 — 2018-03-29T02:23:32Z
I can't reproduce the crash neither with 2.079 nor with master (in valgrind too).
And the same for run.dlang.io: https://run.dlang.io/is/2ncpH0
Is there anything specific about your setup?
Comment #2 by martin.dorey — 2018-03-29T04:23:52Z
How frustrating. I can reproduce it on every one of the three machines I've tried. The output I raised the issue with was from today's master built on Debian Jessie. I found the problem originally on stock 2.079-0 from d-apt on Debian Stretch... like the one below. I was hoping for more symbolic debugging but the -g doesn't seem to affect it for me.
mad@shuttle:~/tmp/D134366$ dmd --version
DMD64 D Compiler v2.079.0
Copyright (C) 1999-2018 by The D Language Foundation, All Rights Reserved written by Walter Bright
mad@shuttle:~/tmp/D134366$ dmd -g utilimal.d && ./utilimal
*** Error in `./utilimal': double free or corruption (fasttop): 0x0000563fea6ca140 ***
======= Backtrace: =========
/lib/x86_64-linux-gnu/libc.so.6(+0x70bcb)[0x7f8c10084bcb]
/lib/x86_64-linux-gnu/libc.so.6(+0x76f96)[0x7f8c1008af96]
/lib/x86_64-linux-gnu/libc.so.6(+0x777de)[0x7f8c1008b7de]
./utilimal(_D3std5regex__T8CapturesTAyaZQo6__dtorMFNbNiNeZv+0x3b)[0x563fe94fda3f]
./utilimal(_Dmain+0xfd)[0x563fe94c6ea9]
./utilimal(_D2rt6dmain211_d_run_mainUiPPaPUAAaZiZ6runAllMFZ9__lambda1MFZv+0x28)[0x563fe9502b88]
./utilimal(_D2rt6dmain211_d_run_mainUiPPaPUAAaZiZ7tryExecMFMDFZvZv+0x20)[0x563fe9502a18]
./utilimal(_D2rt6dmain211_d_run_mainUiPPaPUAAaZiZ6runAllMFZv+0x8b)[0x563fe9502af7]
./utilimal(_D2rt6dmain211_d_run_mainUiPPaPUAAaZiZ7tryExecMFMDFZvZv+0x20)[0x563fe9502a18]
./utilimal(_d_run_main+0x1cf)[0x563fe9502983]
./utilimal(main+0x22)[0x563fe94febd6]
/lib/x86_64-linux-gnu/libc.so.6(__libc_start_main+0xf1)[0x7f8c100342b1]
./utilimal(_start+0x2a)[0x563fe94c6c2a]
======= Memory map: ========
563fe9426000-563fe9569000 r-xp 00000000 08:07 76285143 /u2/home/mad/tmp/D134366/utilimal
563fe9769000-563fe976a000 r--p 00143000 08:07 76285143 /u2/home/mad/tmp/D134366/utilimal
563fe976a000-563fe979f000 rw-p 00144000 08:07 76285143 /u2/home/mad/tmp/D134366/utilimal
563fea6ca000-563fea6eb000 rw-p 00000000 00:00 0 [heap]
7f8c0c000000-7f8c0c021000 rw-p 00000000 00:00 0
7f8c0c021000-7f8c10000000 ---p 00000000 00:00 0
7f8c10014000-7f8c101a9000 r-xp 00000000 08:01 1859659 /lib/x86_64-linux-gnu/libc-2.24.so
7f8c101a9000-7f8c103a9000 ---p 00195000 08:01 1859659 /lib/x86_64-linux-gnu/libc-2.24.so
7f8c103a9000-7f8c103ad000 r--p 00195000 08:01 1859659 /lib/x86_64-linux-gnu/libc-2.24.so
7f8c103ad000-7f8c103af000 rw-p 00199000 08:01 1859659 /lib/x86_64-linux-gnu/libc-2.24.so
7f8c103af000-7f8c103b3000 rw-p 00000000 00:00 0
7f8c103b3000-7f8c103c9000 r-xp 00000000 08:01 1859854 /lib/x86_64-linux-gnu/libgcc_s.so.1
7f8c103c9000-7f8c105c8000 ---p 00016000 08:01 1859854 /lib/x86_64-linux-gnu/libgcc_s.so.1
7f8c105c8000-7f8c105c9000 r--p 00015000 08:01 1859854 /lib/x86_64-linux-gnu/libgcc_s.so.1
7f8c105c9000-7f8c105ca000 rw-p 00016000 08:01 1859854 /lib/x86_64-linux-gnu/libgcc_s.so.1
7f8c105ca000-7f8c105cd000 r-xp 00000000 08:01 1859704 /lib/x86_64-linux-gnu/libdl-2.24.so
7f8c105cd000-7f8c107cc000 ---p 00003000 08:01 1859704 /lib/x86_64-linux-gnu/libdl-2.24.so
7f8c107cc000-7f8c107cd000 r--p 00002000 08:01 1859704 /lib/x86_64-linux-gnu/libdl-2.24.so
7f8c107cd000-7f8c107ce000 rw-p 00003000 08:01 1859704 /lib/x86_64-linux-gnu/libdl-2.24.so
7f8c107ce000-7f8c107d5000 r-xp 00000000 08:01 1859828 /lib/x86_64-linux-gnu/librt-2.24.so
7f8c107d5000-7f8c109d4000 ---p 00007000 08:01 1859828 /lib/x86_64-linux-gnu/librt-2.24.so
7f8c109d4000-7f8c109d5000 r--p 00006000 08:01 1859828 /lib/x86_64-linux-gnu/librt-2.24.so
7f8c109d5000-7f8c109d6000 rw-p 00007000 08:01 1859828 /lib/x86_64-linux-gnu/librt-2.24.so
7f8c109d6000-7f8c10ad9000 r-xp 00000000 08:01 1859707 /lib/x86_64-linux-gnu/libm-2.24.so
7f8c10ad9000-7f8c10cd8000 ---p 00103000 08:01 1859707 /lib/x86_64-linux-gnu/libm-2.24.so
7f8c10cd8000-7f8c10cd9000 r--p 00102000 08:01 1859707 /lib/x86_64-linux-gnu/libm-2.24.so
7f8c10cd9000-7f8c10cda000 rw-p 00103000 08:01 1859707 /lib/x86_64-linux-gnu/libm-2.24.so
7f8c10cda000-7f8c10cf2000 r-xp 00000000 08:01 1859816 /lib/x86_64-linux-gnu/libpthread-2.24.so
7f8c10cf2000-7f8c10ef1000 ---p 00018000 08:01 1859816 /lib/x86_64-linux-gnu/libpthread-2.24.so
7f8c10ef1000-7f8c10ef2000 r--p 00017000 08:01 1859816 /lib/x86_64-linux-gnu/libpthread-2.24.so
7f8c10ef2000-7f8c10ef3000 rw-p 00018000 08:01 1859816 /lib/x86_64-linux-gnu/libpthread-2.24.so
7f8c10ef3000-7f8c10ef7000 rw-p 00000000 00:00 0
7f8c10ef7000-7f8c10f1a000 r-xp 00000000 08:01 1859630 /lib/x86_64-linux-gnu/ld-2.24.so
7f8c10fe6000-7f8c110eb000 rw-p 00000000 00:00 0
7f8c11116000-7f8c1111a000 rw-p 00000000 00:00 0
7f8c1111a000-7f8c1111b000 r--p 00023000 08:01 1859630 /lib/x86_64-linux-gnu/ld-2.24.so
7f8c1111b000-7f8c1111c000 rw-p 00024000 08:01 1859630 /lib/x86_64-linux-gnu/ld-2.24.so
7f8c1111c000-7f8c1111d000 rw-p 00000000 00:00 0
7ffe6f231000-7ffe6f252000 rw-p 00000000 00:00 0 [stack]
7ffe6f3f4000-7ffe6f3f6000 r--p 00000000 00:00 0 [vvar]
7ffe6f3f6000-7ffe6f3f8000 r-xp 00000000 00:00 0 [vdso]
ffffffffff600000-ffffffffff601000 r-xp 00000000 00:00 0 [vsyscall]
Aborted
mad@shuttle:~/tmp/D134366$
Perhaps Debian's libc has more debugging configured than others but surely valgrind ought to behave roughly the same:
mad@shuttle:~/tmp/D134366$ valgrind --version
valgrind-3.12.0.SVN
mad@shuttle:~/tmp/D134366$
Comment #3 by martin.dorey — 2018-03-29T06:24:34Z
If you're interested in this bug, then you're likely to also be interested in:
Issue 18692: assignment of std.regex.Captures reads freed memory from 2.072.0 to 2.078.3 inclusive
Comment #4 by dmitry.olsh — 2018-03-29T12:04:33Z
*** Issue 18692 has been marked as a duplicate of this issue. ***
Comment #5 by dmitry.olsh — 2018-03-29T12:05:19Z
This is the same issue - bogus CoW implementation.
PR is out
Comment #6 by github-bugzilla — 2018-04-06T19:37:10Z