Bug 20862 – Segfault on repeated GC.qalloc calls

Status
RESOLVED
Resolution
INVALID
Severity
major
Priority
P1
Component
druntime
Product
D
Version
D2
Platform
x86_64
OS
All
Creation time
2020-05-24T19:51:20Z
Last change time
2020-07-07T13:55:25Z
Assigned to
No Owner
Creator
moonlightsentinel

Comments

Comment #0 by moonlightsentinel — 2020-05-24T19:51:20Z
The following code causes a segfault in the GC (tested on 2.092.0): =================================================== void main() { import core.memory; string[] arr; foreach (_; 0 .. 3) // first two iterations pass { immutable len = arr.length; auto bi = GC.qalloc(string.sizeof); arr = (cast(string*) bi.base)[0 .. len]; arr = arr.ptr[0 .. len + 1]; arr[] = []; } } =================================================== gdb: Program received signal SIGSEGV, Segmentation fault. 0x0000000008067be6 in _D2gc4impl12conservativeQw3Gcx10smallAllocMFNbmKmkxC8TypeInfoZPv ()
Comment #1 by moonlightsentinel — 2020-05-24T19:56:36Z
Full stack trace: Program received signal SIGSEGV, Segmentation fault. _D2gc4impl12conservativeQw3Gcx10smallAllocMFNbmKmkxC8TypeInfoZPv (this=..., ti=0x7ffffffeda68, bits=0, alloc_size=@0x7ffffffedae8: 16, size=16) at src/gc/impl/conservative/gc.d:1686 1686 auto biti = (p - pool.baseAddr) >> pool.shiftBy; (gdb) bt #0 _D2gc4impl12conservativeQw3Gcx10smallAllocMFNbmKmkxC8TypeInfoZPv (this=..., ti=0x7ffffffeda68, bits=0, alloc_size=@0x7ffffffedae8: 16, size=16) at src/gc/impl/conservative/gc.d:1686 #1 0x000000000807ff73 in _D2gc4impl12conservativeQw14ConservativeGC__T9runLockedS_DQCeQCeQCcQCnQBs12mallocNoSyncMFNbmkKmxC8TypeInfoZPvS_DQEgQEgQEeQEp10mallocTimelS_DQFiQFiQFgQFr10numMallocslTmTkTmTxQCzZQFcMFNbKmKkKmKxQDsZQDl (this=0x84ac0a0, _param_3=@0x7ffffffedb08: 0x0, _param_2=@0x7ffffffedae8: 16, _param_1=@0x7ffffffedb10: 0, _param_0=@0x7ffffffedb18: 16) at src/gc/impl/conservative/gc.d:1627 #2 0x0000000008072bcf in _D2gc4impl12conservativeQw14ConservativeGC6qallocMFNbmkxC8TypeInfoZS4core6memory8BlkInfo_ ( this=0x84ac0a0, __HID14=0x7ffffffedbf0, ti=0x0, bits=0, size=16) at src/gc/impl/conservative/gc.d:417 #3 0x000000000803f283 in gc_qalloc (__HID19=0x7ffffffedbf0, sz=16, ba=0, ti=0x0) at src/gc/proxy.d:36 #4 0x000000000803ed77 in _D4core6memory2GC6qallocFNaNbmkxC8TypeInfoZSQBqQBo8BlkInfo_ (__HID3=0x7ffffffedbf0, ti=0x0, ba=0, sz=16) at src/core/memory.d:523 #5 0x000000000803eb55 in D main () at d_do_test.d:11
Comment #2 by moonlightsentinel — 2020-05-24T22:11:39Z
Passes with -m32 but fails for -m64
Comment #3 by kinke — 2020-05-24T23:05:43Z
(In reply to moonlightsentinel from comment #0) > The following code causes a segfault in the GC (tested on 2.092.0): > > =================================================== > void main() > { > import core.memory; > > string[] arr; > > foreach (_; 0 .. 3) // first two iterations pass > { > immutable len = arr.length; > > auto bi = GC.qalloc(string.sizeof); > arr = (cast(string*) bi.base)[0 .. len]; > > arr = arr.ptr[0 .. len + 1]; > arr[] = []; > } > } Isn't that code clearly writing out of bounds? It's allocating a single slice for each iteration, but writing 1, 2, 3 empty slices into it, and probably overwrites GC-internal data.
Comment #4 by moonlightsentinel — 2020-07-07T13:55:25Z
Closing due to the invalid test case, trying to find a valid reduction