diff options
Diffstat (limited to 'usr/src/cmd/mdb/common/modules/libc/libc.c')
-rw-r--r-- | usr/src/cmd/mdb/common/modules/libc/libc.c | 59 |
1 files changed, 59 insertions, 0 deletions
diff --git a/usr/src/cmd/mdb/common/modules/libc/libc.c b/usr/src/cmd/mdb/common/modules/libc/libc.c index 55ecbd8324..05676c3b24 100644 --- a/usr/src/cmd/mdb/common/modules/libc/libc.c +++ b/usr/src/cmd/mdb/common/modules/libc/libc.c @@ -25,6 +25,7 @@ */ #include <sys/mdb_modapi.h> +#include <mdb/mdb_whatis.h> #include <procfs.h> #include <ucontext.h> #include <siginfo.h> @@ -914,6 +915,61 @@ ulwp_walk_step(mdb_walk_state_t *wsp) return (wsp->walk_callback(addr, &ulwp, wsp->walk_cbdata)); } +/* Avoid classifying NULL pointers as part of the main stack on x86 */ +#define MIN_STACK_ADDR (0x10000ul) + +static int +whatis_walk_ulwp(uintptr_t addr, const ulwp_t *ulwp, mdb_whatis_t *w) +{ + uintptr_t cur; + lwpid_t id = ulwp->ul_lwpid; + uintptr_t top, base, size; + + while (mdb_whatis_match(w, addr, sizeof (ulwp_t), &cur)) + mdb_whatis_report_object(w, cur, addr, + "allocated as thread %#r's ulwp_t\n", id); + + top = (uintptr_t)ulwp->ul_stktop; + size = ulwp->ul_stksiz; + + /* + * The main stack ends up being a little weird, especially if + * the stack ulimit is unlimited. This tries to take that into + * account. + */ + if (size > top) + size = top; + if (top > MIN_STACK_ADDR && top - size < MIN_STACK_ADDR) + size = top - MIN_STACK_ADDR; + + base = top - size; + + while (mdb_whatis_match(w, base, size, &cur)) + mdb_whatis_report_address(w, cur, "in [ stack tid=%#r ]\n", id); + + if (ulwp->ul_ustack.ss_flags & SS_ONSTACK) { + base = (uintptr_t)ulwp->ul_ustack.ss_sp; + size = ulwp->ul_ustack.ss_size; + + while (mdb_whatis_match(w, base, size, &cur)) + mdb_whatis_report_address(w, cur, + "in [ altstack tid=%#r ]\n", id); + } + + return (WHATIS_WALKRET(w)); +} + +/*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); +} + /* * ======================================================= * End of thread (previously libthread) interfaces. @@ -945,5 +1001,8 @@ static const mdb_modinfo_t modinfo = { MDB_API_VERSION, dcmds, walkers }; const mdb_modinfo_t * _mdb_init(void) { + mdb_whatis_register("threads", whatis_run_ulwps, NULL, + WHATIS_PRIO_EARLY, WHATIS_REG_NO_ID); + return (&modinfo); } |