mirror of
https://github.com/mruby/mruby
synced 2026-06-08 16:11:16 +00:00
add verbose_backtrace
This commit is contained in:
@@ -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_bug(mrb_state *mrb, const char *fmt, ...);
|
||||
void mrb_print_backtrace(mrb_state *mrb);
|
||||
void mrb_print_verbose_backtrace(mrb_state *mrb);
|
||||
void mrb_print_error(mrb_state *mrb);
|
||||
|
||||
/* macros to get typical exception objects
|
||||
|
||||
+28
-6
@@ -55,7 +55,7 @@ get_backtrace_i(mrb_state *mrb, void *stream, int level, const char *format, ...
|
||||
}
|
||||
|
||||
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_int ciidx;
|
||||
@@ -72,10 +72,10 @@ mrb_output_backtrace(mrb_state *mrb, struct RObject *exc, output_stream_func fun
|
||||
filename = "(unknown)";
|
||||
line = -1;
|
||||
|
||||
if (MRB_PROC_CFUNC_P(ci->proc)) {
|
||||
if (!verbose && MRB_PROC_CFUNC_P(ci->proc)) {
|
||||
continue;
|
||||
}
|
||||
else {
|
||||
if(!MRB_PROC_CFUNC_P(ci->proc)) {
|
||||
mrb_irep *irep = ci->proc->body.irep;
|
||||
if (irep->filename != NULL)
|
||||
filename = irep->filename;
|
||||
@@ -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)
|
||||
sep = ".";
|
||||
else
|
||||
sep = "#";
|
||||
|
||||
method = mrb_sym2name(mrb, ci->mid);
|
||||
if (verbose && !method && ci->proc->env) {
|
||||
method = mrb_sym2name(mrb, ci->proc->env->mid);
|
||||
}
|
||||
if (method) {
|
||||
const char *cn = mrb_class_name(mrb, ci->proc->target_class);
|
||||
|
||||
@@ -126,7 +129,15 @@ void
|
||||
mrb_print_backtrace(mrb_state *mrb)
|
||||
{
|
||||
#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
|
||||
}
|
||||
|
||||
@@ -136,7 +147,18 @@ mrb_get_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));
|
||||
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;
|
||||
}
|
||||
|
||||
+3
-2
@@ -55,7 +55,7 @@ mrb_name_class(mrb_state *mrb, struct RClass *c, mrb_sym name)
|
||||
mrb_obj_iv_set(mrb, (struct RObject*)c,
|
||||
mrb_intern2(mrb, "__classid__", 11), mrb_symbol_value(name));
|
||||
}
|
||||
|
||||
|
||||
#define make_metaclass(mrb, c) prepare_singleton_class((mrb), (struct RBasic*)(c))
|
||||
|
||||
static void
|
||||
@@ -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);
|
||||
|
||||
p = mrb_proc_new_cfunc(mrb, func);
|
||||
p->target_class = c;
|
||||
mrb_define_method_raw(mrb, c, mid, p);
|
||||
mrb_gc_arena_restore(mrb, ai);
|
||||
}
|
||||
@@ -1065,7 +1066,7 @@ mrb_class_new_class(mrb_state *mrb, mrb_value cv)
|
||||
{
|
||||
mrb_value super;
|
||||
struct RClass *new_class;
|
||||
|
||||
|
||||
if (mrb_get_args(mrb, "|o", &super) == 0) {
|
||||
super = mrb_obj_value(mrb->object_class);
|
||||
}
|
||||
|
||||
@@ -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_verbose_backtrace(mrb_state*, mrb_value);
|
||||
|
||||
void
|
||||
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, "inspect", exc_inspect, 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_define_class(mrb, "RuntimeError", mrb->eStandardError_class); /* 15.2.28 */
|
||||
|
||||
@@ -345,3 +345,13 @@ assert('Exception#backtrace') do
|
||||
|
||||
true
|
||||
end
|
||||
|
||||
assert('Exception#verbose_backtrace') do
|
||||
begin
|
||||
raise "get backtrace"
|
||||
rescue => e
|
||||
e.verbose_backtrace
|
||||
end
|
||||
|
||||
true
|
||||
end
|
||||
|
||||
Reference in New Issue
Block a user