diff --git a/error.c b/error.c index a492d1c3e15600..4a652bb4ad6cc3 100644 --- a/error.c +++ b/error.c @@ -839,13 +839,17 @@ open_report_path(const char *template, char *buf, size_t size, rb_pid_t *pid) return NULL; } +static const char *bugreport_path; + /* SIGSEGV handler might have a very small stack. Thus we need to use it carefully. */ #define REPORT_BUG_BUFSIZ 256 static FILE * bug_report_file(const char *file, int line, rb_pid_t *pid) { char buf[REPORT_BUG_BUFSIZ]; - FILE *out = open_report_path(getenv("RUBY_BUGREPORT_PATH"), buf, sizeof(buf), pid); + const char *report = bugreport_path; + if (!report) report = getenv("RUBY_BUGREPORT_PATH"); + FILE *out = open_report_path(report, buf, sizeof(buf), pid); int len = err_position_0(buf, sizeof(buf), file, line); if (out) { @@ -998,8 +1002,10 @@ bug_report_end(FILE *out, rb_pid_t pid) } while (0) \ void -ruby_test_bug_report(const char *template) +ruby_set_bug_report(const char *template) { + bugreport_path = template; +#if RUBY_DEBUG rb_pid_t pid = -1; char buf[REPORT_BUG_BUFSIZ]; FILE *out = open_report_path(template, buf, sizeof(buf), &pid); @@ -1008,6 +1014,7 @@ ruby_test_bug_report(const char *template) fprintf(out, "ruby_test_bug_report: %s", ctime(&t)); finish_report(out, pid); } +#endif } NORETURN(static void die(void)); diff --git a/internal/cmdlineopt.h b/internal/cmdlineopt.h index 3b678b1edd1d24..0c31351571f400 100644 --- a/internal/cmdlineopt.h +++ b/internal/cmdlineopt.h @@ -28,6 +28,8 @@ typedef struct ruby_cmdline_options { struct rb_rjit_options rjit; #endif + const char *bugreport_path; + signed int sflag: 2; unsigned int xflag: 1; unsigned int warning: 1; diff --git a/man/ruby.1 b/man/ruby.1 index e0d6733880a784..e552cf91467b1f 100644 --- a/man/ruby.1 +++ b/man/ruby.1 @@ -25,6 +25,7 @@ .Op Fl - Ns Bro Cm enable Ns | Ns Cm disable Brc Ns - Ns Ar FEATURE .Op Fl -dump Ns = Ns Ar target .Op Fl -verbose +.Op Fl -bugreport-path Ns = Ns Ar template .Op Fl - .Op Ar program_file .Op Ar argument ... @@ -469,6 +470,12 @@ variable to true. If this switch is given, and no script arguments (script file or .Fl e options) are present, Ruby quits immediately. +.Pp +.It Fl -bugreport-path Ns = Ns Ar template +Sets the template of path name to save bug report. +See +.Ev RUBY_BUGREPORT_PATH +environment variable for details. .El .Pp .Sh ENVIRONMENT diff --git a/ruby.c b/ruby.c index 351a7282e2d9da..125bfb945395e9 100644 --- a/ruby.c +++ b/ruby.c @@ -337,6 +337,7 @@ usage(const char *name, int help, int highlight, int columns) M("--backtrace-limit=num", "", "limit the maximum length of backtrace"), M("--verbose", "", "turn on verbose mode and disable script from stdin"), M("--version", "", "print the version number, then exit"), + M("--bugreport-path=TEMPLATE", "", "template of bug report files"), M("-y", ", --yydebug", "print log of parser. Backward compatibility is not guaranteed"), M("--help", "", "show this message, -h for short message"), }; @@ -1352,8 +1353,6 @@ proc_encoding_option(ruby_cmdline_options_t *opt, const char *s, const char *opt UNREACHABLE; } -static const char *test_bug_report_template; - static long proc_long_options(ruby_cmdline_options_t *opt, const char *s, long argc, char **argv, int envopt) { @@ -1464,8 +1463,10 @@ proc_long_options(ruby_cmdline_options_t *opt, const char *s, long argc, char ** opt->backtrace_length_limit = n; } } - else if (is_option_with_arg("test-bugreport", true, false)) { - test_bug_report_template = s; + else if (is_option_with_arg("bugreport-path", true, true)) { + if (!opt->bugreport_path) { + opt->bugreport_path = s; + } } else { rb_raise(rb_eRuntimeError, @@ -2916,9 +2917,9 @@ ruby_process_options(int argc, char **argv) iseq = process_options(argc, argv, cmdline_options_init(&opt)); - if (test_bug_report_template) { - void ruby_test_bug_report(const char *template); - ruby_test_bug_report(test_bug_report_template); + if (opt.bugreport_path && *opt.bugreport_path) { + void ruby_set_bug_report(const char *template); + ruby_set_bug_report(opt.bugreport_path); } return (void*)(struct RData*)iseq; }