Support backtrace after method calls

GitHub: fix #2902, #2917

The current implementation traverses stack to retrieve backtrace. But
stack will be changed when some operations are occurred. It means that
backtrace may be broken after some operations.

This change (1) saves the minimum information to retrieve backtrace when
exception is raised and (2) restores backtrace from the minimum
information when backtrace is needed. It reduces overhead for creating
backtrace Ruby objects.

The space for the minimum information is reused by multiple
exceptions. So memory allocation isn't occurred for each exception.
This commit is contained in:
Kouhei Sutou
2015-12-29 20:36:12 +09:00
parent e132de9e8e
commit a561bdb25f
7 changed files with 350 additions and 31 deletions
+14
View File
@@ -113,6 +113,14 @@ struct mrb_context {
struct mrb_jmpbuf;
typedef struct {
const char *filename;
int lineno;
struct RClass *klass;
const char *sep;
mrb_sym method_id;
} mrb_backtrace_entry;
typedef void (*mrb_atexit_func)(struct mrb_state*);
typedef struct mrb_state {
@@ -125,6 +133,12 @@ typedef struct mrb_state {
struct mrb_context *root_c;
struct RObject *exc; /* exception */
struct {
struct RObject *exc;
int n;
int n_allocated;
mrb_backtrace_entry *entries;
} backtrace;
struct iv_tbl *globals; /* global variable table */
struct RObject *top_self;