diff --git a/src/gc/impl/conservative/gc.d b/src/gc/impl/conservative/gc.d index e3e3b6da37..fa1d900808 100644 --- a/src/gc/impl/conservative/gc.d +++ b/src/gc/impl/conservative/gc.d @@ -2384,6 +2384,14 @@ struct Gcx */ size_t fullcollect(bool nostack = false) nothrow { + // It is possible that `fullcollect` will be called from a thread which + // is not yet registered in runtime (because allocating `new Thread` is + // part of `thread_attachThis` implementation). In that case it is + // better not to try actually collecting anything + + if (Thread.getThis() is null) + return 0; + MonoTime start, stop, begin; if (config.profile) diff --git a/test/thread/Makefile b/test/thread/Makefile index ca27d1fb86..ba0eafc2e5 100644 --- a/test/thread/Makefile +++ b/test/thread/Makefile @@ -1,6 +1,6 @@ include ../common.mak -TESTS:=fiber_guard_page +TESTS:=fiber_guard_page external_threads .PHONY: all clean all: $(addprefix $(ROOT)/,$(addsuffix .done,$(TESTS))) @@ -11,6 +11,11 @@ $(ROOT)/fiber_guard_page.done: $(ROOT)/%.done : $(ROOT)/% $(QUIET)$(TIMELIMIT)$(ROOT)/$* $(RUN_ARGS); rc=$$?; [ $$rc -eq 139 ] || [ $$rc -eq 138 ] @touch $@ +$(ROOT)/external_threads.done: $(ROOT)/%.done : $(ROOT)/% + @echo Testing $* + $(QUIET)$(TIMELIMIT)$(ROOT)/$* + @touch $@ + $(ROOT)/%: $(SRC)/%.d $(QUIET)$(DMD) $(DFLAGS) -of$@ $< diff --git a/test/thread/src/external_threads.d b/test/thread/src/external_threads.d new file mode 100644 index 0000000000..087c4bfebd --- /dev/null +++ b/test/thread/src/external_threads.d @@ -0,0 +1,22 @@ +import core.sys.posix.pthread; +import core.memory; + +extern(C) +void* entry_point(void*) +{ + // try collecting - GC must ignore this call because this thread + // is not registered in runtime + GC.collect(); + return null; +} + +void main() +{ + // allocate some garbage + auto x = new int[1000]; + + pthread_t thread; + auto status = pthread_create(&thread, null, &entry_point, null); + assert(status == 0); + pthread_join(thread, null); +}