From: wolfgang Date: Sat, 8 Feb 2003 13:34:06 +0000 (+0000) Subject: [project @ 2003-02-08 13:34:06 by wolfgang] X-Git-Tag: Approx_11550_changesets_converted~1188 X-Git-Url: http://git.megacz.com/?p=ghc-hetmet.git;a=commitdiff_plain;h=b0c44859840c251bac0d199fad94645031579096 [project @ 2003-02-08 13:34:06 by wolfgang] Fix a potential crash in the threaded RTS by copying ccall arguments from the TSO stack to a malloced block before doing the call. (no changes were made for the non-threaded case) --- diff --git a/ghc/rts/Interpreter.c b/ghc/rts/Interpreter.c index 270feb0..79b883b 100644 --- a/ghc/rts/Interpreter.c +++ b/ghc/rts/Interpreter.c @@ -1157,8 +1157,19 @@ run_BCO: int stk_offset = BCO_NEXT; int o_itbl = BCO_NEXT; void(*marshall_fn)(void*) = (void (*)(void*))BCO_LIT(o_itbl); - StgTSO *tso = cap->r.rCurrentTSO; +#ifdef RTS_SUPPORTS_THREADS + // Threaded RTS: + // Arguments on the TSO stack are not good, because garbage + // collection might move the TSO as soon as we call + // suspendThread below. + + void *arguments; + + arguments = stgMallocWords(stk_offset,"bci_CCALL"); + memcpy(arguments, Sp, sizeof(W_) * stk_offset); +#endif + // There are a bunch of non-ptr words on the stack (the // ccall args, the ccall fun address and space for the // result), which we need to cover with an info table @@ -1176,21 +1187,35 @@ run_BCO: SAVE_STACK_POINTERS; tok = suspendThread(&cap->r,rtsFalse); +#ifndef RTS_SUPPORTS_THREADS // Careful: // suspendThread might have shifted the stack // around (stack squeezing), so we have to grab the real // Sp out of the TSO to find the ccall args again. - // We don't own the capability anymore, so we mustn't use it. - // Instead, we have to save the TSO ptr beforehand. - // Also note that GC may strike at any time now (from another thread). - // FIXME - DANGER!! Can GC move our TSO? - // If so, we have to copy the args elsewhere! - marshall_fn ( (void*)(tso->sp + RET_DYN_SIZE + sizeofW(StgRetDyn)) ); - + + marshall_fn ( (void*)(cap->r.rCurrentTSO->sp + RET_DYN_SIZE + sizeofW(StgRetDyn)) ); +#else + // Threaded RTS: + // We already made a malloced copy of the arguments above. + + marshall_fn ( arguments ); +#endif + // And restart the thread again, popping the RET_DYN frame. cap = (Capability *)((void *)resumeThread(tok,rtsFalse) - sizeof(StgFunTable)); LOAD_STACK_POINTERS; Sp += RET_DYN_SIZE + sizeofW(StgRetDyn); + + +#ifdef RTS_SUPPORTS_THREADS + // Threaded RTS: + // Copy the "arguments", which might include a return value, + // back to the TSO stack. It would of course be enough to + // just copy the return value, but we don't know the offset. + memcpy(Sp, arguments, sizeof(W_) * stk_offset); + free(arguments); +#endif + goto nextInsn; }