void kp_obj_dump(ktap_State *ks, const Tvalue *v) { switch (ttype(v)) { case KTAP_TNIL: kp_printf(ks, "NIL"); break; case KTAP_TNUMBER: kp_printf(ks, "NUMBER %d", nvalue(v)); break; case KTAP_TBOOLEAN: kp_printf(ks, "BOOLEAN %d", bvalue(v)); break; case KTAP_TLIGHTUSERDATA: kp_printf(ks, "LIGHTUSERDATA %d", pvalue(v)); break; case KTAP_TLCF: kp_printf(ks, "LIGHTCFCUNTION 0x%x", fvalue(v)); break; case KTAP_TSHRSTR: case KTAP_TLNGSTR: kp_printf(ks, "SHRSTR #%s", svalue(v)); break; case KTAP_TUSERDATA: kp_printf(ks, "USERDATA %d", uvalue(v)); break; case KTAP_TTABLE: kp_printf(ks, "TABLE 0x%x", hvalue(v)); break; default: kp_printf(ks, "GCVALUE 0x%x", gcvalue(v)); break; } }
void kp_obj_show(ktap_state_t *ks, const ktap_val_t *v) { switch (itype(v)) { case KTAP_TNIL: kp_puts(ks, "nil"); break; case KTAP_TTRUE: kp_puts(ks, "true"); break; case KTAP_TFALSE: kp_puts(ks, "false"); break; case KTAP_TNUM: kp_printf(ks, "%ld", nvalue(v)); break; case KTAP_TLIGHTUD: kp_printf(ks, "lightud 0x%lx", (unsigned long)pvalue(v)); break; case KTAP_TCFUNC: kp_printf(ks, "cfunction 0x%lx", (unsigned long)fvalue(v)); break; case KTAP_TFUNC: kp_printf(ks, "function 0x%lx", (unsigned long)gcvalue(v)); break; case KTAP_TSTR: kp_puts(ks, svalue(v)); break; case KTAP_TTAB: kp_printf(ks, "table 0x%lx", (unsigned long)hvalue(v)); break; #ifdef CONFIG_KTAP_FFI case KTAP_TCDATA: kp_cdata_dump(ks, cdvalue(v)); break; #endif case KTAP_TEVENTSTR: /* check event context */ if (!ks->current_event) { kp_error(ks, "cannot stringify event str in invalid context\n"); return; } kp_transport_event_write(ks, ks->current_event); break; case KTAP_TKSTACK: kp_transport_print_kstack(ks, v->val.stack.depth, v->val.stack.skip); break; default: kp_error(ks, "print unknown value type: %d\n", itype(v)); break; } }
/** * function ansi.set_color3 - Set the ansi Select Graphic Rendition mode. * @fg: Foreground color to set. * @bg: Background color to set. * @attr: Color attribute to set. * * Description: Sends ansi code for Select Graphic Rendition mode for the * given forground color, Black (30), Blue (34), Green (32), Cyan (36), * Red (31), Purple (35), Brown (33), Light Gray (37), the given * background color, Black (40), Red (41), Green (42), Yellow (43), * Blue (44), Magenta (45), Cyan (46), White (47) and the color attribute * All attributes off (0), Intensity Bold (1), Underline Single (4), * Blink Slow (5), Blink Rapid (6), Image Negative (7). */ static int kplib_ansi_set_color3(ktap_state_t *ks) { int fg = kp_arg_checknumber(ks, 1); int bg = kp_arg_checknumber(ks, 2); int attr = kp_arg_checknumber(ks, 3); if (attr) kp_printf(ks, "\033[%d;%d;%dm", fg, bg, attr); else kp_printf(ks, "\033[%d;%dm", fg, bg); return 0; }
void kp_obj_dump(ktap_state *ks, const ktap_value *v) { switch (ttype(v)) { case KTAP_TNIL: kp_puts(ks, "NIL"); break; case KTAP_TNUMBER: kp_printf(ks, "NUMBER %ld", nvalue(v)); break; case KTAP_TBOOLEAN: kp_printf(ks, "BOOLEAN %d", bvalue(v)); break; case KTAP_TLIGHTUSERDATA: kp_printf(ks, "LIGHTUSERDATA 0x%lx", (unsigned long)pvalue(v)); break; case KTAP_TLCF: kp_printf(ks, "LIGHTCFCUNTION 0x%lx", (unsigned long)fvalue(v)); break; case KTAP_TSHRSTR: case KTAP_TLNGSTR: kp_printf(ks, "SHRSTR #%s", svalue(v)); break; case KTAP_TUSERDATA: kp_printf(ks, "USERDATA 0x%lx", (unsigned long)uvalue(v)); break; case KTAP_TTABLE: kp_printf(ks, "TABLE 0x%lx", (unsigned long)hvalue(v)); break; default: kp_printf(ks, "GCVALUE 0x%lx", (unsigned long)gcvalue(v)); break; } }
void kp_obj_dump(ktap_state_t *ks, const ktap_val_t *v) { switch (itype(v)) { case KTAP_TNIL: kp_puts(ks, "NIL"); break; case KTAP_TTRUE: kp_printf(ks, "true"); break; case KTAP_TFALSE: kp_printf(ks, "false"); break; case KTAP_TNUM: kp_printf(ks, "NUM %ld", nvalue(v)); break; case KTAP_TLIGHTUD: kp_printf(ks, "LIGHTUD 0x%lx", (unsigned long)pvalue(v)); break; case KTAP_TFUNC: kp_printf(ks, "FUNCTION 0x%lx", (unsigned long)fvalue(v)); break; case KTAP_TSTR: kp_printf(ks, "STR #%s", svalue(v)); break; case KTAP_TTAB: kp_printf(ks, "TABLE 0x%lx", (unsigned long)hvalue(v)); break; default: kp_printf(ks, "GCVALUE 0x%lx", (unsigned long)gcvalue(v)); break; } }
void kp_cdata_dump(ktap_state_t *ks, ktap_cdata_t *cd) { switch (cd_type(ks, cd)) { case FFI_UINT8: case FFI_INT8: kp_printf(ks, "c int(0x%01x)", cd_int(cd)); break; case FFI_UINT16: case FFI_INT16: kp_printf(ks, "c int(0x%02x)", cd_int(cd)); break; case FFI_UINT32: case FFI_INT32: kp_printf(ks, "c int(0x%04x)", cd_int(cd)); break; case FFI_UINT64: case FFI_INT64: kp_printf(ks, "c int(0x%08x)", cd_int(cd)); break; case FFI_PTR: kp_printf(ks, "c pointer(0x%p)", cd_ptr(cd)); break; case FFI_STRUCT: kp_printf(ks, "c struct(0x%p)", cd_struct(cd)); break; case FFI_UNION: kp_printf(ks, "c union(0x%p)", cd_union(cd)); break; default: kp_printf(ks, "unsupported cdata type %d!\n", cd_type(ks, cd)); } }
void *kp_reallocv(ktap_state *ks, void *addr, int oldsize, int newsize) { void *new_addr; new_addr = krealloc(addr, newsize, KTAP_ALLOC_FLAGS); if (unlikely(!new_addr)) { kp_error(ks, "krealloc size %d failed, retry again\n", newsize); printk("ktap krealloc size %d failed, retry again\n", newsize); dump_stack(); while (1) { new_addr = krealloc(addr, newsize, KTAP_ALLOC_FLAGS); if (new_addr) break; } kp_printf(ks, "krealloc retry success after failed, exit\n"); } preempt_disable(); if (oldsize == 0) { KTAP_STATS(ks)->nr_mem_allocate += 1; } KTAP_STATS(ks)->mem_allocated += newsize - oldsize; preempt_enable(); return new_addr; }
static int ktap_lib_print(ktap_State *ks) { int i; int n = GetArgN(ks); for (i = 1; i <= n; i++) { Tvalue *arg = GetArg(ks, i); if (i > 1) kp_printf(ks, "\t"); kp_showobj(ks, arg); } kp_printf(ks, "\n"); return 0; }
static int kplib_ansi_set_color(ktap_state_t *ks) { int fg = kp_arg_checknumber(ks, 1); kp_printf(ks, "\033[%dm", fg); return 0; }
void *kp_malloc(ktap_state *ks, int size) { void *addr; /* * Normally we don't want to trace under memory pressure, * so we use a simple rule to handle memory allocation failure: * * retry until allocation success, this will make caller don't need * to handle the unlikely failure case, then ktap exit. * * In this approach, if user find there have memory allocation failure, * user should re-run the ktap script, or fix the memory pressure * issue, or figure out why the script need so many memory. * * Perhaps return pre-allocated stub memory trunk when allocate failed * is a better approch? */ addr = kmalloc(size, KTAP_ALLOC_FLAGS); if (unlikely(!addr)) { kp_error(ks, "kmalloc size %d failed, retry again\n", size); printk("ktap kmalloc size %d failed, retry again\n", size); dump_stack(); while (1) { addr = kmalloc(size, KTAP_ALLOC_FLAGS); if (addr) break; } kp_printf(ks, "kmalloc retry success after failed, exit\n"); } return addr; }
void kp_obj_show(ktap_state *ks, const ktap_value *v) { switch (ttype(v)) { case KTAP_TYPE_NIL: kp_puts(ks, "nil"); break; case KTAP_TYPE_NUMBER: kp_printf(ks, "%ld", nvalue(v)); break; case KTAP_TYPE_BOOLEAN: kp_puts(ks, (bvalue(v) == 1) ? "true" : "false"); break; case KTAP_TYPE_LIGHTUSERDATA: kp_printf(ks, "0x%lx", (unsigned long)pvalue(v)); break; case KTAP_TYPE_CFUNCTION: kp_printf(ks, "0x%lx", (unsigned long)fvalue(v)); break; case KTAP_TYPE_SHRSTR: case KTAP_TYPE_LNGSTR: kp_puts(ks, svalue(v)); break; case KTAP_TYPE_TABLE: kp_tab_dump(ks, hvalue(v)); break; #ifdef CONFIG_KTAP_FFI case KTAP_TYPE_CDATA: kp_cdata_dump(ks, cdvalue(v)); break; #endif case KTAP_TYPE_EVENT: kp_transport_event_write(ks, evalue(v)); break; case KTAP_TYPE_BTRACE: btrace_dump(ks, btvalue(v)); break; case KTAP_TYPE_PTABLE: kp_ptab_dump(ks, phvalue(v)); break; case KTAP_TYPE_STATDATA: kp_statdata_dump(ks, sdvalue(v)); break; default: kp_error(ks, "print unknown value type: %d\n", ttype(v)); break; } }
void kp_showobj(ktap_state *ks, const ktap_value *v) { switch (ttype(v)) { case KTAP_TNIL: kp_puts(ks, "nil"); break; case KTAP_TNUMBER: kp_printf(ks, "%ld", nvalue(v)); break; case KTAP_TBOOLEAN: kp_puts(ks, (bvalue(v) == 1) ? "true" : "false"); break; case KTAP_TLIGHTUSERDATA: kp_printf(ks, "0x%lx", (unsigned long)pvalue(v)); break; case KTAP_TLCF: kp_printf(ks, "0x%lx", (unsigned long)fvalue(v)); break; case KTAP_TSHRSTR: case KTAP_TLNGSTR: kp_puts(ks, svalue(v)); break; case KTAP_TUSERDATA: kp_printf(ks, "0x%lx", (unsigned long)uvalue(v)); break; case KTAP_TTABLE: kp_table_dump(ks, hvalue(v)); break; #ifdef __KERNEL__ case KTAP_TEVENT: kp_transport_event_write(ks, evalue(v)); break; case KTAP_TBTRACE: kp_btrace_dump(ks, btvalue(v)); break; case KTAP_TAGGRTABLE: kp_aggrtable_dump(ks, ahvalue(v)); break; case KTAP_TAGGRACCVAL: kp_aggraccval_dump(ks, aggraccvalue(v)); break; #endif default: kp_error(ks, "print unknown value type: %d\n", ttype(v)); break; } }
/** * function ansi.set_color3 - Set the ansi Select Graphic Rendition mode. * @fg: Foreground color to set. * @bg: Background color to set. * @attr: Color attribute to set. * * Description: Sends ansi code for Select Graphic Rendition mode for the * given forground color, Black (30), Blue (34), Green (32), Cyan (36), * Red (31), Purple (35), Brown (33), Light Gray (37), the given * background color, Black (40), Red (41), Green (42), Yellow (43), * Blue (44), Magenta (45), Cyan (46), White (47) and the color attribute * All attributes off (0), Intensity Bold (1), Underline Single (4), * Blink Slow (5), Blink Rapid (6), Image Negative (7). */ static int ktap_lib_set_color3(ktap_state *ks) { int fg, bg, attr; kp_arg_check(ks, 1, KTAP_TNUMBER); kp_arg_check(ks, 2, KTAP_TNUMBER); kp_arg_check(ks, 3, KTAP_TNUMBER); fg = nvalue(kp_arg(ks, 1)); bg = nvalue(kp_arg(ks, 2)); attr = nvalue(kp_arg(ks, 3)); if (attr) kp_printf(ks, "\033[%d;%d;%dm", fg, bg, attr); else kp_printf(ks, "\033[%d;%dm", fg, bg); return 0; }
static int ktap_lib_set_color(ktap_state *ks) { int fg; kp_arg_check(ks, 1, KTAP_TNUMBER); fg = nvalue(kp_arg(ks, 1)); kp_printf(ks, "\033[%dm", fg); return 0; }
/* * ktap will not use lua's length operator on table meaning, * also # is not for length operator any more in ktap. */ int kp_obj_len(ktap_state *ks, const ktap_value *v) { switch(v->type) { case KTAP_TYPE_TABLE: return kp_tab_length(ks, hvalue(v)); case KTAP_TYPE_STRING: return rawtsvalue(v)->tsv.len; default: kp_printf(ks, "cannot get length of type %d\n", v->type); return -1; } return 0; }
/* * ktap will not use lua's length operator for table, * also # is not for length operator any more in ktap. */ int kp_obj_len(ktap_state_t *ks, const ktap_val_t *v) { switch(itype(v)) { case KTAP_TTAB: return kp_tab_len(ks, hvalue(v)); case KTAP_TSTR: return rawtsvalue(v)->len; default: kp_printf(ks, "cannot get length of type %d\n", v->type); return -1; } return 0; }
static void kp_btrace_dump(ktap_state *ks, ktap_btrace *bt) { char str[KSYM_SYMBOL_LEN]; int i; for (i = 0; i < bt->nr_entries; i++) { unsigned long p = bt->entries[i]; if (p == ULONG_MAX) break; SPRINT_SYMBOL(str, p); kp_printf(ks, "%s\n", str); } }
static int kplib_print_trace_clock(ktap_state_t *ks) { unsigned long long t; unsigned long secs, usec_rem; u64 timestamp; /* use ring buffer's timestamp */ timestamp = ring_buffer_time_stamp(G(ks)->buffer, smp_processor_id()); t = ns2usecs(timestamp); usec_rem = do_div(t, USEC_PER_SEC); secs = (unsigned long)t; kp_printf(ks, "%5lu.%06lu\n", secs, usec_rem); return 0; }
void kp_table_dump(ktap_State *ks, Table *t) { int i, count = 0; kp_printf(ks, "{"); for (i = 0; i < t->sizearray; i++) { Tvalue *v = &t->array[i]; if (isnil(v)) continue; if (count) kp_printf(ks, ", "); kp_printf(ks, "(%d: ", i + 1); kp_showobj(ks, v); kp_printf(ks, ")"); count++; } for (i = 0; i < sizenode(t); i++) { Node *n = &t->node[i]; if (isnil(gkey(n))) continue; if (count) kp_printf(ks, ", "); kp_printf(ks, "("); kp_showobj(ks, gkey(n)); kp_printf(ks, ": "); kp_showobj(ks, gval(n)); kp_printf(ks, ")"); count++; } kp_printf(ks, "}"); }
void *kp_zalloc(ktap_state *ks, int size) { void *addr; addr = kzalloc(size, KTAP_ALLOC_FLAGS); if (unlikely(!addr)) { kp_error(ks, "kzalloc size %d failed, retry again\n", size); printk("ktap kzalloc size %d failed, retry again\n", size); dump_stack(); while (1) { addr = kzalloc(size, KTAP_ALLOC_FLAGS); if (addr) break; } kp_printf(ks, "kzalloc retry success after failed, exit\n"); } return addr; }
void *kp_realloc(ktap_state *ks, void *addr, int newsize) { void *new_addr; new_addr = krealloc(addr, newsize, KTAP_ALLOC_FLAGS); if (unlikely(!new_addr)) { kp_error(ks, "krealloc size %d failed, retry again\n", newsize); printk("ktap krealloc size %d failed, retry again\n", newsize); dump_stack(); while (1) { new_addr = krealloc(addr, newsize, KTAP_ALLOC_FLAGS); if (new_addr) break; } kp_printf(ks, "krealloc retry success after failed, exit\n"); } return new_addr; }
void kp_showobj(ktap_State *ks, const Tvalue *v) { switch (ttype(v)) { case KTAP_TNIL: kp_printf(ks, "nil"); break; case KTAP_TNUMBER: kp_printf(ks, "%d", nvalue(v)); break; case KTAP_TBOOLEAN: kp_printf(ks, "%s", (bvalue(v) == 1) ? "true" : "false"); break; case KTAP_TLIGHTUSERDATA: kp_printf(ks, "%d", pvalue(v)); break; case KTAP_TLCF: kp_printf(ks, "0x%x", fvalue(v)); break; case KTAP_TSHRSTR: case KTAP_TLNGSTR: kp_printf(ks, "\"%s\"", getstr(rawtsvalue(v))); break; case KTAP_TUSERDATA: kp_printf(ks, "%d", uvalue(v)); break; case KTAP_TTABLE: kp_table_dump(ks, hvalue(v)); break; #ifdef __KERNEL__ case KTAP_TEVENT: kp_show_event(ks); break; #endif default: kp_printf(ks, "[unknown value type: %d]", ttype(v)); break; } }
void *kp_zalloc(ktap_state *ks, int size) { void *addr; addr = kzalloc(size, KTAP_ALLOC_FLAGS); if (unlikely(!addr)) { kp_error(ks, "kzalloc size %d failed, retry again\n", size); printk("ktap kzalloc size %d failed, retry again\n", size); dump_stack(); while (1) { addr = kzalloc(size, KTAP_ALLOC_FLAGS); if (addr) break; } kp_printf(ks, "kzalloc retry success after failed, exit\n"); } preempt_disable(); KTAP_STATS(ks)->nr_mem_allocate += 1; KTAP_STATS(ks)->mem_allocated += size; preempt_enable(); return addr; }
/** * function ansi.reset_color - Resets Select Graphic Rendition mode. * * Description: Sends ansi code to reset foreground, background and color * attribute to default values. */ static int kplib_ansi_reset_color(ktap_state_t *ks) { kp_printf(ks, "\033[0;0m"); return 0; }
static int kplib_ansi_clear_screen(ktap_state_t *ks) { kp_printf(ks, "\033[1;1H\033[J"); return 0; }
/* histogram: key should be number or string, value must be number */ void kp_table_histogram(ktap_State *ks, Table *t) { struct table_hist_record *thr; char dist_str[40]; int i, ratio, total = 0, count = 0; thr = kp_malloc(ks, sizeof(*thr) * (t->sizearray + sizenode(t))); for (i = 0; i < t->sizearray; i++) { Tvalue *v = &t->array[i]; if (isnil(v)) continue; if (!ttisnumber(v)) goto error; setnvalue(&thr[count++].key, i + 1); total += nvalue(v); } for (i = 0; i < sizenode(t); i++) { Node *n = &t->node[i]; int num; if (isnil(gkey(n))) continue; if (!ttisnumber(gval(n))) goto error; num = nvalue(gval(n)); setobj(ks, &thr[count].key, gkey(n)); setobj(ks, &thr[count].val, gval(n)); count++; total += nvalue(gval(n)); } sort(thr, count, sizeof(struct table_hist_record), hist_record_cmp, NULL); kp_printf(ks, "%32s%s%s\n", "value ", DISTRIBUTION_STR, " count"); dist_str[sizeof(dist_str) - 1] = '\0'; for (i = 0; i < count; i++) { Tvalue *key = &thr[i].key; Tvalue *val = &thr[i].val; memset(dist_str, ' ', sizeof(dist_str) - 1); ratio = (nvalue(val) * (sizeof(dist_str) - 1)) / total; memset(dist_str, '@', ratio); if (ttisstring(key)) { char buf[32 + 1] = {0}; char *keystr; if (strlen(svalue(key)) > 32) { strncpy(buf, svalue(key), 32-4); memset(buf + 32-4, '.', 3); keystr = buf; } else keystr = svalue(key); kp_printf(ks, "%32s |%s%-10d\n", keystr, dist_str, nvalue(val)); } else kp_printf(ks, "%32d | %s%-10d\n", nvalue(key), dist_str, nvalue(val)); } goto out; error: kp_printf(ks, "error: table histogram only handle " " (key: string/number val: number)\n"); out: kp_free(ks, thr); }
/** * function ansi.new_line - Move cursor to new line. * * Description: Sends ansi code new line. */ static int kplib_ansi_new_line (ktap_state_t *ks) { kp_printf(ks, "\12"); return 0; }
/** * function ansi.reset_color - Resets Select Graphic Rendition mode. * * Description: Sends ansi code to reset foreground, background and color * attribute to default values. */ static int ktap_lib_reset_color(ktap_state *ks) { kp_printf(ks, "\033[0;0m"); return 0; }
/** * function ansi.new_line - Move cursor to new line. * * Description: Sends ansi code new line. */ static int ktap_lib_new_line (ktap_state *ks) { kp_printf(ks, "\12"); return 0; }
static int ktap_lib_clear_screen(ktap_state *ks) { kp_printf(ks, "\033[1;1H\033[J"); return 0; }