diff options
-rw-r--r-- | ChangeLog | 12 | ||||
-rw-r--r-- | error.c | 32 | ||||
-rw-r--r-- | ext/-test-/bug_reporter/bug_reporter.c | 24 | ||||
-rw-r--r-- | ext/-test-/bug_reporter/extconf.rb | 1 | ||||
-rw-r--r-- | internal.h | 3 | ||||
-rw-r--r-- | test/-ext-/bug_reporter/test_bug_reporter.rb | 9 |
6 files changed, 80 insertions, 1 deletions
@@ -1,3 +1,15 @@ +Wed Oct 16 17:37:17 2013 Koichi Sasada <ko1@atdot.net> + + * error.c, internal.h (rb_bug_reporter_add): add a new C-API. + rb_bug_reporter_add() allows to register a function which + is called at rb_bug() called. + + * ext/-test-/bug_reporter/bug_reporter.c: add a test for this C-API. + + * ext/-test-/bug_reporter/extconf.rb: ditto. + + * test/-ext-/bug_reporter/test_bug_reporter.rb: ditto. + Wed Oct 16 15:14:21 2013 Koichi Sasada <ko1@atdot.net> * NEWS: add a line into NEWS for last commit. @@ -264,6 +264,29 @@ rb_warn_m(int argc, VALUE *argv, VALUE exc) return Qnil; } +#define MAX_BUG_REPORTERS 0x100 + +static struct bug_reporters { + void (*func)(FILE *out, void *data); + void *data; +} bug_reporters[MAX_BUG_REPORTERS]; + +static int bug_reporters_size; + +int +rb_bug_reporter_add(void (*func)(FILE *, void *), void *data) +{ + struct bug_reporters *reporter; + if (bug_reporters_size >= MAX_BUG_REPORTERS) { + rb_bug("rb_bug_reporter_add: overflow"); + } + reporter = &bug_reporters[bug_reporters_size++]; + reporter->func = func; + reporter->data = data; + + return bug_reporters_size; +} + static void report_bug(const char *file, int line, const char *fmt, va_list args) { @@ -281,9 +304,16 @@ report_bug(const char *file, int line, const char *fmt, va_list args) snprintf(buf, 256, "\n%s\n\n", ruby_description); fputs(buf, out); - rb_vm_bugreport(); + /* call additional bug reporters */ + { + int i; + for (i=0; i<bug_reporters_size; i++) { + struct bug_reporters *reporter = &bug_reporters[i]; + (*reporter->func)(out, reporter->data); + } + } fprintf(out, REPORTBUG_MSG); } } diff --git a/ext/-test-/bug_reporter/bug_reporter.c b/ext/-test-/bug_reporter/bug_reporter.c new file mode 100644 index 0000000000..875c3a4617 --- /dev/null +++ b/ext/-test-/bug_reporter/bug_reporter.c @@ -0,0 +1,24 @@ +#include <ruby.h>
+#include <stdio.h>
+
+int rb_bug_reporter_add(void (*func)(FILE *, void *), void *data);
+
+static void
+sample_bug_reporter(FILE *out, void *ptr)
+{
+ int n = (int)ptr;
+ fprintf(out, "Sample bug reporter: %d\n", n);
+}
+
+static VALUE
+register_sample_bug_reporter(VALUE self, VALUE obj)
+{
+ rb_bug_reporter_add(sample_bug_reporter, NUM2INT(obj));
+ return Qnil;
+}
+
+void
+Init_bug_reporter(void)
+{
+ rb_define_global_function("register_sample_bug_reporter", register_sample_bug_reporter, 1);
+}
diff --git a/ext/-test-/bug_reporter/extconf.rb b/ext/-test-/bug_reporter/extconf.rb new file mode 100644 index 0000000000..76c1e6ff78 --- /dev/null +++ b/ext/-test-/bug_reporter/extconf.rb @@ -0,0 +1 @@ +create_makefile("-test-/bug_reporter/bug_reporter")
diff --git a/internal.h b/internal.h index 403b91bade..c1890961c3 100644 --- a/internal.h +++ b/internal.h @@ -772,6 +772,9 @@ VALUE rb_big2str_gmp(VALUE x, int base); VALUE rb_str2big_gmp(VALUE arg, int base, int badcheck); #endif +/* error.c */ +int rb_bug_reporter_add(void (*func)(FILE *, void *), void *data); + /* file.c */ #ifdef __APPLE__ VALUE rb_str_normalize_ospath(const char *ptr, long len); diff --git a/test/-ext-/bug_reporter/test_bug_reporter.rb b/test/-ext-/bug_reporter/test_bug_reporter.rb new file mode 100644 index 0000000000..319f3ffe9a --- /dev/null +++ b/test/-ext-/bug_reporter/test_bug_reporter.rb @@ -0,0 +1,9 @@ +require 'test/unit'
+require_relative "../../ruby/envutil"
+
+class TestBugReporter < Test::Unit::TestCase
+ def test_bug_reporter_add
+ expected_stderr = /Sample bug reporter: 12345/
+ assert_in_out_err(["--disable-gems", "-r-test-/bug_reporter/bug_reporter", "-e", "register_sample_bug_reporter(12345); Process.kill :SEGV, $$"], "", [], expected_stderr, nil)
+ end
+end
|