Skip to content

Commit 21296e9

Browse files
authored
Fix a pthread stack corruption problem (#21417)
Fix a problem with pthread creation where it would call from JS to C/C++ function `_emscripten_thread_init()` before having correctly initialized the C/C++ program stack, leading the pthread to stomp on the main thread's stack for the execution of that function.
1 parent e668097 commit 21296e9

File tree

3 files changed

+18
-11
lines changed

3 files changed

+18
-11
lines changed

src/library_pthread.js

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1063,8 +1063,12 @@ var LibraryPThread = {
10631063
10641064
$establishStackSpace__internal: true,
10651065
$establishStackSpace__deps: ['$stackRestore'],
1066-
$establishStackSpace: () => {
1067-
var pthread_ptr = _pthread_self();
1066+
$establishStackSpace: (pthread_ptr) => {
1067+
#if ALLOW_MEMORY_GROWTH
1068+
// If memory growth is enabled, the memory views may have gotten out of date,
1069+
// so resync them before accessing the pthread ptr below.
1070+
updateMemoryViews();
1071+
#endif
10681072
var stackHigh = {{{ makeGetValue('pthread_ptr', C_STRUCTS.pthread.stack, '*') }}};
10691073
var stackSize = {{{ makeGetValue('pthread_ptr', C_STRUCTS.pthread.stack_size, '*') }}};
10701074
var stackLow = stackHigh - stackSize;

src/preamble.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -139,7 +139,7 @@ var HEAP,
139139
/* BigInt64Array type is not correctly defined in closure
140140
/** not-@type {!BigInt64Array} */
141141
HEAP64,
142-
/* BigUInt64Array type is not correctly defined in closure
142+
/* BigUint64Array type is not correctly defined in closure
143143
/** not-t@type {!BigUint64Array} */
144144
HEAPU64,
145145
#endif

src/runtime_pthread.js

Lines changed: 11 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -179,21 +179,24 @@ if (ENVIRONMENT_IS_PTHREAD) {
179179
wasmPromiseResolve(msgData['wasmModule']);
180180
#endif // MINIMAL_RUNTIME
181181
} else if (cmd === 'run') {
182+
#if ASSERTIONS
183+
assert(msgData['pthread_ptr']);
184+
#endif
185+
// Call inside JS module to set up the stack frame for this pthread in JS module scope.
186+
// This needs to be the first thing that we do, as we cannot call to any C/C++ functions
187+
// until the thread stack is initialized.
188+
establishStackSpace(msgData['pthread_ptr']);
189+
182190
// Pass the thread address to wasm to store it for fast access.
183191
__emscripten_thread_init(msgData['pthread_ptr'], /*is_main=*/0, /*is_runtime=*/0, /*can_block=*/1, 0, 0);
184192

193+
PThread.receiveObjectTransfer(msgData);
194+
PThread.threadInitTLS();
195+
185196
// Await mailbox notifications with `Atomics.waitAsync` so we can start
186197
// using the fast `Atomics.notify` notification path.
187198
__emscripten_thread_mailbox_await(msgData['pthread_ptr']);
188199

189-
#if ASSERTIONS
190-
assert(msgData['pthread_ptr']);
191-
#endif
192-
// Also call inside JS module to set up the stack frame for this pthread in JS module scope
193-
establishStackSpace();
194-
PThread.receiveObjectTransfer(msgData);
195-
PThread.threadInitTLS();
196-
197200
if (!initializedJS) {
198201
#if EMBIND
199202
#if PTHREADS_DEBUG

0 commit comments

Comments
 (0)