📄 dt_consume.c
字号:
for (i = 0; i < depth && pc[i] != NULL; i++) { if ((err = dt_printf(dtp, fp, "%*s", indent, "")) < 0) break; if (P != NULL && Plookup_by_addr(P, pc[i], name, sizeof (name), &sym) == 0) { (void) Pobjname(P, pc[i], objname, sizeof (objname)); if (pc[i] > sym.st_value) { (void) snprintf(c, sizeof (c), "%s`%s+0x%llx", dt_basename(objname), name, (u_longlong_t)(pc[i] - sym.st_value)); } else { (void) snprintf(c, sizeof (c), "%s`%s", dt_basename(objname), name); } } else if (str != NULL && str[0] != '\0') { (void) snprintf(c, sizeof (c), "%s", str); } else { if (P != NULL && Pobjname(P, pc[i], objname, sizeof (objname)) != NULL) { (void) snprintf(c, sizeof (c), "%s`0x%llx", dt_basename(objname), (u_longlong_t)pc[i]); } else { (void) snprintf(c, sizeof (c), "0x%llx", (u_longlong_t)pc[i]); } } if (err < 0) break; if (dt_printf(dtp, fp, format, c) < 0) return (-1); if (dt_printf(dtp, fp, "\n") < 0) return (-1); if (str != NULL) { str += strlen(str) + 1; if (str - strbase >= strsize) str = NULL; } } if (P != NULL) { dt_proc_unlock(dtp, P); dt_proc_release(dtp, P); } return (err);}typedef struct dt_normal { dtrace_aggvarid_t dtnd_id; uint64_t dtnd_normal;} dt_normal_t;static intdt_normalize_agg(dtrace_aggdata_t *aggdata, void *arg){ dt_normal_t *normal = arg; dtrace_aggdesc_t *agg = aggdata->dtada_desc; dtrace_aggvarid_t id = normal->dtnd_id; uintptr_t data = (uintptr_t)aggdata->dtada_data; if (agg->dtagd_nrecs == 0) return (DTRACE_AGGWALK_NEXT); if (id != *(dtrace_aggvarid_t *)(data + agg->dtagd_rec[0].dtrd_offset)) return (DTRACE_AGGWALK_NEXT); aggdata->dtada_normal = normal->dtnd_normal; return (DTRACE_AGGWALK_NORMALIZE);}static intdt_normalize(dtrace_hdl_t *dtp, caddr_t base, dtrace_recdesc_t *rec){ dt_normal_t normal; caddr_t addr; /* * We (should) have two records: the aggregation ID followed by the * normalization value. */ addr = base + rec->dtrd_offset; if (rec->dtrd_size != sizeof (dtrace_aggvarid_t)) return (dt_set_errno(dtp, EDT_BADNORMAL)); /* LINTED - alignment */ normal.dtnd_id = *((dtrace_aggvarid_t *)addr); rec++; if (rec->dtrd_action != DTRACEACT_LIBACT) return (dt_set_errno(dtp, EDT_BADNORMAL)); if (rec->dtrd_arg != DT_ACT_NORMALIZE) return (dt_set_errno(dtp, EDT_BADNORMAL)); addr = base + rec->dtrd_offset; switch (rec->dtrd_size) { case sizeof (uint64_t): /* LINTED - alignment */ normal.dtnd_normal = *((uint64_t *)addr); break; case sizeof (uint32_t): /* LINTED - alignment */ normal.dtnd_normal = *((uint32_t *)addr); break; case sizeof (uint16_t): /* LINTED - alignment */ normal.dtnd_normal = *((uint16_t *)addr); break; case sizeof (uint8_t): normal.dtnd_normal = *((uint8_t *)addr); break; default: return (dt_set_errno(dtp, EDT_BADNORMAL)); } (void) dtrace_aggregate_walk(dtp, dt_normalize_agg, &normal); return (0);}static intdt_denormalize_agg(dtrace_aggdata_t *aggdata, void *arg){ dtrace_aggdesc_t *agg = aggdata->dtada_desc; dtrace_aggvarid_t id = *((dtrace_aggvarid_t *)arg); uintptr_t data = (uintptr_t)aggdata->dtada_data; if (agg->dtagd_nrecs == 0) return (DTRACE_AGGWALK_NEXT); if (id != *(dtrace_aggvarid_t *)(data + agg->dtagd_rec[0].dtrd_offset)) return (DTRACE_AGGWALK_NEXT); return (DTRACE_AGGWALK_DENORMALIZE);}static intdt_clear_agg(dtrace_aggdata_t *aggdata, void *arg){ dtrace_aggdesc_t *agg = aggdata->dtada_desc; dtrace_aggvarid_t id = *((dtrace_aggvarid_t *)arg); uintptr_t data = (uintptr_t)aggdata->dtada_data; if (agg->dtagd_nrecs == 0) return (DTRACE_AGGWALK_NEXT); if (id != *(dtrace_aggvarid_t *)(data + agg->dtagd_rec[0].dtrd_offset)) return (DTRACE_AGGWALK_NEXT); return (DTRACE_AGGWALK_CLEAR);}typedef struct dt_trunc { dtrace_aggvarid_t dttd_id; uint64_t dttd_remaining;} dt_trunc_t;static intdt_trunc_agg(dtrace_aggdata_t *aggdata, void *arg){ dt_trunc_t *trunc = arg; dtrace_aggdesc_t *agg = aggdata->dtada_desc; dtrace_aggvarid_t id = trunc->dttd_id; uintptr_t data = (uintptr_t)aggdata->dtada_data; if (agg->dtagd_nrecs == 0) return (DTRACE_AGGWALK_NEXT); if (id != *(dtrace_aggvarid_t *)(data + agg->dtagd_rec[0].dtrd_offset)) return (DTRACE_AGGWALK_NEXT); if (trunc->dttd_remaining == 0) return (DTRACE_AGGWALK_REMOVE); trunc->dttd_remaining--; return (DTRACE_AGGWALK_NEXT);}static intdt_trunc(dtrace_hdl_t *dtp, caddr_t base, dtrace_recdesc_t *rec){ dt_trunc_t trunc; caddr_t addr; int64_t remaining; int (*func)(dtrace_hdl_t *, dtrace_aggregate_f *, void *); /* * We (should) have two records: the aggregation ID followed by the * number of aggregation entries after which the aggregation is to be * truncated. */ addr = base + rec->dtrd_offset; if (rec->dtrd_size != sizeof (dtrace_aggvarid_t)) return (dt_set_errno(dtp, EDT_BADTRUNC)); /* LINTED - alignment */ trunc.dttd_id = *((dtrace_aggvarid_t *)addr); rec++; if (rec->dtrd_action != DTRACEACT_LIBACT) return (dt_set_errno(dtp, EDT_BADTRUNC)); if (rec->dtrd_arg != DT_ACT_TRUNC) return (dt_set_errno(dtp, EDT_BADTRUNC)); addr = base + rec->dtrd_offset; switch (rec->dtrd_size) { case sizeof (uint64_t): /* LINTED - alignment */ remaining = *((int64_t *)addr); break; case sizeof (uint32_t): /* LINTED - alignment */ remaining = *((int32_t *)addr); break; case sizeof (uint16_t): /* LINTED - alignment */ remaining = *((int16_t *)addr); break; case sizeof (uint8_t): remaining = *((int8_t *)addr); break; default: return (dt_set_errno(dtp, EDT_BADNORMAL)); } if (remaining < 0) { func = dtrace_aggregate_walk_valsorted; remaining = -remaining; } else { func = dtrace_aggregate_walk_valrevsorted; } assert(remaining >= 0); trunc.dttd_remaining = remaining; (void) func(dtp, dt_trunc_agg, &trunc); return (0);}intdt_print_agg(dtrace_aggdata_t *aggdata, void *arg){ int i, err = 0; dt_print_aggdata_t *pd = arg; dtrace_aggdesc_t *agg = aggdata->dtada_desc; FILE *fp = pd->dtpa_fp; dtrace_hdl_t *dtp = pd->dtpa_dtp; dtrace_aggvarid_t aggvarid = pd->dtpa_id; uintptr_t data = (uintptr_t)aggdata->dtada_data; if (pd->dtpa_allunprint) { if (agg->dtagd_flags & DTRACE_AGD_PRINTED) return (0); } else { /* * If we're not printing all unprinted aggregations, then the * aggregation variable ID denotes a specific aggregation * variable that we should print -- skip any other aggregations * that we encounter. */ if (agg->dtagd_nrecs == 0) return (0); if (aggvarid != *(dtrace_aggvarid_t *)(data + agg->dtagd_rec[0].dtrd_offset)) return (0); } /* * Iterate over each record description, printing the traced data, * skipping the first datum (the tuple member created by the compiler). */ for (i = 1; err >= 0 && i < agg->dtagd_nrecs; i++) { dtrace_recdesc_t *rec = &agg->dtagd_rec[i]; dtrace_actkind_t act = rec->dtrd_action; caddr_t addr = aggdata->dtada_data + rec->dtrd_offset; size_t size = rec->dtrd_size; uint64_t normal; normal = DTRACEACT_ISAGG(act) ? aggdata->dtada_normal : 1; if (act == DTRACEACT_STACK) { int depth = rec->dtrd_size / sizeof (pc_t); err = dt_print_stack(dtp, fp, NULL, addr, depth); goto nextrec; } if (act == DTRACEACT_USTACK || act == DTRACEACT_JSTACK) { err = dt_print_ustack(dtp, fp, NULL, addr, rec->dtrd_arg); goto nextrec; } if (act == DTRACEAGG_QUANTIZE) { err = dt_print_quantize(dtp, fp, addr, size, normal); goto nextrec; } if (act == DTRACEAGG_LQUANTIZE) { err = dt_print_lquantize(dtp, fp, addr, size, normal); goto nextrec; } if (act == DTRACEAGG_AVG) { err = dt_print_average(dtp, fp, addr, size, normal); goto nextrec; } switch (size) { case sizeof (uint64_t): err = dt_printf(dtp, fp, " %16lld", /* LINTED - alignment */ (long long)*((uint64_t *)addr) / normal); break; case sizeof (uint32_t): /* LINTED - alignment */ err = dt_printf(dtp, fp, " %8d", *((uint32_t *)addr) / (uint32_t)normal); break; case sizeof (uint16_t): /* LINTED - alignment */ err = dt_printf(dtp, fp, " %5d", *((uint16_t *)addr) / (uint32_t)normal); break; case sizeof (uint8_t): err = dt_printf(dtp, fp, " %3d", *((uint8_t *)addr) / (uint32_t)normal); break; default: err = dt_print_bytes(dtp, fp, addr, size, 50, 0); break; }nextrec: if (dt_buffered_flush(dtp, NULL, rec, aggdata) < 0) return (-1); } if (err >= 0) err = dt_printf(dtp, fp, "\n"); if (dt_buffered_flush(dtp, NULL, NULL, aggdata) < 0) return (-1); if (!pd->dtpa_allunprint) agg->dtagd_flags |= DTRACE_AGD_PRINTED; return (err < 0 ? -1 : 0);}static intdt_consume_cpu(dtrace_hdl_t *dtp, FILE *fp, int cpu, dtrace_bufdesc_t *buf, dtrace_consume_probe_f *efunc, dtrace_consume_rec_f *rfunc, void *arg){ dtrace_epid_t id; size_t offs, start = buf->dtbd_oldest, end = buf->dtbd_size; int flow = (dtp->dt_options[DTRACEOPT_FLOWINDENT] != DTRACEOPT_UNSET); int quiet = (dtp->dt_options[DTRACEOPT_QUIET] != DTRACEOPT_UNSET); int rval, i, n; dtrace_epid_t last = DTRACE_EPIDNONE; dtrace_probedata_t data; uint64_t drops; caddr_t addr; bzero(&data, sizeof (data)); data.dtpda_handle = dtp; data.dtpda_cpu = cpu;again: for (offs = start; offs < end; ) { dtrace_eprobedesc_t *epd; /* * We're guaranteed to have an ID. */ id = *(uint32_t *)((uintptr_t)buf->dtbd_data + offs); if (id == DTRACE_EPIDNONE) { /* * This is filler to assure proper alignment of the * next record; we simply ignore it. */ offs += sizeof (id); continue; } if ((rval = dt_epid_lookup(dtp, id, &data.dtpda_edesc, &data.dtpda_pdesc)) != 0) return (rval); epd = data.dtpda_edesc; data.dtpda_data = buf->dtbd_data + offs; if (data.dtpda_edesc->dtepd_uarg != DT_ECB_DEFAULT) { rval = dt_handle(dtp, &data); if (rval == DTRACE_CONSUME_NEXT) goto nextepid; if (rval == DTRACE_CONSUME_ERROR) return (-1); } if (flow) (void) dt_flowindent(dtp, &data, last, buf, offs); rval = (*efunc)(&data, arg); if (flow) { if (data.dtpda_flow == DTRACEFLOW_ENTRY) data.dtpda_indent += 2; } if (rval == DTRACE_CONSUME_NEXT) goto nextepid; if (rval == DTRACE_CONSUME_ABORT) return (dt_set_errno(dtp, EDT_DIRABORT)); if (rval != DTRACE_CONSUME_THIS) return (dt_set_errno(dtp, EDT_BADRVAL)); for (i = 0; i < epd->dtepd_nrecs; i++) { dtrace_recdesc_t *rec = &epd->dtepd_rec[i]; dtrace_actkind_t act = rec->dtrd_action; data.dtpda_data = buf->dtbd_data + offs + rec->dtrd_offset; addr = data.dtpda_data; if (act == DTRACEACT_LIBACT) { if (rec->dtrd_arg == DT_ACT_CLEAR) { dtrace_aggvarid_t id; /* LINTED - alignment */ id = *((dtrace_aggvarid_t *)addr); (void) dtrace_aggregate_walk(dtp, dt_clear_agg, &id); continue; } if (rec->dtrd_arg == DT_ACT_DENORMALIZE) { dtrace_aggvarid_t id; /* LINTED - alignment */ id = *((dtrace_aggvarid_t *)addr); (void) dtrace_aggregate_walk(dtp, dt_denormalize_agg, &id); continue; } if (rec->dtrd_arg == DT_ACT_NORMALIZE) { if (i == epd->dtepd_nrecs - 1) return (dt_set_errno(dtp, EDT_BADNORMAL));
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -