[前][次][番号順一覧][スレッド一覧]

ruby-changes:61261

From: Yusuke <ko1@a...>
Date: Fri, 15 May 2020 01:23:09 +0900 (JST)
Subject: [ruby-changes:61261] 39365b46e2 (master): Merge pull request #3047 from mame/suppress-backtrace

https://git.ruby-lang.org/ruby.git/commit/?id=39365b46e2

From 39365b46e250162f278cb36aa148bc2a92b1b84a Mon Sep 17 00:00:00 2001
From: Yusuke Endoh <mame@r...>
Date: Fri, 15 May 2020 01:22:56 +0900
Subject: Merge pull request #3047 from mame/suppress-backtrace

Add `--suppress-backtrace=num` option to limit the backtrace length

diff --git a/doc/fiber.rdoc b/doc/fiber.rdoc
index d3c19a0..4a489ed 100644
--- a/doc/fiber.rdoc
+++ b/doc/fiber.rdoc
@@ -88,13 +88,13 @@ context switching points. https://github.com/ruby/ruby/blob/trunk/doc/fiber.rdoc#L88
   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
 
diff --git a/error.c b/error.c
index 4912869..31ffc32 100644
--- a/error.c
+++ b/error.c
@@ -64,6 +64,7 @@ VALUE rb_iseqw_local_variables(VALUE iseqval); https://github.com/ruby/ruby/blob/trunk/error.c#L64
 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;
diff --git a/eval_error.c b/eval_error.c
index 89e27af..e8a7243 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 https://github.com/ruby/ruby/blob/trunk/eval_error.c#L233
     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;
-	    }
 	}
     }
 }
diff --git a/internal/error.h b/internal/error.h
index 06eb0c4..ff60d00 100644
--- a/internal/error.h
+++ b/internal/error.h
@@ -46,6 +46,7 @@ typedef enum { https://github.com/ruby/ruby/blob/trunk/internal/error.h#L46
     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;
diff --git a/ruby.c b/ruby.c
index 901556f..ba515bf 100644
--- a/ruby.c
+++ b/ruby.c
@@ -309,6 +309,7 @@ usage(const char *name, int help, int highlight, int columns) https://github.com/ruby/ruby/blob/trunk/ruby.c#L309
 	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) https://github.com/ruby/ruby/blob/trunk/ruby.c#L1424
 		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);
-- 
cgit v0.10.2


--
ML: ruby-changes@q...
Info: http://www.atdot.net/~ko1/quickml/

[前][次][番号順一覧][スレッド一覧]