summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorBen Gamari <ben@well-typed.com>2022-01-28 23:47:50 -0500
committerMarge Bot <ben+marge-bot@smart-cactus.org>2022-01-30 06:27:19 -0500
commitc76c8050a95b6e5828a6684635c10d890afbb114 (patch)
tree5afd919ce6a8a5f9e0d263d95f4cec68d774cae3
parentd07799ab22c156df53919737e3b11ab4ccb2b0d4 (diff)
downloadhaskell-c76c8050a95b6e5828a6684635c10d890afbb114.tar.gz
rts: Don't allocate closurePtrs# pointers on C stack
Previously `closurePtrs#` would allocate an aray of the size of the closure being decoded on the C stack. This was ripe for overflowing the C stack overflow. This resulted in `T12492` failing on Windows.
-rw-r--r--rts/Heap.c7
1 files changed, 5 insertions, 2 deletions
diff --git a/rts/Heap.c b/rts/Heap.c
index 9f9154de27..09beb9a8d2 100644
--- a/rts/Heap.c
+++ b/rts/Heap.c
@@ -8,6 +8,7 @@
#include "Rts.h"
#include "RtsAPI.h"
+#include "RtsUtils.h"
#include "Capability.h"
#include "Printer.h"
@@ -248,8 +249,9 @@ StgMutArrPtrs *heap_view_closurePtrs(Capability *cap, StgClosure *closure) {
// First collect all pointers here, with the comfortable memory bound
// of the whole closure. Afterwards we know how many pointers are in
// the closure and then we can allocate space on the heap and copy them
- // there
- StgClosure *ptrs[size];
+ // there. Note that we cannot allocate this on the C stack as the closure
+ // may be, e.g., a large array.
+ StgClosure **ptrs = (StgClosure **) stgMallocBytes(sizeof(StgClosure *) * size, "heap_view_closurePtrs");
StgWord nptrs = collect_pointers(closure, ptrs);
size = nptrs + mutArrPtrsCardTableSize(nptrs);
@@ -263,6 +265,7 @@ StgMutArrPtrs *heap_view_closurePtrs(Capability *cap, StgClosure *closure) {
for (StgWord i = 0; i<nptrs; i++) {
arr->payload[i] = ptrs[i];
}
+ free(ptrs);
return arr;
}