struct backtrace_state * backtrace_create_state (const char *filename, int threaded, backtrace_error_callback error_callback, void *data) { struct backtrace_state init_state; struct backtrace_state *state; #ifndef HAVE_SYNC_FUNCTIONS if (threaded) { error_callback (data, "backtrace library does not support threads", 0); return NULL; } #endif memset (&init_state, 0, sizeof init_state); init_state.filename = filename; init_state.threaded = threaded; state = ((struct backtrace_state *) backtrace_alloc (&init_state, sizeof *state, error_callback, data)); if (state == NULL) return NULL; *state = init_state; return state; }
int backtrace_full (struct backtrace_state *state, int skip, backtrace_full_callback callback, backtrace_error_callback error_callback, void *data) { struct backtrace_data bdata; void *p; bdata.skip = skip + 1; bdata.state = state; bdata.callback = callback; bdata.error_callback = error_callback; bdata.data = data; bdata.ret = 0; /* If we can't allocate any memory at all, don't try to produce file/line information. */ p = backtrace_alloc (state, 4096, NULL, NULL); if (p == NULL) bdata.can_alloc = 0; else { backtrace_free (state, p, 4096, NULL, NULL); bdata.can_alloc = 1; } _Unwind_Backtrace (unwind, &bdata); return bdata.ret; }
static void bt_init(void *ptr, size_t size) { struct bt_iter_arg *arg = (struct bt_iter_arg *)ptr; arg->btobj = backtrace_alloc(rb_cBacktrace); GetCoreDataFromValue(arg->btobj, rb_backtrace_t, arg->bt); arg->bt->backtrace_base = arg->bt->backtrace = ruby_xmalloc(sizeof(rb_backtrace_location_t) * size); arg->bt->backtrace_size = 0; }
int backtrace_get_view (struct backtrace_state *state, int descriptor, off_t offset, size_t size, backtrace_error_callback error_callback, void *data, struct backtrace_view *view) { ssize_t got; if (lseek (descriptor, offset, SEEK_SET) < 0) { error_callback (data, "lseek", errno); return 0; } view->base = backtrace_alloc (state, size, error_callback, data); if (view->base == NULL) return 0; view->data = view->base; view->len = size; got = read (descriptor, view->base, size); if (got < 0) { error_callback (data, "read", errno); free (view->base); return 0; } if ((size_t) got < size) { error_callback (data, "file too short", 0); free (view->base); return 0; } return 1; }