mirror of
https://github.com/ruby/ruby.git
synced 2022-11-09 12:17:21 -05:00
Merge pull request #3047 from mame/suppress-backtrace
Add `--suppress-backtrace=num` option to limit the backtrace length
This commit is contained in:
parent
531e4a35f4
commit
39365b46e2
Notes:
git
2020-05-15 01:23:19 +09:00
Merged-By: mame <mame@ruby-lang.org>
5 changed files with 35 additions and 12 deletions
|
@ -88,13 +88,13 @@ context switching points.
|
|||
Fiber.new(blocking: false) do
|
||||
puts Fiber.current.blocking? # false
|
||||
|
||||
# May invoke `Thread.scheduler&.wait_readable`.
|
||||
# May invoke `Thread.current.scheduler&.wait_readable`.
|
||||
io.read(...)
|
||||
|
||||
# May invoke `Thread.scheduler&.wait_writable`.
|
||||
# May invoke `Thread.current.scheduler&.wait_writable`.
|
||||
io.write(...)
|
||||
|
||||
# Will invoke `Thread.scheduler&.wait_sleep`.
|
||||
# Will invoke `Thread.current.scheduler&.wait_sleep`.
|
||||
sleep(n)
|
||||
end.resume
|
||||
|
||||
|
|
1
error.c
1
error.c
|
@ -64,6 +64,7 @@ VALUE rb_iseqw_local_variables(VALUE iseqval);
|
|||
VALUE rb_iseqw_new(const rb_iseq_t *);
|
||||
int rb_str_end_with_asciichar(VALUE str, int c);
|
||||
|
||||
long rb_backtrace_length_limit = -1;
|
||||
VALUE rb_eEAGAIN;
|
||||
VALUE rb_eEWOULDBLOCK;
|
||||
VALUE rb_eEINPROGRESS;
|
||||
|
|
32
eval_error.c
32
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;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -46,6 +46,7 @@ typedef enum {
|
|||
RB_WARN_CATEGORY_EXPERIMENTAL,
|
||||
} rb_warning_category_t;
|
||||
|
||||
extern long rb_backtrace_length_limit;
|
||||
extern VALUE rb_eEAGAIN;
|
||||
extern VALUE rb_eEWOULDBLOCK;
|
||||
extern VALUE rb_eEINPROGRESS;
|
||||
|
|
7
ruby.c
7
ruby.c
|
@ -309,6 +309,7 @@ usage(const char *name, int help, int highlight, int columns)
|
|||
M("--verbose", "", "turn on verbose mode and disable script from stdin"),
|
||||
M("--version", "", "print the version number, then exit"),
|
||||
M("--help", "", "show this message, -h for short message"),
|
||||
M("--backtrace-limit=num", "", "limit the maximum length of backtrace"),
|
||||
};
|
||||
static const struct message dumps[] = {
|
||||
M("insns", "", "instruction sequences"),
|
||||
|
@ -1423,6 +1424,12 @@ proc_options(long argc, char **argv, ruby_cmdline_options_t *opt, int envopt)
|
|||
opt->dump |= DUMP_BIT(help);
|
||||
goto switch_end;
|
||||
}
|
||||
else if (is_option_with_arg("backtrace-limit", Qfalse, Qfalse)) {
|
||||
char *e;
|
||||
long n = strtol(s, &e, 10);
|
||||
if (errno == ERANGE || n < 0 || *e) rb_raise(rb_eRuntimeError, "wrong limit for backtrace length");
|
||||
rb_backtrace_length_limit = n;
|
||||
}
|
||||
else {
|
||||
rb_raise(rb_eRuntimeError,
|
||||
"invalid option --%s (-h will show valid options)", s);
|
||||
|
|
Loading…
Reference in a new issue