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

Commit d62a454

Browse files
authored
Merge pull request #2904 from rainers/issue20497
fix Issue 20497 - thread with limited stackspace crashes depending on… merged-on-behalf-of: Nicholas Wilson <[email protected]>
2 parents 2eca79b + d8876bc commit d62a454

File tree

4 files changed

+88
-16
lines changed

4 files changed

+88
-16
lines changed

src/core/thread/osthread.d

Lines changed: 26 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -752,11 +752,13 @@ class Thread
752752
version (Windows) {} else
753753
version (Posix)
754754
{
755+
size_t stksz = adjustStackSize( m_sz );
756+
755757
pthread_attr_t attr;
756758

757759
if ( pthread_attr_init( &attr ) )
758760
onThreadError( "Error initializing thread attributes" );
759-
if ( m_sz && pthread_attr_setstacksize( &attr, m_sz ) )
761+
if ( stksz && pthread_attr_setstacksize( &attr, stksz ) )
760762
onThreadError( "Error initializing thread stack size" );
761763
}
762764

@@ -1535,19 +1537,7 @@ private:
15351537
//
15361538
this(size_t sz = 0) @safe pure nothrow @nogc
15371539
{
1538-
if (sz)
1539-
{
1540-
version (Posix)
1541-
{
1542-
// stack size must be a multiple of PAGESIZE
1543-
sz += PAGESIZE - 1;
1544-
sz -= sz % PAGESIZE;
1545-
// and at least PTHREAD_STACK_MIN
1546-
if (PTHREAD_STACK_MIN > sz)
1547-
sz = PTHREAD_STACK_MIN;
1548-
}
1549-
m_sz = sz;
1550-
}
1540+
m_sz = sz;
15511541
m_call = Call.NO;
15521542
m_curr = &m_main;
15531543
}
@@ -3189,6 +3179,25 @@ private void onThreadError(string msg) nothrow @nogc
31893179
throw error;
31903180
}
31913181

3182+
version (Posix)
3183+
private size_t adjustStackSize(size_t sz) nothrow @nogc
3184+
{
3185+
if (sz == 0)
3186+
return 0;
3187+
3188+
version (CRuntime_Glibc)
3189+
{
3190+
// TLS uses the top of the stack, so add its size to the requested size
3191+
sz += externDFunc!("rt.sections_elf_shared.sizeOfTLS",
3192+
size_t function() @nogc nothrow)();
3193+
}
3194+
// stack size must be a multiple of PAGESIZE and at least PTHREAD_STACK_MIN
3195+
sz = ((sz + PAGESIZE - 1) & ~(PAGESIZE - 1));
3196+
if (PTHREAD_STACK_MIN > sz)
3197+
sz = PTHREAD_STACK_MIN;
3198+
3199+
return sz;
3200+
}
31923201

31933202
unittest
31943203
{
@@ -3988,12 +3997,14 @@ ThreadID createLowLevelThread(void delegate() nothrow dg, uint stacksize = 0,
39883997
return null;
39893998
}
39903999

4000+
size_t stksz = adjustStackSize(stacksize);
4001+
39914002
pthread_attr_t attr;
39924003

39934004
int rc;
39944005
if ((rc = pthread_attr_init(&attr)) != 0)
39954006
return ThreadID.init;
3996-
if (stacksize && (rc = pthread_attr_setstacksize(&attr, stacksize)) != 0)
4007+
if (stksz && (rc = pthread_attr_setstacksize(&attr, stksz)) != 0)
39974008
return ThreadID.init;
39984009
if ((rc = pthread_create(&tid, &attr, &thread_lowlevelEntry, context)) != 0)
39994010
return ThreadID.init;

src/rt/sections_elf_shared.d

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -189,6 +189,15 @@ version (Shared)
189189
dg(tdso._tlsRange.ptr, tdso._tlsRange.ptr + tdso._tlsRange.length);
190190
}
191191

192+
size_t sizeOfTLS() nothrow @nogc
193+
{
194+
auto tdsos = initTLSRanges();
195+
size_t sum;
196+
foreach (ref tdso; *tdsos)
197+
sum += tdso._tlsRange.length;
198+
return sum;
199+
}
200+
192201
// interface for core.thread to inherit loaded libraries
193202
void* pinLoadedLibraries() nothrow @nogc
194203
{
@@ -282,6 +291,15 @@ else
282291
foreach (rng; *rngs)
283292
dg(rng.ptr, rng.ptr + rng.length);
284293
}
294+
295+
size_t sizeOfTLS() nothrow @nogc
296+
{
297+
auto rngs = initTLSRanges();
298+
size_t sum;
299+
foreach (rng; *rngs)
300+
sum += rng.length;
301+
return sum;
302+
}
285303
}
286304

287305
private:

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 external_threads tlsgc_sections test_import
3+
TESTS:=fiber_guard_page external_threads tlsgc_sections test_import tlsstack
44

55
.PHONY: all clean
66
all: $(addprefix $(ROOT)/,$(addsuffix .done,$(TESTS)))
@@ -26,6 +26,11 @@ $(ROOT)/test_import.done: $(ROOT)/%.done : $(ROOT)/%
2626
$(QUIET)$(TIMELIMIT)$(ROOT)/$*
2727
@touch $@
2828

29+
$(ROOT)/tlsstack.done: $(ROOT)/%.done : $(ROOT)/%
30+
@echo Testing $*
31+
$(QUIET)$(TIMELIMIT)$(ROOT)/$*
32+
@touch $@
33+
2934
$(ROOT)/%: $(SRC)/%.d
3035
$(QUIET)$(DMD) $(DFLAGS) -of$@ $<
3136

test/thread/src/tlsstack.d

Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,38 @@
1+
module core.thread.test; // needs access to getStackTop()/getStackBottom()
2+
3+
import core.stdc.stdio;
4+
import core.thread;
5+
6+
ubyte[16384] data;
7+
8+
void showThreadInfo() nothrow
9+
{
10+
try
11+
{
12+
auto top = getStackTop();
13+
auto bottom = getStackBottom();
14+
printf("tlsdata: %p\n", data.ptr);
15+
printf("stack top: %p\n", getStackTop());
16+
printf("stack bottom:%p\n", getStackBottom());
17+
printf("used stack: %lld\n", cast(ulong)(bottom - top));
18+
}
19+
catch(Exception e)
20+
{
21+
assert(false, e.msg);
22+
}
23+
}
24+
25+
void main()
26+
{
27+
printf("### main\n");
28+
showThreadInfo();
29+
30+
printf("### thread\n");
31+
auto th = new Thread(&showThreadInfo, 16384);
32+
th.start();
33+
th.join();
34+
35+
printf("### lowlevel thread\n");
36+
auto llth = createLowLevelThread(() { showThreadInfo(); });
37+
joinLowLevelThread(llth);
38+
}

0 commit comments

Comments
 (0)