> I need to look at the content of the lwpsinfo structure from a process core 
> dump. Is there some MDB magic for that?
> 
> - Alexander Kolbasov

The mdb proc target publishes some of the libproc data structures
as "xdata" (extended data buffers): you can list them using ::xdata:

> ::xdata
auxv                     - procfs auxv_t array (104 bytes)
cred                     - procfs prcred_t structure (44 bytes)
ehdr                     - executable file GElf_Ehdr structure (64 bytes)
lwpstatus                - procfs lwpstatus_t array (800 bytes)
pshandle                 - libproc proc service API handle (4 bytes)
psinfo                   - procfs psinfo_t structure (336 bytes)
pstatus                  - procfs pstatus_t structure (1136 bytes)
utsname                  - utsname structure (1285 bytes)

The mdb_get_xdata() api (see the docs for info) is used to read these buffers.
Feel free to add more if they are needed and useful.  Note that the pshandle
itself is exported, so you can read it directly and then get to other things.
Some example code to do this for per-lwp cursig values is below.

-Mike

-- 
Mike Shapiro, Solaris Kernel Development. blogs.sun.com/mws/

#include <sys/mdb_modapi.h>
#include <libproc.h>

static struct ps_prochandle *
curproc(void)
{
        struct ps_prochandle *P = NULL;

        if (mdb_get_xdata("pshandle", &P,
            sizeof (P)) != sizeof (P) || P == NULL)
                mdb_warn("failed to obtain handle for current process");

        return (P);
}

static int
lwp_cursig(struct ps_prochandle *P, const lwpstatus_t *psp)
{
        mdb_printf("LWP %d:\n", psp->pr_lwpid);

        mdb_printf("  pr_flags  = 0x%x\n", psp->pr_flags);
        mdb_printf("  pr_what   = %d\n", psp->pr_what);
        mdb_printf("  pr_why    = %d\n", psp->pr_why);
        mdb_printf("  pr_cursig = %d\n", psp->pr_cursig);

        mdb_printf("  pr_info = {\n");
        mdb_printf("      si_signo = %d\n", psp->pr_info.si_signo);
        mdb_printf("      si_code = %d\n", psp->pr_info.si_code);
        mdb_printf("      si_errno = %d\n  }\n", psp->pr_info.si_errno);

        if (psp->pr_info.si_code == SI_USER) {
                mdb_printf("      si_pid = %d\n", psp->pr_info.si_pid);
                mdb_printf("      si_ctid = %d\n", psp->pr_info.si_ctid);
                mdb_printf("      si_zoneid = %d\n", psp->pr_info.si_zoneid);

                if (psp->pr_info.si_signo == SIGCLD) {
                        mdb_printf("      si_status = 0x%x\n",
                            psp->pr_info.si_status);
                } else {
                        mdb_printf("      si_uid = %d\n", psp->pr_info.si_uid);
                }
        }

        mdb_printf("  pr_action = {\n");
        mdb_printf("      sa_flags = 0x%x\n", psp->pr_action.sa_flags);
        mdb_printf("      sa_handler = %a\n", psp->pr_action.sa_handler);
        mdb_printf("      sa_mask = 0x%x 0x%x 0x%x 0x%x\n  }\n\n",
            psp->pr_action.sa_mask.__sigbits[0],
            psp->pr_action.sa_mask.__sigbits[1],
            psp->pr_action.sa_mask.__sigbits[2],
            psp->pr_action.sa_mask.__sigbits[3]);

        return (0);
}

static int
cursig(uintptr_t addr, uint_t flags, int argc, const mdb_arg_t *argv)
{
        struct ps_prochandle *P;
        const pstatus_t *psp;

        if ((P = curproc()) == NULL)
                return (DCMD_ERR);

        if ((psp = Pstatus(P)) == NULL) {
                mdb_warn("Pstatus failed");
                return (DCMD_ERR);
        }

        (void) lwp_cursig(P, &psp->pr_lwp);
        (void) Plwp_iter(P, (proc_lwp_f *)lwp_cursig, NULL);
        return (DCMD_OK);
}

static const mdb_dcmd_t dcmds[] = {
        { "cursig", NULL, "display LWP cursig info", cursig },
        { NULL }
};

static const mdb_modinfo_t modinfo = {
        MDB_API_VERSION, dcmds, NULL
};

const mdb_modinfo_t *
_mdb_init(void)
{
        return (&modinfo);
}

Reply via email to