static int kplib_backtrace(ktap_state *ks) { struct stack_trace trace; int skip = 10, max_entries = 10; int n = kp_arg_nr(ks); ktap_btrace *bt; if (n >= 1) { kp_arg_check(ks, 1, KTAP_TYPE_NUMBER); skip = nvalue(kp_arg(ks, 1)); } if (n >= 2) { kp_arg_check(ks, 2, KTAP_TYPE_NUMBER); max_entries = nvalue(kp_arg(ks, 2)); max_entries = min(max_entries, KTAP_MAX_STACK_ENTRIES); } bt = kp_percpu_data(ks, KTAP_PERCPU_DATA_BTRACE); trace.nr_entries = 0; trace.skip = skip; trace.max_entries = max_entries; trace.entries = (unsigned long *)(bt + 1); save_stack_trace(&trace); bt->nr_entries = trace.nr_entries; set_btrace(ks->top, bt); incr_top(ks); return 1; }
void kp_obj_clone(ktap_state *ks, const ktap_value *o, ktap_value *newo, ktap_gcobject **list) { if (is_btrace(o)) { int nr_entries = btvalue(o)->nr_entries; ktap_btrace *bt; bt = kp_obj_newbacktrace(ks, nr_entries, list); memcpy((unsigned long *)(bt + 1), btvalue(o) + 1, nr_entries * sizeof(unsigned long)); set_btrace(newo, bt); } else { kp_error(ks, "cannot clone ktap value type %d\n", ttype(o)); set_nil(newo); } }