static int fmd_trace(uintptr_t tid, uint_t flags, int argc, const mdb_arg_t *argv) { int (*func)(uintptr_t, const fmd_tracerec_t *, uintptr_t); uint_t opt_c = FALSE, opt_s = FALSE; if (mdb_getopts(argc, argv, 'c', MDB_OPT_SETBITS, TRUE, &opt_c, 's', MDB_OPT_SETBITS, TRUE, &opt_s, NULL) != argc) return (DCMD_USAGE); if (!(flags & DCMD_ADDRSPEC)) { mdb_printf("TID "); tid = 0; } if (opt_c) { mdb_printf("%-16s %-4s FILE:LINE\n", "TIME", "TAG"); func = opt_s ? trprint_cpp_stack : trprint_cpp; } else { mdb_printf("%-16s %-4s %-5s MSG\n", "TIME", "TAG", "ERRNO"); func = opt_s ? trprint_msg_stack : trprint_msg; } if (mdb_walk("fmd_trace", (mdb_walk_cb_t)func, (void *)tid) == -1) { mdb_warn("failed to walk fmd_trace"); return (DCMD_ERR); } return (DCMD_OK); }
/*ARGSUSED*/ static int fmd_serd(uintptr_t addr, uint_t flags, int argc, const mdb_arg_t *argv) { char name[PATH_MAX]; fmd_serd_eng_t sg; if (argc != 0) return (DCMD_USAGE); if (!(flags & DCMD_ADDRSPEC)) { if (mdb_walk("fmd_module", module_serd, 0) == -1) { mdb_warn("failed to walk 'fmd_module'"); return (DCMD_ERR); } return (DCMD_OK); } if (mdb_vread(&sg, sizeof (sg), addr) != sizeof (sg)) { mdb_warn("failed to read fmd_serd_eng at %p", addr); return (DCMD_ERR); } if (DCMD_HDRSPEC(flags)) { mdb_printf("%<u>%-11s %-32s %-3s F >%-2s %-16s%</u>\n", "ADDR", "NAME", "CNT", "N", "T"); } if (mdb_readstr(name, sizeof (name), (uintptr_t)sg.sg_name) <= 0) (void) mdb_snprintf(name, sizeof (name), "<%p>", sg.sg_name); mdb_printf("%-11p %-32s %-3u %c >%-2u %lluns\n", addr, name, sg.sg_count, (sg.sg_flags & FMD_SERD_FIRED) ? 'F' : ' ', sg.sg_n, (u_longlong_t)sg.sg_t); return (DCMD_OK); }
/*ARGSUSED*/ static int umastat_lwp(uintptr_t addr, const ulwp_t *ulwp, void *ignored) { size_t size; datafmt_t *dfp = ptcfmt; mdb_printf((dfp++)->fmt, ulwp->ul_lwpid); mdb_printf((dfp++)->fmt, ulwp->ul_tmem.tm_size); if (umem_readvar(&size, "umem_ptc_size") == -1) { mdb_warn("unable to read 'umem_ptc_size'"); return (WALK_ERR); } mdb_printf((dfp++)->fmt, (ulwp->ul_tmem.tm_size * 100) / size); if (mdb_walk("umem_cache", (mdb_walk_cb_t)umastat_lwp_cache, (void *)ulwp) == -1) { mdb_warn("can't walk 'umem_cache'"); return (WALK_ERR); } mdb_printf("\n"); return (WALK_NEXT); }
int stmf_sbd_lu(uintptr_t addr, uint_t flags, int argc, const mdb_arg_t *argv) { uint_t verbose = FALSE; sbd_lu_t slu; stmf_sbd_cb_t cb_st = {0}; if (mdb_getopts(argc, argv, 'v', MDB_OPT_SETBITS, TRUE, &verbose, NULL) != argc) return (DCMD_USAGE); if (verbose) cb_st.flag |= STMF_SBD_VERBOSE; if (flags & DCMD_ADDRSPEC) { cb_st.flag |= STMF_SBD_VERBOSE; if (mdb_vread(&slu, sizeof (sbd_lu_t), addr) == -1) { mdb_warn("failed to read sbd_lu_t at %p\n", addr); return (DCMD_ERR); } if (stmf_sbd_lu_cb(addr, &slu, &cb_st) == WALK_ERR) return (DCMD_ERR); } else { if (mdb_walk("stmf_sbd_lu", (mdb_walk_cb_t)stmf_sbd_lu_cb, &cb_st) == -1) { mdb_warn("failed to walk sbd_lu_list\n"); return (DCMD_ERR); } } return (DCMD_OK); }
/*ARGSUSED*/ static int whatis_run_ulwps(mdb_whatis_t *w, void *arg) { if (mdb_walk("ulwps", (mdb_walk_cb_t)whatis_walk_ulwp, w) == -1) { mdb_warn("couldn't find ulwps walker"); return (1); } return (0); }
/*ARGSUSED*/ static int fcf_sec(uintptr_t addr, uint_t flags, int argc, const mdb_arg_t *argv) { static const char *const types[] = { "none", /* FCF_SECT_NONE */ "strtab", /* FCF_SECT_STRTAB */ "module", /* FCF_SECT_MODULE */ "case", /* FCF_SECT_CASE */ "bufs", /* FCF_SECT_BUFS */ "buffer", /* FCF_SECT_BUFFER */ "serd", /* FCF_SECT_SERD */ "events", /* FCF_SECT_EVENTS */ "nvlists", /* FCF_SECT_NVLISTS */ }; uint_t sec = 0; fcf_sec_t s; if (!(flags & DCMD_ADDRSPEC)) mdb_printf("%<u>%-3s ", "NDX"); if (!(flags & DCMD_ADDRSPEC) || DCMD_HDRSPEC(flags)) { mdb_printf("%<u>%?s %-10s %-5s %-5s %-5s %-6s %-5s%</u>\n", "ADDR", "TYPE", "ALIGN", "FLAGS", "ENTSZ", "OFF", "SIZE"); } if (!(flags & DCMD_ADDRSPEC)) { if (mdb_walk("fcf_sec", (mdb_walk_cb_t)fcf_sec_one, &sec) < 0) { mdb_warn("failed to walk fcf_sec"); return (DCMD_ERR); } return (DCMD_OK); } if (argc != 0) return (DCMD_USAGE); if (mdb_vread(&s, sizeof (s), addr) != sizeof (s)) { mdb_warn("failed to read section header at %p", addr); return (DCMD_ERR); } mdb_printf("%?p ", addr); if (s.fcfs_type < sizeof (types) / sizeof (types[0])) mdb_printf("%-10s ", types[s.fcfs_type]); else mdb_printf("%-10u ", s.fcfs_type); mdb_printf("%-5u %-#5x %-#5x %-6llx %-#5llx\n", s.fcfs_align, s.fcfs_flags, s.fcfs_entsize, s.fcfs_offset, s.fcfs_size); return (DCMD_OK); }
/*ARGSUSED*/ int zid2zone(uintptr_t addr, uint_t flags, int argc, const mdb_arg_t *argv) { if (!(flags & DCMD_ADDRSPEC) || argc != 0) return (DCMD_USAGE); if (mdb_walk("zone", (mdb_walk_cb_t)zid_lookup_cb, &addr) == -1) { mdb_warn("failed to walk zone"); return (DCMD_ERR); } return (DCMD_OK); }
static int netstat_print_conn(const char *cache, int proto, mdb_walk_cb_t cbfunc, void *cbdata) { netstat_cb_data_t *ncb = cbdata; if ((ncb->opts & NETSTAT_VERBOSE) && proto == IPPROTO_TCP) netstat_tcp_verbose_header_pr(); if (mdb_walk(cache, cbfunc, cbdata) == -1) { mdb_warn("failed to walk %s", cache); return (DCMD_ERR); } return (DCMD_OK); }
/*ARGSUSED*/ int dof_sec(uintptr_t addr, uint_t flags, int argc, const mdb_arg_t *argv) { const char *name; dof_sec_t s; if (!(flags & DCMD_ADDRSPEC)) mdb_printf("%<u>%-3s ", "NDX"); if (!(flags & DCMD_ADDRSPEC) || DCMD_HDRSPEC(flags)) { mdb_printf("%<u>%?s %-10s %-5s %-5s %-5s %-6s %-5s%</u>\n", "ADDR", "TYPE", "ALIGN", "FLAGS", "ENTSZ", "OFFSET", "SIZE"); } if (!(flags & DCMD_ADDRSPEC)) { int sec = 0; if (mdb_walk("dof_sec", (mdb_walk_cb_t)dof_sec_walk, &sec) == -1) { mdb_warn("failed to walk dof_sec"); return (DCMD_ERR); } return (DCMD_OK); } if (argc != 0) return (DCMD_USAGE); if (mdb_vread(&s, sizeof (s), addr) != sizeof (s)) { mdb_warn("failed to read section header at %p", addr); return (DCMD_ERR); } mdb_printf("%?p ", addr); if ((name = dof_sec_name(s.dofs_type)) != NULL) mdb_printf("%-10s ", name); else mdb_printf("%-10u ", s.dofs_type); mdb_printf("%-5u %-#5x %-#5x %-6llx %-#5llx\n", s.dofs_align, s.dofs_flags, s.dofs_entsize, s.dofs_offset, s.dofs_size); return (DCMD_OK); }
/*ARGSUSED*/ int snode(uintptr_t addr, uint_t flags, int argc, const mdb_arg_t *argv) { snode_cbdata_t sd; struct snode snode; uintptr_t major = 0, dev = 0; sd.sd_major = -1; sd.sd_minor = -1; sd.sd_verbose = !(flags & DCMD_PIPE_OUT); if (mdb_getopts(argc, argv, 'm', MDB_OPT_UINTPTR, &major, 'd', MDB_OPT_UINTPTR, &dev, NULL) != argc) return (DCMD_USAGE); if (dev != 0) { sd.sd_major = getmajor(dev); sd.sd_minor = getminor(dev); } if (major != 0) sd.sd_major = major; if (DCMD_HDRSPEC(flags) && !(flags & DCMD_PIPE_OUT)) { mdb_printf("%<u>%?s %?s %6s %16s %-15s%</u>\n", "ADDR", "VNODE", "COUNT", "DEV", "FLAG"); } if (!(flags & DCMD_ADDRSPEC)) { if (mdb_walk("snode", (mdb_walk_cb_t)snode_cb, &sd) == -1) { mdb_warn("can't walk snodes"); return (DCMD_ERR); } return (DCMD_OK); } if (mdb_vread(&snode, sizeof (snode), addr) == -1) { mdb_warn("failed to read snode structure at %p", addr); return (DCMD_ERR); } snode_cb(addr, &snode, &sd); return (DCMD_OK); }
int kgrep_subr(kgrep_cb_func *cb, void *cbdata) { ugrep_walk_data_t ug; prockludge_add_walkers(); ug.ug_cb = cb; ug.ug_cbdata = cbdata; if (mdb_walk(KLUDGE_MAPWALK_NAME, ugrep_mapping_cb, &ug) == -1) { mdb_warn("Unable to walk "KLUDGE_MAPWALK_NAME); return (DCMD_ERR); } prockludge_remove_walkers(); return (DCMD_OK); }
static int tid2ulwp_impl(uintptr_t tid_addr, uintptr_t *ulwp_addrp) { tid2ulwp_walk_t t2u; bzero(&t2u, sizeof (t2u)); t2u.t2u_tid = (lwpid_t)tid_addr; if (mdb_walk("ulwp", (mdb_walk_cb_t)tid2ulwp_walk, &t2u) != 0) { mdb_warn("can't walk 'ulwp'"); return (DCMD_ERR); } if (!t2u.t2u_found) { mdb_warn("thread ID %d not found", t2u.t2u_tid); return (DCMD_ERR); } *ulwp_addrp = t2u.t2u_lwp; return (DCMD_OK); }
static int fmd_ustat(uintptr_t addr, uint_t flags, int argc, const mdb_arg_t *argv) { if (!(flags & DCMD_ADDRSPEC)) { struct fmd_cmd_data ud; ud.argc = argc; ud.argv = argv; if (mdb_walk("fmd_module", module_ustat, &ud) == -1) { mdb_warn("failed to walk 'fmd_module'"); return (DCMD_ERR); } return (DCMD_OK); } if (mdb_pwalk_dcmd("fmd_ustat", "fmd_stat", argc, argv, addr) != 0) { mdb_warn("failed to walk fmd_ustat at %p", addr); return (DCMD_ERR); } return (DCMD_OK); }
/*ARGSUSED*/ static int py_stack(uintptr_t addr, uint_t flags, int argc, const mdb_arg_t *argv) { uint_t verbose = FALSE; if (mdb_getopts(argc, argv, 'v', MDB_OPT_SETBITS, TRUE, &verbose, NULL) != argc) return (DCMD_USAGE); if (flags & DCMD_PIPE_OUT) { mdb_warn("py_stack cannot output into a pipe\n"); return (DCMD_ERR); } if (flags & DCMD_ADDRSPEC) { mdb_arg_t nargv; uint_t nargc = verbose ? 1 : 0; nargv.a_type = MDB_TYPE_STRING; nargv.a_un.a_str = "-v"; if (mdb_pwalk_dcmd("pyframe", "pyframe", nargc, &nargv, addr) == -1) { mdb_warn("can't walk 'pyframe'"); return (DCMD_ERR); } return (DCMD_OK); } if (mdb_walk("pyinterp", (mdb_walk_cb_t)python_thread, &verbose) == -1) { mdb_warn("can't walk 'pyinterp'"); return (DCMD_ERR); } return (DCMD_OK); }
static int umastat_cache(uintptr_t addr, const umem_cache_t *cp, umastat_vmem_t **kvp) { umastat_vmem_t *kv; datafmt_t *dfp = umemfmt; char buf[10]; int magsize; int avail, alloc, total, nptc = 0; size_t meminuse = (cp->cache_slab_create - cp->cache_slab_destroy) * cp->cache_slabsize; mdb_walk_cb_t cpu_avail = (mdb_walk_cb_t)umastat_cpu_avail; mdb_walk_cb_t cpu_alloc = (mdb_walk_cb_t)umastat_cpu_alloc; mdb_walk_cb_t slab_avail = (mdb_walk_cb_t)umastat_slab_avail; magsize = umem_get_magsize(cp); alloc = cp->cache_slab_alloc + cp->cache_full.ml_alloc; avail = cp->cache_full.ml_total * magsize; total = cp->cache_buftotal; (void) mdb_pwalk("umem_cpu_cache", cpu_alloc, &alloc, addr); (void) mdb_pwalk("umem_cpu_cache", cpu_avail, &avail, addr); (void) mdb_pwalk("umem_slab_partial", slab_avail, &avail, addr); if (cp->cache_flags & UMF_PTC) { char walk[60]; (void) snprintf(walk, sizeof (walk), "umem_ptc_%d", cp->cache_bufsize); if (mdb_walk(walk, (mdb_walk_cb_t)umastat_cache_ptc, &nptc) == -1) { mdb_warn("unable to walk '%s'", walk); return (WALK_ERR); } (void) snprintf(buf, sizeof (buf), "%d", nptc); } for (kv = *kvp; kv != NULL; kv = kv->kv_next) { if (kv->kv_addr == (uintptr_t)cp->cache_arena) goto out; } kv = mdb_zalloc(sizeof (umastat_vmem_t), UM_SLEEP | UM_GC); kv->kv_next = *kvp; kv->kv_addr = (uintptr_t)cp->cache_arena; *kvp = kv; out: kv->kv_meminuse += meminuse; kv->kv_alloc += alloc; kv->kv_fail += cp->cache_alloc_fail; mdb_printf((dfp++)->fmt, cp->cache_name); mdb_printf((dfp++)->fmt, cp->cache_bufsize); mdb_printf((dfp++)->fmt, total - avail); mdb_printf((dfp++)->fmt, cp->cache_flags & UMF_PTC ? buf : "-"); mdb_printf((dfp++)->fmt, total); mdb_printf((dfp++)->fmt, meminuse); mdb_printf((dfp++)->fmt, alloc); mdb_printf((dfp++)->fmt, cp->cache_alloc_fail); mdb_printf("\n"); return (WALK_NEXT); }
/* ARGSUSED */ int memstat(uintptr_t addr, uint_t flags, int argc, const mdb_arg_t *argv) { pgcnt_t total_pages, physmem; ulong_t freemem; memstat_t stats; GElf_Sym sym; vn_htable_t ht; struct vnode *kvps; uintptr_t vn_size = 0; #if defined(__i386) || defined(__amd64) bln_stats_t bln_stats; ssize_t bln_size; #endif bzero(&stats, sizeof (memstat_t)); /* * -s size, is an internal option. It specifies the size of vn_htable. * Hash table size is set in the following order: * If user has specified the size that is larger than VN_LARGE: try it, * but if malloc failed default to VN_SMALL. Otherwise try VN_LARGE, if * failed to allocate default to VN_SMALL. * For a better efficiency of hash table it is highly recommended to * set size to a prime number. */ if ((flags & DCMD_ADDRSPEC) || mdb_getopts(argc, argv, 's', MDB_OPT_UINTPTR, &vn_size, NULL) != argc) return (DCMD_USAGE); /* Initialize vnode hash list and queue */ vn_htable_init(&ht, vn_size); stats.ms_vn_htable = &ht; /* Total physical memory */ if (mdb_readvar(&total_pages, "total_pages") == -1) { mdb_warn("unable to read total_pages"); return (DCMD_ERR); } /* Artificially limited memory */ if (mdb_readvar(&physmem, "physmem") == -1) { mdb_warn("unable to read physmem"); return (DCMD_ERR); } /* read kernel vnode array pointer */ if (mdb_lookup_by_obj(MDB_OBJ_EXEC, "kvps", (GElf_Sym *)&sym) == -1) { mdb_warn("unable to read kvps"); return (DCMD_ERR); } kvps = (struct vnode *)(uintptr_t)sym.st_value; stats.ms_kvp = &kvps[KV_KVP]; /* * Read the zio vnode pointer. */ stats.ms_zvp = &kvps[KV_ZVP]; /* * If physmem != total_pages, then the administrator has limited the * number of pages available in the system. Excluded pages are * associated with the unused pages vnode. Read this vnode so the * pages can be excluded in the page accounting. */ if (mdb_lookup_by_obj(MDB_OBJ_EXEC, "unused_pages_vp", (GElf_Sym *)&sym) == -1) { mdb_warn("unable to read unused_pages_vp"); return (DCMD_ERR); } stats.ms_unused_vp = (struct vnode *)(uintptr_t)sym.st_value; /* walk all pages, collect statistics */ if (mdb_walk("allpages", (mdb_walk_cb_t)memstat_callback, &stats) == -1) { mdb_warn("can't walk memseg"); return (DCMD_ERR); } #define MS_PCT_TOTAL(x) ((ulong_t)((((5 * total_pages) + ((x) * 1000ull))) / \ ((physmem) * 10))) mdb_printf("Page Summary Pages MB" " %%Tot\n"); mdb_printf("------------ ---------------- ----------------" " ----\n"); mdb_printf("Kernel %16llu %16llu %3lu%%\n", stats.ms_kmem, (uint64_t)stats.ms_kmem * PAGESIZE / (1024 * 1024), MS_PCT_TOTAL(stats.ms_kmem)); if (stats.ms_zfs_data != 0) mdb_printf("ZFS File Data %16llu %16llu %3lu%%\n", stats.ms_zfs_data, (uint64_t)stats.ms_zfs_data * PAGESIZE / (1024 * 1024), MS_PCT_TOTAL(stats.ms_zfs_data)); mdb_printf("Anon %16llu %16llu %3lu%%\n", stats.ms_anon, (uint64_t)stats.ms_anon * PAGESIZE / (1024 * 1024), MS_PCT_TOTAL(stats.ms_anon)); mdb_printf("Exec and libs %16llu %16llu %3lu%%\n", stats.ms_exec, (uint64_t)stats.ms_exec * PAGESIZE / (1024 * 1024), MS_PCT_TOTAL(stats.ms_exec)); mdb_printf("Page cache %16llu %16llu %3lu%%\n", stats.ms_vnode, (uint64_t)stats.ms_vnode * PAGESIZE / (1024 * 1024), MS_PCT_TOTAL(stats.ms_vnode)); mdb_printf("Free (cachelist) %16llu %16llu %3lu%%\n", stats.ms_cachelist, (uint64_t)stats.ms_cachelist * PAGESIZE / (1024 * 1024), MS_PCT_TOTAL(stats.ms_cachelist)); /* * occasionally, we double count pages above. To avoid printing * absurdly large values for freemem, we clamp it at zero. */ if (physmem > stats.ms_total) freemem = physmem - stats.ms_total; else freemem = 0; #if defined(__i386) || defined(__amd64) /* Are we running under Xen? If so, get balloon memory usage. */ if ((bln_size = mdb_readvar(&bln_stats, "bln_stats")) != -1) { if (freemem > bln_stats.bln_hv_pages) freemem -= bln_stats.bln_hv_pages; else freemem = 0; } #endif mdb_printf("Free (freelist) %16lu %16llu %3lu%%\n", freemem, (uint64_t)freemem * PAGESIZE / (1024 * 1024), MS_PCT_TOTAL(freemem)); #if defined(__i386) || defined(__amd64) if (bln_size != -1) { mdb_printf("Balloon %16lu %16llu %3lu%%\n", bln_stats.bln_hv_pages, (uint64_t)bln_stats.bln_hv_pages * PAGESIZE / (1024 * 1024), MS_PCT_TOTAL(bln_stats.bln_hv_pages)); } #endif mdb_printf("\nTotal %16lu %16lu\n", physmem, (uint64_t)physmem * PAGESIZE / (1024 * 1024)); if (physmem != total_pages) { mdb_printf("Physical %16lu %16lu\n", total_pages, (uint64_t)total_pages * PAGESIZE / (1024 * 1024)); } #undef MS_PCT_TOTAL return (DCMD_OK); }
static int request_log_walk_init(mdb_walk_state_t *wsp) { struct request_log_walk *rlw; struct request_entry *list, *listp; uint_t log_size; uint_t size; uint_t idx; uint_t pos; request_log_entry_t *base; request_log_entry_t cur; if (mdb_readvar(&base, "request_log") == -1) { mdb_warn("couldn't read 'request_log'"); return (WALK_ERR); } if (mdb_readvar(&log_size, "request_log_size") == -1) { mdb_warn("couldn't read 'request_log_size'"); return (WALK_ERR); } size = log_size; if (mdb_walk("configd_threads", (mdb_walk_cb_t)request_log_count_thread, &size) == -1) { mdb_warn("couldn't walk 'configd_threads'"); return (WALK_ERR); } list = mdb_zalloc(sizeof (*list) * size, UM_SLEEP); listp = list; if (mdb_walk("configd_threads", (mdb_walk_cb_t)request_log_add_thread, &listp) == -1) { mdb_warn("couldn't walk 'configd_threads'"); mdb_free(list, sizeof (*list) * size); return (WALK_ERR); } pos = listp - list; for (idx = 0; idx < log_size; idx++) { uintptr_t addr = (uintptr_t)&base[idx]; if (mdb_vread(&cur, sizeof (cur), addr) == -1) { mdb_warn("couldn't read log entry at %p", addr); mdb_free(list, sizeof (*list) * size); return (WALK_ERR); } if (max_time_seen < cur.rl_start) max_time_seen = cur.rl_start; if (max_time_seen < cur.rl_end) max_time_seen = cur.rl_end; if (cur.rl_start != 0) { list[pos].timestamp = cur.rl_start; list[pos].addr = addr; pos++; } } qsort(list, pos, sizeof (*list), &request_entry_compare); rlw = mdb_zalloc(sizeof (*rlw), UM_SLEEP); rlw->rlw_max = size; rlw->rlw_count = pos; rlw->rlw_cur = 0; rlw->rlw_list = list; wsp->walk_data = rlw; return (WALK_NEXT); }
/*ARGSUSED*/ static int fmd_stat(uintptr_t addr, uint_t flags, int argc, const mdb_arg_t *argv) { char buf[512]; fmd_stat_t s; if (argc != 0) return (DCMD_USAGE); if (DCMD_HDRSPEC(flags)) mdb_printf("%<u>%-11s %-4s %-32s %s%</u>\n", "ADDR", "TYPE", "NAME", "VALUE"); if (!(flags & DCMD_ADDRSPEC)) { struct fmd_cmd_data ud; ud.argc = argc; ud.argv = argv; if (mdb_walk("fmd_module", module_stat, &ud) == -1) { mdb_warn("failed to walk 'fmd_module'"); return (DCMD_ERR); } return (DCMD_OK); } if (mdb_vread(&s, sizeof (s), addr) != sizeof (s)) { mdb_warn("failed to read statistic at %p", addr); return (DCMD_ERR); } switch (s.fmds_type) { case FMD_TYPE_BOOL: mdb_printf("%-11p %-4s %-32s %s\n", addr, "bool", s.fmds_name, s.fmds_value.bool ? "true" : "false"); break; case FMD_TYPE_INT32: mdb_printf("%-11p %-4s %-32s %d\n", addr, "i32", s.fmds_name, s.fmds_value.i32); break; case FMD_TYPE_UINT32: mdb_printf("%-11p %-4s %-32s %u\n", addr, "ui32", s.fmds_name, s.fmds_value.i32); break; case FMD_TYPE_INT64: mdb_printf("%-11p %-4s %-32s %lld\n", addr, "i64", s.fmds_name, s.fmds_value.i64); break; case FMD_TYPE_UINT64: mdb_printf("%-11p %-4s %-32s %llu\n", addr, "ui64", s.fmds_name, s.fmds_value.ui64); break; case FMD_TYPE_STRING: if (mdb_readstr(buf, sizeof (buf), (uintptr_t)s.fmds_value.str) < 0) { (void) mdb_snprintf(buf, sizeof (buf), "<%p>", s.fmds_value.str); } mdb_printf("%-11p %-4s %-32s %s\n", addr, "str", s.fmds_name, buf); break; case FMD_TYPE_TIME: mdb_printf("%-11p %-4s %-32s %llu\n", addr, "time", s.fmds_name, s.fmds_value.ui64); break; case FMD_TYPE_SIZE: mdb_printf("%-11p %-4s %-32s %llu\n", addr, "size", s.fmds_name, s.fmds_value.ui64); break; default: mdb_printf("%-11p %-4u %-32s ???\n", addr, s.fmds_type, s.fmds_name); break; } return (DCMD_OK); }
/*ARGSUSED*/ int umastat(uintptr_t addr, uint_t flags, int argc, const mdb_arg_t *argv) { umastat_vmem_t *kv = NULL; datafmt_t *dfp; int nptc = 0, i; if (argc != 0) return (DCMD_USAGE); /* * We need to determine if we have any caches that have per-thread * caching enabled. */ if (mdb_walk("umem_cache", (mdb_walk_cb_t)umastat_cache_nptc, &nptc) == -1) { mdb_warn("can't walk 'umem_cache'"); return (DCMD_ERR); } if (nptc) { for (dfp = ptcfmt; dfp->hdr2 != NULL; dfp++) mdb_printf("%s ", dfp->hdr1); for (i = 0; i < nptc; i++) mdb_printf("%s ", dfp->hdr1); mdb_printf("\n"); for (dfp = ptcfmt; dfp->hdr2 != NULL; dfp++) mdb_printf("%s ", dfp->hdr2); if (mdb_walk("umem_cache", (mdb_walk_cb_t)umastat_cache_hdr, NULL) == -1) { mdb_warn("can't walk 'umem_cache'"); return (DCMD_ERR); } mdb_printf("\n"); for (dfp = ptcfmt; dfp->hdr2 != NULL; dfp++) mdb_printf("%s ", dfp->dashes); for (i = 0; i < nptc; i++) mdb_printf("%s ", dfp->dashes); mdb_printf("\n"); if (mdb_walk("ulwp", (mdb_walk_cb_t)umastat_lwp, NULL) == -1) { mdb_warn("can't walk 'ulwp'"); return (DCMD_ERR); } mdb_printf("\n"); } for (dfp = umemfmt; dfp->hdr1 != NULL; dfp++) mdb_printf("%s%s", dfp == umemfmt ? "" : " ", dfp->hdr1); mdb_printf("\n"); for (dfp = umemfmt; dfp->hdr1 != NULL; dfp++) mdb_printf("%s%s", dfp == umemfmt ? "" : " ", dfp->hdr2); mdb_printf("\n"); for (dfp = umemfmt; dfp->hdr1 != NULL; dfp++) mdb_printf("%s%s", dfp == umemfmt ? "" : " ", dfp->dashes); mdb_printf("\n"); if (mdb_walk("umem_cache", (mdb_walk_cb_t)umastat_cache, &kv) == -1) { mdb_warn("can't walk 'umem_cache'"); return (DCMD_ERR); } for (dfp = umemfmt; dfp->hdr1 != NULL; dfp++) mdb_printf("%s%s", dfp == umemfmt ? "" : " ", dfp->dashes); mdb_printf("\n"); if (mdb_walk("vmem", (mdb_walk_cb_t)umastat_vmem_totals, kv) == -1) { mdb_warn("can't walk 'vmem'"); return (DCMD_ERR); } for (dfp = umemfmt; dfp->hdr1 != NULL; dfp++) mdb_printf("%s ", dfp->dashes); mdb_printf("\n"); mdb_printf("\n"); for (dfp = vmemfmt; dfp->hdr1 != NULL; dfp++) mdb_printf("%s ", dfp->hdr1); mdb_printf("\n"); for (dfp = vmemfmt; dfp->hdr1 != NULL; dfp++) mdb_printf("%s ", dfp->hdr2); mdb_printf("\n"); for (dfp = vmemfmt; dfp->hdr1 != NULL; dfp++) mdb_printf("%s ", dfp->dashes); mdb_printf("\n"); if (mdb_walk("vmem", (mdb_walk_cb_t)umastat_vmem, NULL) == -1) { mdb_warn("can't walk 'vmem'"); return (DCMD_ERR); } for (dfp = vmemfmt; dfp->hdr1 != NULL; dfp++) mdb_printf("%s ", dfp->dashes); mdb_printf("\n"); return (DCMD_OK); }
int stacks_run(int verbose, mdb_pipe_t *tlist) { stacks_info_t si; findstack_info_t *fsip = &si.si_fsi; size_t idx; stacks_entry_t **cur; bzero(&si, sizeof (si)); stacks_state = STACKS_STATE_DIRTY; stacks_hash = si.si_hash = mdb_zalloc(STACKS_HSIZE * sizeof (*si.si_hash), UM_SLEEP); si.si_entries = 0; si.si_count = 0; fsip->fsi_max_depth = STACKS_MAX_DEPTH; fsip->fsi_stack = mdb_alloc(fsip->fsi_max_depth * sizeof (*fsip->fsi_stack), UM_SLEEP | UM_GC); if (verbose) mdb_warn("stacks: processing kernel threads\n"); if (tlist != NULL) { if (stacks_run_tlist(tlist, &si)) return (DCMD_ERR); } else { if (mdb_walk("thread", stacks_thread_cb, &si) != 0) { mdb_warn("cannot walk \"thread\""); return (DCMD_ERR); } } if (verbose) mdb_warn("stacks: %d unique stacks / %d threads\n", si.si_entries, si.si_count); stacks_array_size = si.si_entries; stacks_array = mdb_zalloc(si.si_entries * sizeof (*stacks_array), UM_SLEEP); cur = stacks_array; for (idx = 0; idx < STACKS_HSIZE; idx++) { stacks_entry_t *sep; for (sep = si.si_hash[idx]; sep != NULL; sep = sep->se_next) *(cur++) = sep; } if (cur != stacks_array + si.si_entries) { mdb_warn("stacks: miscounted array size (%d != size: %d)\n", (cur - stacks_array), stacks_array_size); return (DCMD_ERR); } qsort(stacks_array, si.si_entries, sizeof (*stacks_array), stacks_entry_comp); /* Now that we're done, free the hash table */ stacks_hash = NULL; mdb_free(si.si_hash, STACKS_HSIZE * sizeof (*si.si_hash)); if (tlist == NULL) stacks_state = STACKS_STATE_DONE; if (verbose) mdb_warn("stacks: done\n"); return (DCMD_OK); }
/* * Print out all project, task, and process rctls for a given process. * If a handle is specified, print only the rctl matching that handle * for the process. */ int rctl_list(uintptr_t addr, uint_t flags, int argc, const mdb_arg_t *argv) { proc_t proc; uintptr_t set; task_t task; kproject_t proj; zone_t zone; dict_data_t rdict; int i; rdict.dict_addr = NULL; if (!(flags & DCMD_ADDRSPEC)) return (DCMD_USAGE); if (argc == 0) rdict.hndl = 0; else if (argc == 1) { /* * User specified a handle. Go find the rctl_dict_entity_t * structure so we know what type of rctl to look for. */ const mdb_arg_t *argp = &argv[0]; if (argp->a_type == MDB_TYPE_IMMEDIATE) rdict.hndl = (rctl_hndl_t)argp->a_un.a_val; else rdict.hndl = (rctl_hndl_t)mdb_strtoull(argp->a_un.a_str); if (mdb_walk("rctl_dict_list", (mdb_walk_cb_t)hndl2dict, &rdict) == -1) { mdb_warn("failed to walk rctl_dict_list"); return (DCMD_ERR); } /* Couldn't find a rctl_dict_entry_t for this handle */ if (rdict.dict_addr == NULL) return (DCMD_ERR); } else return (DCMD_USAGE); if (mdb_vread(&proc, sizeof (proc_t), addr) == -1) { mdb_warn("failed to read proc at %p", addr); return (DCMD_ERR); } if (mdb_vread(&zone, sizeof (zone_t), (uintptr_t)proc.p_zone) == -1) { mdb_warn("failed to read zone at %p", proc.p_zone); return (DCMD_ERR); } if (mdb_vread(&task, sizeof (task_t), (uintptr_t)proc.p_task) == -1) { mdb_warn("failed to read task at %p", proc.p_task); return (DCMD_ERR); } if (mdb_vread(&proj, sizeof (kproject_t), (uintptr_t)task.tk_proj) == -1) { mdb_warn("failed to read proj at %p", task.tk_proj); return (DCMD_ERR); } for (i = 0; i <= RC_MAX_ENTITY; i++) { /* * If user didn't specify a handle, print rctls for all * types. Otherwise, we can walk the rctl_set for only the * entity specified by the handle. */ if (rdict.hndl != 0 && rdict.type != i) continue; switch (i) { case (RCENTITY_PROCESS): set = (uintptr_t)proc.p_rctls; break; case (RCENTITY_TASK): set = (uintptr_t)task.tk_rctls; break; case (RCENTITY_PROJECT): set = (uintptr_t)proj.kpj_rctls; break; case (RCENTITY_ZONE): set = (uintptr_t)zone.zone_rctls; break; default: mdb_warn("Unknown rctl type %d", i); return (DCMD_ERR); } if (mdb_pwalk_dcmd("rctl_set", "rctl", argc, argv, set) == -1) { mdb_warn("failed to walk rctls in set %p", set); return (DCMD_ERR); } } return (DCMD_OK); }
/*ARGSUSED*/ int netstat(uintptr_t addr, uint_t flags, int argc, const mdb_arg_t *argv) { uint_t opts = 0; const char *optf = NULL; const char *optP = NULL; netstat_cb_data_t *cbdata; int status; int af = 0; if (mdb_getopts(argc, argv, 'a', MDB_OPT_SETBITS, NETSTAT_ALL, &opts, 'f', MDB_OPT_STR, &optf, 'P', MDB_OPT_STR, &optP, 'r', MDB_OPT_SETBITS, NETSTAT_ROUTE, &opts, 'v', MDB_OPT_SETBITS, NETSTAT_VERBOSE, &opts, NULL) != argc) return (DCMD_USAGE); if (optP != NULL) { if ((strcmp("tcp", optP) != 0) && (strcmp("udp", optP) != 0) && (strcmp("icmp", optP) != 0)) return (DCMD_USAGE); if (opts & NETSTAT_ROUTE) return (DCMD_USAGE); } if (optf == NULL) opts |= NETSTAT_V4 | NETSTAT_V6 | NETSTAT_UNIX; else if (strcmp("inet", optf) == 0) opts |= NETSTAT_V4; else if (strcmp("inet6", optf) == 0) opts |= NETSTAT_V6; else if (strcmp("unix", optf) == 0) opts |= NETSTAT_UNIX; else return (DCMD_USAGE); if (opts & NETSTAT_ROUTE) { if (!(opts & (NETSTAT_V4|NETSTAT_V6))) return (DCMD_USAGE); if (opts & NETSTAT_V4) { opts |= NETSTAT_FIRST; if (mdb_walk("ip`ire", netstat_irev4_cb, &opts) == -1) { mdb_warn("failed to walk ip`ire"); return (DCMD_ERR); } } if (opts & NETSTAT_V6) { opts |= NETSTAT_FIRST; if (mdb_walk("ip`ire", netstat_irev6_cb, &opts) == -1) { mdb_warn("failed to walk ip`ire"); return (DCMD_ERR); } } return (DCMD_OK); } if ((opts & NETSTAT_UNIX) && (optP == NULL)) { /* Print Unix Domain Sockets */ mdb_printf("%<u>%-?s %-10s %-?s %-?s %-14s %-14s %s%</u>\n", "AF_UNIX", "Type", "Vnode", "Conn", "Local Addr", "Remote Addr", "Zone"); if (mdb_walk("genunix`sonode", netstat_unix_cb, NULL) == -1) { mdb_warn("failed to walk genunix`sonode"); return (DCMD_ERR); } if (!(opts & (NETSTAT_V4 | NETSTAT_V6))) return (DCMD_OK); } cbdata = mdb_alloc(sizeof (netstat_cb_data_t), UM_SLEEP); cbdata->opts = opts; if ((optf != NULL) && (opts & NETSTAT_V4)) af = AF_INET; else if ((optf != NULL) && (opts & NETSTAT_V6)) af = AF_INET6; cbdata->af = af; if ((optP == NULL) || (strcmp("tcp", optP) == 0)) { status = netstat_print_common("tcp_conn_cache", IPPROTO_TCP, netstat_tcp_cb, cbdata); if (status != DCMD_OK) goto out; } if ((optP == NULL) || (strcmp("udp", optP) == 0)) { status = netstat_print_common("udp_conn_cache", IPPROTO_UDP, netstat_udp_cb, cbdata); if (status != DCMD_OK) goto out; } if ((optP == NULL) || (strcmp("icmp", optP) == 0)) { status = netstat_print_common("rawip_conn_cache", IPPROTO_ICMP, netstat_icmp_cb, cbdata); if (status != DCMD_OK) goto out; } out: mdb_free(cbdata, sizeof (netstat_cb_data_t)); return (status); }
int ttrace(uintptr_t addr, uint_t flags, int argc, const mdb_arg_t *argv) { ttrace_dcmd_t dcmd; trap_trace_ctl_t *ttc = dcmd.ttd_ttc; trap_trace_rec_t rec; size_t ttc_size = sizeof (trap_trace_ctl_t) * NCPU; if (!ttrace_ttr_size_check()) return (WALK_ERR); bzero(&dcmd, sizeof (dcmd)); dcmd.ttd_cpu = -1; dcmd.ttd_extended = FALSE; if (mdb_readsym(ttc, ttc_size, "trap_trace_ctl") == -1) { mdb_warn("symbol 'trap_trace_ctl' not found; " "non-TRAPTRACE kernel?\n"); return (DCMD_ERR); } if (mdb_getopts(argc, argv, 'x', MDB_OPT_SETBITS, TRUE, &dcmd.ttd_extended, 't', MDB_OPT_UINTPTR, &dcmd.ttd_kthread, NULL) != argc) return (DCMD_USAGE); if (DCMD_HDRSPEC(flags)) { mdb_printf("%3s %15s %4s %2s %-*s%s\n", "CPU", "TIMESTAMP", "TYPE", "Vec", TT_HDLR_WIDTH, "HANDLER", " EIP"); } if (flags & DCMD_ADDRSPEC) { if (addr >= NCPU) { if (mdb_vread(&rec, sizeof (rec), addr) == -1) { mdb_warn("couldn't read trap trace record " "at %p", addr); return (DCMD_ERR); } if (ttrace_walk(addr, &rec, &dcmd) == WALK_ERR) return (DCMD_ERR); return (DCMD_OK); } dcmd.ttd_cpu = addr; } if (mdb_readvar(&use_apix, "apix_enable") == -1) { mdb_warn("failed to read apix_enable"); use_apix = 0; } if (use_apix) { if (mdb_readvar(&d_apixs, "apixs") == -1) { mdb_warn("\nfailed to read apixs."); return (DCMD_ERR); } /* change to apix ttrace interrupt handler */ ttrace_hdlr[4].t_hdlr = ttrace_apix_interrupt; } if (mdb_walk("ttrace", (mdb_walk_cb_t)ttrace_walk, &dcmd) == -1) { mdb_warn("couldn't walk 'ttrace'"); return (DCMD_ERR); } return (DCMD_OK); }