Skip to content
This repository was archived by the owner on Oct 12, 2022. It is now read-only.

Commit 42b4e0a

Browse files
author
Mihails Strasuns
committed
Fix crash on attaching external threads
Fixes https://issues.dlang.org/show_bug.cgi?id=19313 Issue comes from combination of two factors: 1) Calling `thread_attachThis` does `new Thread` as part of its implementation (because any thread context has to be wrapped into Thread class for registration in runtime). 2) Current GC implementation is not prepared to be called from external thread context and will crash in several places if `Thread.getThis` returns `null`. There are different possible fixes but it seems that the least intrusive one is to simply skip collection when called from the context of unregistered thread. Worst thing it can possibly do for any other code not affected by the issue is to delay garbage collection a bit.
1 parent 0bb71a3 commit 42b4e0a

File tree

3 files changed

+36
-1
lines changed

3 files changed

+36
-1
lines changed

src/gc/impl/conservative/gc.d

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2384,6 +2384,14 @@ struct Gcx
23842384
*/
23852385
size_t fullcollect(bool nostack = false) nothrow
23862386
{
2387+
// It is possible that `fullcollect` will be called from a thread which
2388+
// is not yet registered in runtime (because allocating `new Thread` is
2389+
// part of `thread_attachThis` implementation). In that case it is
2390+
// better not to try actually collecting anything
2391+
2392+
if (Thread.getThis() is null)
2393+
return 0;
2394+
23872395
MonoTime start, stop, begin;
23882396

23892397
if (config.profile)

test/thread/Makefile

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
include ../common.mak
22

3-
TESTS:=fiber_guard_page
3+
TESTS:=fiber_guard_page external_threads
44

55
.PHONY: all clean
66
all: $(addprefix $(ROOT)/,$(addsuffix .done,$(TESTS)))
@@ -11,6 +11,11 @@ $(ROOT)/fiber_guard_page.done: $(ROOT)/%.done : $(ROOT)/%
1111
$(QUIET)$(TIMELIMIT)$(ROOT)/$* $(RUN_ARGS); rc=$$?; [ $$rc -eq 139 ] || [ $$rc -eq 138 ]
1212
@touch $@
1313

14+
$(ROOT)/external_threads.done: $(ROOT)/%.done : $(ROOT)/%
15+
@echo Testing $*
16+
$(QUIET)$(TIMELIMIT)$(ROOT)/$*
17+
@touch $@
18+
1419
$(ROOT)/%: $(SRC)/%.d
1520
$(QUIET)$(DMD) $(DFLAGS) -of$@ $<
1621

test/thread/src/external_threads.d

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
import core.sys.posix.pthread;
2+
import core.memory;
3+
4+
extern(C)
5+
void* entry_point(void*)
6+
{
7+
// try collecting - GC must ignore this call because this thread
8+
// is not registered in runtime
9+
GC.collect();
10+
return null;
11+
}
12+
13+
void main()
14+
{
15+
// allocate some garbage
16+
auto x = new int[1000];
17+
18+
pthread_t thread;
19+
auto status = pthread_create(&thread, null, &entry_point, null);
20+
assert(status == 0);
21+
pthread_join(thread, null);
22+
}

0 commit comments

Comments
 (0)