diff options
author | Yusuke Endoh <mame@ruby-lang.org> | 2020-05-15 01:22:56 +0900 |
---|---|---|
committer | GitHub <noreply@github.com> | 2020-05-15 01:22:56 +0900 |
commit | 39365b46e250162f278cb36aa148bc2a92b1b84a (patch) | |
tree | 4eb62c6d4143dd0bd095a8f6c0cd5b89f7a59a7f /eval_error.c | |
parent | 531e4a35f4c9c772aae331281cad324c6806c603 (diff) |
Merge pull request #3047 from mame/suppress-backtrace
Add `--suppress-backtrace=num` option to limit the backtrace length
Notes
Notes:
Merged-By: mame <mame@ruby-lang.org>
Diffstat (limited to 'eval_error.c')
-rw-r--r-- | eval_error.c | 32 |
1 files changed, 23 insertions, 9 deletions
diff --git a/eval_error.c b/eval_error.c index 89e27afe56..e8a7243b96 100644 --- a/eval_error.c +++ b/eval_error.c @@ -233,29 +233,43 @@ print_backtrace(const VALUE eclass, const VALUE errat, const VALUE str, int reve if (!NIL_P(errat)) { long i; long len = RARRAY_LEN(errat); - int skip = eclass == rb_eSysStackError; const int threshold = 1000000000; int width = (len <= 1) ? INT_MIN : ((int)log10((double)(len > threshold ? ((len - 1) / threshold) : len - 1)) + (len < threshold ? 0 : 9) + 1); -#define TRACE_MAX (TRACE_HEAD+TRACE_TAIL+5) -#define TRACE_HEAD 8 -#define TRACE_TAIL 5 + long skip_start = -1, skip_len = 0; + + // skip for stackoverflow + if (eclass == rb_eSysStackError) { + long trace_head = 9; + long trace_tail = 4; + long trace_max = trace_head + trace_tail + 5; + if (len > trace_max) { + skip_start = trace_head; + skip_len = len - trace_max + 5; + } + } + + // skip for explicit limit + if (rb_backtrace_length_limit >= 0 && len > rb_backtrace_length_limit + 1) { + skip_start = rb_backtrace_length_limit + 1; + skip_len = len - rb_backtrace_length_limit; + } for (i = 1; i < len; i++) { + if (i == skip_start) { + write_warn_str(str, rb_sprintf("\t ... %ld levels...\n", skip_len)); + i += skip_len; + if (i >= len) break; + } VALUE line = RARRAY_AREF(errat, reverse ? len - i : i); if (RB_TYPE_P(line, T_STRING)) { VALUE bt = rb_str_new_cstr("\t"); if (reverse) rb_str_catf(bt, "%*ld: ", width, len - i); write_warn_str(str, rb_str_catf(bt, "from %"PRIsVALUE"\n", line)); } - if (skip && i == TRACE_HEAD && len > TRACE_MAX) { - write_warn_str(str, rb_sprintf("\t ... %ld levels...\n", - len - TRACE_HEAD - TRACE_TAIL)); - i = len - TRACE_TAIL; - } } } } |