aboutsummaryrefslogtreecommitdiffstats
path: root/signal.c
diff options
context:
space:
mode:
authorNobuyoshi Nakada <nobu@ruby-lang.org>2021-08-18 14:09:29 +0900
committerNobuyoshi Nakada <nobu@ruby-lang.org>2021-08-18 17:23:19 +0900
commit574f3af36ea008896419d2e2407f8fce83bdcd2e (patch)
tree9df37ef765bfeddf40ae25adc85e375eeeec4e79 /signal.c
parent58bd9434360d5a46974eaa03139893c0145615dc (diff)
downloadruby-574f3af36ea008896419d2e2407f8fce83bdcd2e.tar.gz
Rewind execution tags more at stack overflow [Bug #18084]
Diffstat (limited to 'signal.c')
-rw-r--r--signal.c5
1 files changed, 3 insertions, 2 deletions
diff --git a/signal.c b/signal.c
index 46ac6c26cc..dd05e8270e 100644
--- a/signal.c
+++ b/signal.c
@@ -878,12 +878,13 @@ check_stack_overflow(int sig, const uintptr_t addr, const ucontext_t *ctx)
(sp_page <= fault_page && fault_page <= bp_page)) {
rb_execution_context_t *ec = GET_EC();
int crit = FALSE;
- if ((uintptr_t)ec->tag->buf / pagesize <= fault_page + 1) {
+ int uplevel = roomof(pagesize, sizeof(*ec->tag)) / 2; /* XXX: heuristic */
+ while ((uintptr_t)ec->tag->buf / pagesize <= fault_page + 1) {
/* drop the last tag if it is close to the fault,
* otherwise it can cause stack overflow again at the same
* place. */
+ if ((crit = (!ec->tag->prev || !--uplevel)) != FALSE) break;
ec->tag = ec->tag->prev;
- crit = TRUE;
}
reset_sigmask(sig);
rb_ec_stack_overflow(ec, crit);