Commit d12b6ab2 authored by take_cheeze's avatar take_cheeze

add verbose_backtrace

parent d19d9bb0
...@@ -323,6 +323,7 @@ void mrb_name_error(mrb_state *mrb, mrb_sym id, const char *fmt, ...); ...@@ -323,6 +323,7 @@ void mrb_name_error(mrb_state *mrb, mrb_sym id, const char *fmt, ...);
void mrb_warn(mrb_state *mrb, const char *fmt, ...); void mrb_warn(mrb_state *mrb, const char *fmt, ...);
void mrb_bug(mrb_state *mrb, const char *fmt, ...); void mrb_bug(mrb_state *mrb, const char *fmt, ...);
void mrb_print_backtrace(mrb_state *mrb); void mrb_print_backtrace(mrb_state *mrb);
void mrb_print_verbose_backtrace(mrb_state *mrb);
void mrb_print_error(mrb_state *mrb); void mrb_print_error(mrb_state *mrb);
/* macros to get typical exception objects /* macros to get typical exception objects
......
...@@ -55,7 +55,7 @@ get_backtrace_i(mrb_state *mrb, void *stream, int level, const char *format, ... ...@@ -55,7 +55,7 @@ get_backtrace_i(mrb_state *mrb, void *stream, int level, const char *format, ...
} }
static void static void
mrb_output_backtrace(mrb_state *mrb, struct RObject *exc, output_stream_func func, void *stream) mrb_output_backtrace(mrb_state *mrb, struct RObject *exc, output_stream_func func, void *stream, mrb_bool verbose)
{ {
mrb_callinfo *ci; mrb_callinfo *ci;
mrb_int ciidx; mrb_int ciidx;
...@@ -72,10 +72,10 @@ mrb_output_backtrace(mrb_state *mrb, struct RObject *exc, output_stream_func fun ...@@ -72,10 +72,10 @@ mrb_output_backtrace(mrb_state *mrb, struct RObject *exc, output_stream_func fun
filename = "(unknown)"; filename = "(unknown)";
line = -1; line = -1;
if (MRB_PROC_CFUNC_P(ci->proc)) { if (!verbose && MRB_PROC_CFUNC_P(ci->proc)) {
continue; continue;
} }
else { if(!MRB_PROC_CFUNC_P(ci->proc)) {
mrb_irep *irep = ci->proc->body.irep; mrb_irep *irep = ci->proc->body.irep;
if (irep->filename != NULL) if (irep->filename != NULL)
filename = irep->filename; filename = irep->filename;
...@@ -93,13 +93,16 @@ mrb_output_backtrace(mrb_state *mrb, struct RObject *exc, output_stream_func fun ...@@ -93,13 +93,16 @@ mrb_output_backtrace(mrb_state *mrb, struct RObject *exc, output_stream_func fun
} }
} }
} }
if (line == -1) continue; if (!verbose && line == -1) continue;
if (ci->target_class == ci->proc->target_class) if (ci->target_class == ci->proc->target_class)
sep = "."; sep = ".";
else else
sep = "#"; sep = "#";
method = mrb_sym2name(mrb, ci->mid); method = mrb_sym2name(mrb, ci->mid);
if (verbose && !method && ci->proc->env) {
method = mrb_sym2name(mrb, ci->proc->env->mid);
}
if (method) { if (method) {
const char *cn = mrb_class_name(mrb, ci->proc->target_class); const char *cn = mrb_class_name(mrb, ci->proc->target_class);
...@@ -126,7 +129,15 @@ void ...@@ -126,7 +129,15 @@ void
mrb_print_backtrace(mrb_state *mrb) mrb_print_backtrace(mrb_state *mrb)
{ {
#ifdef ENABLE_STDIO #ifdef ENABLE_STDIO
mrb_output_backtrace(mrb, mrb->exc, print_backtrace_i, (void*)stderr); mrb_output_backtrace(mrb, mrb->exc, print_backtrace_i, (void*)stderr, 0);
#endif
}
void
mrb_print_verbose_backtrace(mrb_state *mrb)
{
#ifdef ENABLE_STDIO
mrb_output_backtrace(mrb, mrb->exc, print_backtrace_i, (void*)stderr, 1);
#endif #endif
} }
...@@ -136,7 +147,18 @@ mrb_get_backtrace(mrb_state *mrb, mrb_value self) ...@@ -136,7 +147,18 @@ mrb_get_backtrace(mrb_state *mrb, mrb_value self)
mrb_value ary; mrb_value ary;
ary = mrb_ary_new(mrb); ary = mrb_ary_new(mrb);
mrb_output_backtrace(mrb, mrb_obj_ptr(self), get_backtrace_i, (void*)mrb_ary_ptr(ary)); mrb_output_backtrace(mrb, mrb_obj_ptr(self), get_backtrace_i, (void*)mrb_ary_ptr(ary), 0);
return ary;
}
mrb_value
mrb_get_verbose_backtrace(mrb_state *mrb, mrb_value self)
{
mrb_value ary;
ary = mrb_ary_new(mrb);
mrb_output_backtrace(mrb, mrb_obj_ptr(self), get_backtrace_i, (void*)mrb_ary_ptr(ary), 1);
return ary; return ary;
} }
...@@ -311,6 +311,7 @@ mrb_define_method_id(mrb_state *mrb, struct RClass *c, mrb_sym mid, mrb_func_t f ...@@ -311,6 +311,7 @@ mrb_define_method_id(mrb_state *mrb, struct RClass *c, mrb_sym mid, mrb_func_t f
int ai = mrb_gc_arena_save(mrb); int ai = mrb_gc_arena_save(mrb);
p = mrb_proc_new_cfunc(mrb, func); p = mrb_proc_new_cfunc(mrb, func);
p->target_class = c;
mrb_define_method_raw(mrb, c, mid, p); mrb_define_method_raw(mrb, c, mid, p);
mrb_gc_arena_restore(mrb, ai); mrb_gc_arena_restore(mrb, ai);
} }
......
...@@ -436,6 +436,7 @@ mrb_sys_fail(mrb_state *mrb, const char *mesg) ...@@ -436,6 +436,7 @@ mrb_sys_fail(mrb_state *mrb, const char *mesg)
} }
mrb_value mrb_get_backtrace(mrb_state*, mrb_value); mrb_value mrb_get_backtrace(mrb_state*, mrb_value);
mrb_value mrb_get_verbose_backtrace(mrb_state*, mrb_value);
void void
mrb_init_exception(mrb_state *mrb) mrb_init_exception(mrb_state *mrb)
...@@ -451,6 +452,7 @@ mrb_init_exception(mrb_state *mrb) ...@@ -451,6 +452,7 @@ mrb_init_exception(mrb_state *mrb)
mrb_define_method(mrb, e, "message", exc_message, MRB_ARGS_NONE()); mrb_define_method(mrb, e, "message", exc_message, MRB_ARGS_NONE());
mrb_define_method(mrb, e, "inspect", exc_inspect, MRB_ARGS_NONE()); mrb_define_method(mrb, e, "inspect", exc_inspect, MRB_ARGS_NONE());
mrb_define_method(mrb, e, "backtrace", mrb_get_backtrace, MRB_ARGS_NONE()); mrb_define_method(mrb, e, "backtrace", mrb_get_backtrace, MRB_ARGS_NONE());
mrb_define_method(mrb, e, "verbose_backtrace", mrb_get_verbose_backtrace, MRB_ARGS_NONE());
mrb->eStandardError_class = mrb_define_class(mrb, "StandardError", mrb->eException_class); /* 15.2.23 */ mrb->eStandardError_class = mrb_define_class(mrb, "StandardError", mrb->eException_class); /* 15.2.23 */
mrb_define_class(mrb, "RuntimeError", mrb->eStandardError_class); /* 15.2.28 */ mrb_define_class(mrb, "RuntimeError", mrb->eStandardError_class); /* 15.2.28 */
......
...@@ -345,3 +345,13 @@ assert('Exception#backtrace') do ...@@ -345,3 +345,13 @@ assert('Exception#backtrace') do
true true
end end
assert('Exception#verbose_backtrace') do
begin
raise "get backtrace"
rescue => e
e.verbose_backtrace
end
true
end
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment