When run repeatedly, below code on Linux eventually crashes the interpreter (tested on Ubuntu and CentOS).
While the issue is quicker to reproduce with higher numbers of threads, I've been able to reproduce with as low as 40 threads. This doesn't seem to point to an issue with system resources (maximum of threads) being exhausted.
use arg n = 299
do n
.t~thread
end
::class t
::method thread class unguarded
reply
.stdout~charOut(SysSleep(1))
This is the stack trace for the failing thread
Thread 318 (Thread 0x7fffda7cf700 (LWP 5786)):
#0 0x00007ffff7312438 in __GI_raise (sig=sig@entry=6) at ../sysdeps/unix/sysv/linux/raise.c:54
#1 0x00007ffff731403a in __GI_abort () at abort.c:89
#2 0x00007ffff73547fa in __libc_message (do_abort=do_abort@entry=2, fmt=fmt@entry=0x7ffff746dfd8 "*** Error in `%s': %s: 0x%s ***\n") at ../sysdeps/posix/libc_fatal.c:175
#3 0x00007ffff735d38a in malloc_printerr (ar_ptr=<optimized out>, ptr=<optimized out>, str=0x7ffff746e0a0 "double free or corruption (fasttop)", action=3) at malloc.c:5020
#4 _int_free (av=<optimized out>, p=<optimized out>, have_lock=0) at malloc.c:3874
#5 0x00007ffff736158c in __GI___libc_free (mem=<optimized out>) at malloc.c:2975
#6 0x00007ffff7abfdc2 in __gnu_cxx::new_allocator<Activity**>::deallocate (this=0x7fffda7cecb7, __p=0x614c20) at /usr/include/c++/5/ext/new_allocator.h:110
#7 0x00007ffff7abf656 in std::allocator_traits<std::allocator<Activity**> >::deallocate (__a=..., __p=0x614c20, __n=8) at /usr/include/c++/5/bits/alloc_traits.h:517
#8 0x00007ffff7abefc5 in std::_Deque_base<Activity*, std::allocator<Activity*> >::_M_deallocate_map (this=0x7ffff7dd4820 <ActivityManager::waitingActivities>, __p=0x614c20, __n=8) at /usr/include/c++/5/bits/stl_deque.h:622
#9 0x00007ffff7abf821 in std::deque<Activity*, std::allocator<Activity*> >::_M_reallocate_map (this=0x7ffff7dd4820 <ActivityManager::waitingActivities>, __nodes_to_add=1, __add_at_front=false) at /usr/include/c++/5/bits/deque.tcc:935
#10 0x00007ffff7abf08d in std::deque<Activity*, std::allocator<Activity*> >::_M_reserve_map_at_back (this=0x7ffff7dd4820 <ActivityManager::waitingActivities>, __nodes_to_add=1) at /usr/include/c++/5/bits/stl_deque.h:2118
#11 0x00007ffff7abe8f6 in std::deque<Activity*, std::allocator<Activity*> >::_M_push_back_aux<Activity* const&> (this=0x7ffff7dd4820 <ActivityManager::waitingActivities>) at /usr/include/c++/5/bits/deque.tcc:470
#12 0x00007ffff7abe4e7 in std::deque<Activity*, std::allocator<Activity*> >::push_back (this=0x7ffff7dd4820 <ActivityManager::waitingActivities>, __x=@0x7fffda7cedd8: 0x7ffff5693d00) at /usr/include/c++/5/bits/stl_deque.h:1526
#13 0x00007ffff7abc999 in ActivityManager::addWaitingActivity (waitingAct=0x7ffff5693d00, release=false) at .../interpreter/concurrency/ActivityManager.cpp:175
#14 0x00007ffff7ac5a50 in Activity::requestAccess (this=0x7ffff5693d00) at .../interpreter/concurrency/Activity.cpp:2143
#15 0x00007ffff7ac222f in Activity::runThread (this=0x7ffff5693d00) at .../interpreter/concurrency/Activity.cpp:197
#16 0x00007ffff7b15192 in threadFnc (args=0x7ffff5693d00) at .../interpreter/platform/unix/SysActivity.cpp:61
#17 0x00007ffff6ec36ba in start_thread (arg=0x7fffda7cf700) at pthread_create.c:333
#18 0x00007ffff73e451d in clone () at ../sysdeps/unix/sysv/linux/x86_64/clone.S:109
Anonymous
This no longer happens on current trunk. It was fixed by [r13184] (bug [#2072]).
The stack in the description is a push_back on ActivityManager::waitingActivities, the dispatch queue. On Linux, the lock that is meant to protect that queue never actually locked, because of static initialization order (see the log of [r13186], bug [#2078]), so concurrent requests for the kernel corrupted the deque.
Measured on Linux, with the program in the description:
[#1736] had the same cause and is also fixed by [r13184].
Related
Bugs:
#1736Bugs:
#2072Bugs:
#2078Commit: [r13182]
Commit: [r13183]
Commit: [r13184]
Commit: [r13186]
Commit: [r13421]