diff --git a/pkg/noun/manage.c b/pkg/noun/manage.c index 126eaf07ee..024a80fce5 100644 --- a/pkg/noun/manage.c +++ b/pkg/noun/manage.c @@ -280,10 +280,47 @@ _cm_stack_recover(u3a_road* rod_u) /* _cm_stack_unwind(): unwind to the top level, preserving all frames. */ static u3_noun -_cm_stack_unwind(void) +_cm_stack_unwind(c3_l sig_l) { u3_noun tax; + if ( c3__meme == sig_l ) { + // heuristic: if we crash with %meme then our stacktrace might be too big + // to copy, so we trim it. + // + // we abuse the fact that the cells in the stacktrace list are not + // structurally shared with anything else + // we also use the fact that the mug hashes of the stacktrace list + // do not matter (since this is a nondeterministic crash, so the + // stacktrace won't get materialized as a product of the outer + // computation), thus we are allowed to edit the noun in place. + // + u3_noun beg = u3R->bug.tax; + // 512 is from +mook to make things more consistent + // + for (c3_w i_w = 0; i_w < 512; i_w++) { + if ( u3_nul == beg ) break; + beg = u3t(beg); + } + + if ( u3_nul != beg ) { + u3_noun end = u3R->bug.tax, xat = beg; + c3_w len_w = 0; + while (u3_nul != xat) { + xat = u3t(xat); + end = u3t(end); + len_w++; + } + + if (len_w > 512) { + u3k(end); + u3a_cell* beg_u = u3a_to_ptr(beg); + u3z(beg_u->tel); + beg_u->tel = u3nc(u3nc(c3__mean, u3i_string("meme: trace")), end); + } + } + } + while ( u3R != &(u3H->rod_u) ) { u3_noun yat = u3m_love(u3R->bug.tax); @@ -359,7 +396,7 @@ _cm_signal_recover(c3_l sig_l, u3_noun arg) } } #else - tax = _cm_stack_unwind(); + tax = _cm_stack_unwind(sig_l); #endif pro = u3nt(3, sig_l, tax); _cm_signal_reset();