1*7c478bd9Sstevel@tonic-gate /* 2*7c478bd9Sstevel@tonic-gate * CDDL HEADER START 3*7c478bd9Sstevel@tonic-gate * 4*7c478bd9Sstevel@tonic-gate * The contents of this file are subject to the terms of the 5*7c478bd9Sstevel@tonic-gate * Common Development and Distribution License, Version 1.0 only 6*7c478bd9Sstevel@tonic-gate * (the "License"). You may not use this file except in compliance 7*7c478bd9Sstevel@tonic-gate * with the License. 8*7c478bd9Sstevel@tonic-gate * 9*7c478bd9Sstevel@tonic-gate * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 10*7c478bd9Sstevel@tonic-gate * or http://www.opensolaris.org/os/licensing. 11*7c478bd9Sstevel@tonic-gate * See the License for the specific language governing permissions 12*7c478bd9Sstevel@tonic-gate * and limitations under the License. 13*7c478bd9Sstevel@tonic-gate * 14*7c478bd9Sstevel@tonic-gate * When distributing Covered Code, include this CDDL HEADER in each 15*7c478bd9Sstevel@tonic-gate * file and include the License file at usr/src/OPENSOLARIS.LICENSE. 16*7c478bd9Sstevel@tonic-gate * If applicable, add the following below this CDDL HEADER, with the 17*7c478bd9Sstevel@tonic-gate * fields enclosed by brackets "[]" replaced with your own identifying 18*7c478bd9Sstevel@tonic-gate * information: Portions Copyright [yyyy] [name of copyright owner] 19*7c478bd9Sstevel@tonic-gate * 20*7c478bd9Sstevel@tonic-gate * CDDL HEADER END 21*7c478bd9Sstevel@tonic-gate */ 22*7c478bd9Sstevel@tonic-gate /* 23*7c478bd9Sstevel@tonic-gate * Copyright 2005 Sun Microsystems, Inc. All rights reserved. 24*7c478bd9Sstevel@tonic-gate * Use is subject to license terms. 25*7c478bd9Sstevel@tonic-gate */ 26*7c478bd9Sstevel@tonic-gate 27*7c478bd9Sstevel@tonic-gate #pragma ident "%Z%%M% %I% %E% SMI" 28*7c478bd9Sstevel@tonic-gate 29*7c478bd9Sstevel@tonic-gate #include <sys/mdb_modapi.h> 30*7c478bd9Sstevel@tonic-gate #include <procfs.h> 31*7c478bd9Sstevel@tonic-gate #include <ucontext.h> 32*7c478bd9Sstevel@tonic-gate #include <siginfo.h> 33*7c478bd9Sstevel@tonic-gate #include <signal.h> 34*7c478bd9Sstevel@tonic-gate #include <setjmp.h> 35*7c478bd9Sstevel@tonic-gate #include <string.h> 36*7c478bd9Sstevel@tonic-gate #include <thr_uberdata.h> 37*7c478bd9Sstevel@tonic-gate 38*7c478bd9Sstevel@tonic-gate static const char * 39*7c478bd9Sstevel@tonic-gate stack_flags(const stack_t *sp) 40*7c478bd9Sstevel@tonic-gate { 41*7c478bd9Sstevel@tonic-gate static char buf[32]; 42*7c478bd9Sstevel@tonic-gate 43*7c478bd9Sstevel@tonic-gate if (sp->ss_flags == 0) 44*7c478bd9Sstevel@tonic-gate (void) strcpy(buf, " 0"); 45*7c478bd9Sstevel@tonic-gate else if (sp->ss_flags & ~(SS_ONSTACK | SS_DISABLE)) 46*7c478bd9Sstevel@tonic-gate (void) mdb_snprintf(buf, sizeof (buf), " 0x%x", sp->ss_flags); 47*7c478bd9Sstevel@tonic-gate else { 48*7c478bd9Sstevel@tonic-gate buf[0] = '\0'; 49*7c478bd9Sstevel@tonic-gate if (sp->ss_flags & SS_ONSTACK) 50*7c478bd9Sstevel@tonic-gate (void) strcat(buf, "|ONSTACK"); 51*7c478bd9Sstevel@tonic-gate if (sp->ss_flags & SS_DISABLE) 52*7c478bd9Sstevel@tonic-gate (void) strcat(buf, "|DISABLE"); 53*7c478bd9Sstevel@tonic-gate } 54*7c478bd9Sstevel@tonic-gate 55*7c478bd9Sstevel@tonic-gate return (buf + 1); 56*7c478bd9Sstevel@tonic-gate } 57*7c478bd9Sstevel@tonic-gate 58*7c478bd9Sstevel@tonic-gate /*ARGSUSED*/ 59*7c478bd9Sstevel@tonic-gate static int 60*7c478bd9Sstevel@tonic-gate d_jmp_buf(uintptr_t addr, uint_t flags, int argc, const mdb_arg_t *argv) 61*7c478bd9Sstevel@tonic-gate { 62*7c478bd9Sstevel@tonic-gate jmp_buf jb; 63*7c478bd9Sstevel@tonic-gate const ulong_t *b = (const ulong_t *)jb; 64*7c478bd9Sstevel@tonic-gate 65*7c478bd9Sstevel@tonic-gate if (argc != 0) 66*7c478bd9Sstevel@tonic-gate return (DCMD_USAGE); 67*7c478bd9Sstevel@tonic-gate 68*7c478bd9Sstevel@tonic-gate if (mdb_vread(&jb, sizeof (jb), addr) != sizeof (jb)) { 69*7c478bd9Sstevel@tonic-gate mdb_warn("failed to read jmp_buf at %p", addr); 70*7c478bd9Sstevel@tonic-gate return (DCMD_ERR); 71*7c478bd9Sstevel@tonic-gate } 72*7c478bd9Sstevel@tonic-gate 73*7c478bd9Sstevel@tonic-gate #if defined(__sparc) 74*7c478bd9Sstevel@tonic-gate mdb_printf(" %%sp = 0x%lx\n", b[1]); 75*7c478bd9Sstevel@tonic-gate mdb_printf(" %%pc = 0x%lx %lA\n", b[2], b[2]); 76*7c478bd9Sstevel@tonic-gate mdb_printf(" %%fp = 0x%lx\n", b[3]); 77*7c478bd9Sstevel@tonic-gate mdb_printf(" %%i7 = 0x%lx %lA\n", b[4], b[4]); 78*7c478bd9Sstevel@tonic-gate #elif defined(__amd64) 79*7c478bd9Sstevel@tonic-gate mdb_printf(" %%rbx = 0x%lx\n", b[0]); 80*7c478bd9Sstevel@tonic-gate mdb_printf(" %%r12 = 0x%lx\n", b[1]); 81*7c478bd9Sstevel@tonic-gate mdb_printf(" %%r13 = 0x%lx\n", b[2]); 82*7c478bd9Sstevel@tonic-gate mdb_printf(" %%r14 = 0x%lx\n", b[3]); 83*7c478bd9Sstevel@tonic-gate mdb_printf(" %%r15 = 0x%lx\n", b[4]); 84*7c478bd9Sstevel@tonic-gate mdb_printf(" %%rbp = 0x%lx\n", b[5]); 85*7c478bd9Sstevel@tonic-gate mdb_printf(" %%rsp = 0x%lx\n", b[6]); 86*7c478bd9Sstevel@tonic-gate mdb_printf(" %%rip = 0x%lx %lA\n", b[7], b[7]); 87*7c478bd9Sstevel@tonic-gate #elif defined(__i386) 88*7c478bd9Sstevel@tonic-gate mdb_printf(" %%ebx = 0x%lx\n", b[0]); 89*7c478bd9Sstevel@tonic-gate mdb_printf(" %%esi = 0x%lx\n", b[1]); 90*7c478bd9Sstevel@tonic-gate mdb_printf(" %%edi = 0x%lx\n", b[2]); 91*7c478bd9Sstevel@tonic-gate mdb_printf(" %%ebp = 0x%lx\n", b[3]); 92*7c478bd9Sstevel@tonic-gate mdb_printf(" %%esp = 0x%lx\n", b[4]); 93*7c478bd9Sstevel@tonic-gate mdb_printf(" %%eip = 0x%lx %lA\n", b[5], b[5]); 94*7c478bd9Sstevel@tonic-gate #endif 95*7c478bd9Sstevel@tonic-gate return (DCMD_OK); 96*7c478bd9Sstevel@tonic-gate } 97*7c478bd9Sstevel@tonic-gate 98*7c478bd9Sstevel@tonic-gate /*ARGSUSED*/ 99*7c478bd9Sstevel@tonic-gate static int 100*7c478bd9Sstevel@tonic-gate d_ucontext(uintptr_t addr, uint_t flags, int argc, const mdb_arg_t *argv) 101*7c478bd9Sstevel@tonic-gate { 102*7c478bd9Sstevel@tonic-gate ucontext_t uc; 103*7c478bd9Sstevel@tonic-gate 104*7c478bd9Sstevel@tonic-gate if (argc != 0) 105*7c478bd9Sstevel@tonic-gate return (DCMD_USAGE); 106*7c478bd9Sstevel@tonic-gate 107*7c478bd9Sstevel@tonic-gate if (mdb_vread(&uc, sizeof (uc), addr) != sizeof (uc)) { 108*7c478bd9Sstevel@tonic-gate mdb_warn("failed to read ucontext at %p", addr); 109*7c478bd9Sstevel@tonic-gate return (DCMD_ERR); 110*7c478bd9Sstevel@tonic-gate } 111*7c478bd9Sstevel@tonic-gate 112*7c478bd9Sstevel@tonic-gate mdb_printf(" flags = 0x%lx\n", uc.uc_flags); 113*7c478bd9Sstevel@tonic-gate mdb_printf(" link = 0x%p\n", uc.uc_link); 114*7c478bd9Sstevel@tonic-gate mdb_printf(" sigmask = 0x%08x 0x%08x 0x%08x 0x%08x\n", 115*7c478bd9Sstevel@tonic-gate uc.uc_sigmask.__sigbits[0], uc.uc_sigmask.__sigbits[1], 116*7c478bd9Sstevel@tonic-gate uc.uc_sigmask.__sigbits[2], uc.uc_sigmask.__sigbits[3]); 117*7c478bd9Sstevel@tonic-gate mdb_printf(" stack = sp 0x%p size 0x%lx flags %s\n", 118*7c478bd9Sstevel@tonic-gate uc.uc_stack.ss_sp, uc.uc_stack.ss_size, stack_flags(&uc.uc_stack)); 119*7c478bd9Sstevel@tonic-gate mdb_printf(" mcontext = 0x%p\n", 120*7c478bd9Sstevel@tonic-gate addr + OFFSETOF(ucontext_t, uc_mcontext)); 121*7c478bd9Sstevel@tonic-gate 122*7c478bd9Sstevel@tonic-gate return (DCMD_OK); 123*7c478bd9Sstevel@tonic-gate } 124*7c478bd9Sstevel@tonic-gate 125*7c478bd9Sstevel@tonic-gate /*ARGSUSED*/ 126*7c478bd9Sstevel@tonic-gate static int 127*7c478bd9Sstevel@tonic-gate d_sigjmp_buf(uintptr_t addr, uint_t flags, int argc, const mdb_arg_t *argv) 128*7c478bd9Sstevel@tonic-gate { 129*7c478bd9Sstevel@tonic-gate #if defined(__sparc) 130*7c478bd9Sstevel@tonic-gate struct { 131*7c478bd9Sstevel@tonic-gate int sjs_flags; 132*7c478bd9Sstevel@tonic-gate greg_t sjs_sp; 133*7c478bd9Sstevel@tonic-gate greg_t sjs_pc; 134*7c478bd9Sstevel@tonic-gate greg_t sjs_fp; 135*7c478bd9Sstevel@tonic-gate greg_t sjs_i7; 136*7c478bd9Sstevel@tonic-gate ucontext_t *sjs_uclink; 137*7c478bd9Sstevel@tonic-gate ulong_t sjs_pad[_JBLEN - 6]; 138*7c478bd9Sstevel@tonic-gate sigset_t sjs_sigmask; 139*7c478bd9Sstevel@tonic-gate #if defined(_LP64) 140*7c478bd9Sstevel@tonic-gate ulong_t sjs_pad1[2]; 141*7c478bd9Sstevel@tonic-gate #endif 142*7c478bd9Sstevel@tonic-gate stack_t sjs_stack; 143*7c478bd9Sstevel@tonic-gate } s; 144*7c478bd9Sstevel@tonic-gate 145*7c478bd9Sstevel@tonic-gate if (argc != 0) 146*7c478bd9Sstevel@tonic-gate return (DCMD_USAGE); 147*7c478bd9Sstevel@tonic-gate 148*7c478bd9Sstevel@tonic-gate if (mdb_vread(&s, sizeof (s), addr) != sizeof (s)) { 149*7c478bd9Sstevel@tonic-gate mdb_warn("failed to read sigjmp_buf at %p", addr); 150*7c478bd9Sstevel@tonic-gate return (DCMD_ERR); 151*7c478bd9Sstevel@tonic-gate } 152*7c478bd9Sstevel@tonic-gate 153*7c478bd9Sstevel@tonic-gate mdb_printf(" flags = 0x%x\n", s.sjs_flags); 154*7c478bd9Sstevel@tonic-gate mdb_printf(" %%sp = 0x%lx %lA\n", s.sjs_sp, s.sjs_sp); 155*7c478bd9Sstevel@tonic-gate mdb_printf(" %%pc = 0x%lx %lA\n", s.sjs_pc, s.sjs_pc); 156*7c478bd9Sstevel@tonic-gate mdb_printf(" %%fp = 0x%lx %lA\n", s.sjs_fp, s.sjs_fp); 157*7c478bd9Sstevel@tonic-gate mdb_printf(" %%i7 = 0x%lx %lA\n", s.sjs_i7, s.sjs_i7); 158*7c478bd9Sstevel@tonic-gate mdb_printf(" uclink = %p\n", s.sjs_uclink); 159*7c478bd9Sstevel@tonic-gate mdb_printf(" sigset = 0x%08x 0x%08x 0x%08x 0x%08x\n", 160*7c478bd9Sstevel@tonic-gate s.sjs_sigmask.__sigbits[0], s.sjs_sigmask.__sigbits[1], 161*7c478bd9Sstevel@tonic-gate s.sjs_sigmask.__sigbits[2], s.sjs_sigmask.__sigbits[3]); 162*7c478bd9Sstevel@tonic-gate mdb_printf(" stack = sp 0x%p size 0x%lx flags %s\n", 163*7c478bd9Sstevel@tonic-gate s.sjs_stack.ss_sp, s.sjs_stack.ss_size, stack_flags(&s.sjs_stack)); 164*7c478bd9Sstevel@tonic-gate 165*7c478bd9Sstevel@tonic-gate return (DCMD_OK); 166*7c478bd9Sstevel@tonic-gate 167*7c478bd9Sstevel@tonic-gate #elif defined(__i386) || defined(__amd64) 168*7c478bd9Sstevel@tonic-gate return (d_ucontext(addr, flags, argc, argv)); 169*7c478bd9Sstevel@tonic-gate #endif 170*7c478bd9Sstevel@tonic-gate } 171*7c478bd9Sstevel@tonic-gate 172*7c478bd9Sstevel@tonic-gate /*ARGSUSED*/ 173*7c478bd9Sstevel@tonic-gate static int 174*7c478bd9Sstevel@tonic-gate d_siginfo(uintptr_t addr, uint_t flags, int argc, const mdb_arg_t *argv) 175*7c478bd9Sstevel@tonic-gate { 176*7c478bd9Sstevel@tonic-gate static const char *const msname[] = { 177*7c478bd9Sstevel@tonic-gate "USER", "SYSTEM", "TRAP", "TFAULT", "DFAULT", "KFAULT", 178*7c478bd9Sstevel@tonic-gate "USER_LOCK", "SLEEP", "WAIT_CPU", "STOPPED" 179*7c478bd9Sstevel@tonic-gate }; 180*7c478bd9Sstevel@tonic-gate 181*7c478bd9Sstevel@tonic-gate char signame[SIG2STR_MAX]; 182*7c478bd9Sstevel@tonic-gate siginfo_t si; 183*7c478bd9Sstevel@tonic-gate int i; 184*7c478bd9Sstevel@tonic-gate 185*7c478bd9Sstevel@tonic-gate if (argc != 0) 186*7c478bd9Sstevel@tonic-gate return (DCMD_USAGE); 187*7c478bd9Sstevel@tonic-gate 188*7c478bd9Sstevel@tonic-gate if (mdb_vread(&si, sizeof (si), addr) != sizeof (si)) { 189*7c478bd9Sstevel@tonic-gate mdb_warn("failed to read siginfo at %p", addr); 190*7c478bd9Sstevel@tonic-gate return (DCMD_ERR); 191*7c478bd9Sstevel@tonic-gate } 192*7c478bd9Sstevel@tonic-gate 193*7c478bd9Sstevel@tonic-gate if (sig2str(si.si_signo, signame) == -1) 194*7c478bd9Sstevel@tonic-gate (void) strcpy(signame, "unknown"); 195*7c478bd9Sstevel@tonic-gate 196*7c478bd9Sstevel@tonic-gate mdb_printf(" signal %5d (%s)\n", si.si_signo, signame); 197*7c478bd9Sstevel@tonic-gate mdb_printf(" code %5d (", si.si_code); 198*7c478bd9Sstevel@tonic-gate 199*7c478bd9Sstevel@tonic-gate switch (si.si_code) { 200*7c478bd9Sstevel@tonic-gate case SI_NOINFO: 201*7c478bd9Sstevel@tonic-gate mdb_printf("no info"); 202*7c478bd9Sstevel@tonic-gate break; 203*7c478bd9Sstevel@tonic-gate case SI_DTRACE: 204*7c478bd9Sstevel@tonic-gate mdb_printf("from DTrace raise() action"); 205*7c478bd9Sstevel@tonic-gate break; 206*7c478bd9Sstevel@tonic-gate case SI_RCTL: 207*7c478bd9Sstevel@tonic-gate mdb_printf("from rctl action"); 208*7c478bd9Sstevel@tonic-gate break; 209*7c478bd9Sstevel@tonic-gate case SI_USER: 210*7c478bd9Sstevel@tonic-gate mdb_printf("user generated via kill"); 211*7c478bd9Sstevel@tonic-gate break; 212*7c478bd9Sstevel@tonic-gate case SI_LWP: 213*7c478bd9Sstevel@tonic-gate mdb_printf("user generated via lwp_kill"); 214*7c478bd9Sstevel@tonic-gate break; 215*7c478bd9Sstevel@tonic-gate case SI_QUEUE: 216*7c478bd9Sstevel@tonic-gate mdb_printf("user generated via sigqueue"); 217*7c478bd9Sstevel@tonic-gate break; 218*7c478bd9Sstevel@tonic-gate case SI_TIMER: 219*7c478bd9Sstevel@tonic-gate mdb_printf("from timer expiration"); 220*7c478bd9Sstevel@tonic-gate break; 221*7c478bd9Sstevel@tonic-gate case SI_ASYNCIO: 222*7c478bd9Sstevel@tonic-gate mdb_printf("from async i/o completion"); 223*7c478bd9Sstevel@tonic-gate break; 224*7c478bd9Sstevel@tonic-gate case SI_MESGQ: 225*7c478bd9Sstevel@tonic-gate mdb_printf("from message arrival"); 226*7c478bd9Sstevel@tonic-gate break; 227*7c478bd9Sstevel@tonic-gate default: 228*7c478bd9Sstevel@tonic-gate if (SI_FROMUSER(&si)) 229*7c478bd9Sstevel@tonic-gate mdb_printf("from user process"); 230*7c478bd9Sstevel@tonic-gate else 231*7c478bd9Sstevel@tonic-gate mdb_printf("from kernel"); 232*7c478bd9Sstevel@tonic-gate } 233*7c478bd9Sstevel@tonic-gate 234*7c478bd9Sstevel@tonic-gate mdb_printf(")\n errno %5d (%s)\n", 235*7c478bd9Sstevel@tonic-gate si.si_errno, strerror(si.si_errno)); 236*7c478bd9Sstevel@tonic-gate 237*7c478bd9Sstevel@tonic-gate if (si.si_code == SI_USER || si.si_code == SI_QUEUE) { 238*7c478bd9Sstevel@tonic-gate mdb_printf(" signal sent from PID %d (uid %d)\n", 239*7c478bd9Sstevel@tonic-gate si.si_pid, si.si_uid); 240*7c478bd9Sstevel@tonic-gate } 241*7c478bd9Sstevel@tonic-gate 242*7c478bd9Sstevel@tonic-gate if (si.si_code == SI_QUEUE) { 243*7c478bd9Sstevel@tonic-gate mdb_printf(" signal value = 0t%d / %p\n", 244*7c478bd9Sstevel@tonic-gate si.si_value.sival_int, si.si_value.sival_ptr); 245*7c478bd9Sstevel@tonic-gate } 246*7c478bd9Sstevel@tonic-gate 247*7c478bd9Sstevel@tonic-gate switch (si.si_signo) { 248*7c478bd9Sstevel@tonic-gate case SIGCLD: 249*7c478bd9Sstevel@tonic-gate mdb_printf(" signal sent from child PID %d (uid %d)\n", 250*7c478bd9Sstevel@tonic-gate si.si_pid, si.si_uid); 251*7c478bd9Sstevel@tonic-gate mdb_printf(" usr time = 0t%ld ticks, sys time = 0t%ld ticks\n", 252*7c478bd9Sstevel@tonic-gate si.si_utime, si.si_stime); 253*7c478bd9Sstevel@tonic-gate mdb_printf(" wait status = 0x%x\n", si.si_status); 254*7c478bd9Sstevel@tonic-gate break; 255*7c478bd9Sstevel@tonic-gate 256*7c478bd9Sstevel@tonic-gate case SIGSEGV: 257*7c478bd9Sstevel@tonic-gate case SIGBUS: 258*7c478bd9Sstevel@tonic-gate case SIGILL: 259*7c478bd9Sstevel@tonic-gate case SIGTRAP: 260*7c478bd9Sstevel@tonic-gate case SIGFPE: 261*7c478bd9Sstevel@tonic-gate mdb_printf(" fault address = 0x%p\n trapno = %d\n", 262*7c478bd9Sstevel@tonic-gate si.si_addr, si.si_trapno); 263*7c478bd9Sstevel@tonic-gate mdb_printf(" instruction address = 0x%p %lA\n", 264*7c478bd9Sstevel@tonic-gate si.si_pc, si.si_pc); 265*7c478bd9Sstevel@tonic-gate break; 266*7c478bd9Sstevel@tonic-gate 267*7c478bd9Sstevel@tonic-gate case SIGPOLL: 268*7c478bd9Sstevel@tonic-gate case SIGXFSZ: 269*7c478bd9Sstevel@tonic-gate mdb_printf(" fd = %d band = 0x%lx\n", 270*7c478bd9Sstevel@tonic-gate si.si_fd, si.si_band); 271*7c478bd9Sstevel@tonic-gate break; 272*7c478bd9Sstevel@tonic-gate 273*7c478bd9Sstevel@tonic-gate case SIGPROF: 274*7c478bd9Sstevel@tonic-gate mdb_printf(" last fault address = 0x%p fault type = %d\n", 275*7c478bd9Sstevel@tonic-gate si.si_faddr, si.si_fault); 276*7c478bd9Sstevel@tonic-gate mdb_printf(" timestamp = 0t%ld sec 0t%ld nsec\n", 277*7c478bd9Sstevel@tonic-gate si.si_tstamp.tv_sec, si.si_tstamp.tv_nsec); 278*7c478bd9Sstevel@tonic-gate 279*7c478bd9Sstevel@tonic-gate if (si.__data.__prof.__syscall != 0) { 280*7c478bd9Sstevel@tonic-gate mdb_printf(" system call %d (", si.si_syscall); 281*7c478bd9Sstevel@tonic-gate if (si.si_nsysarg > 0) { 282*7c478bd9Sstevel@tonic-gate mdb_printf("%lx", si.si_sysarg[0]); 283*7c478bd9Sstevel@tonic-gate for (i = 1; i < si.si_nsysarg; i++) 284*7c478bd9Sstevel@tonic-gate mdb_printf(", %lx", si.si_sysarg[i]); 285*7c478bd9Sstevel@tonic-gate } 286*7c478bd9Sstevel@tonic-gate mdb_printf(" )\n"); 287*7c478bd9Sstevel@tonic-gate } 288*7c478bd9Sstevel@tonic-gate 289*7c478bd9Sstevel@tonic-gate for (i = 0; i < sizeof (msname) / sizeof (msname[0]); i++) { 290*7c478bd9Sstevel@tonic-gate mdb_printf(" mstate[\"%s\"] = %d\n", 291*7c478bd9Sstevel@tonic-gate msname[i], si.si_mstate[i]); 292*7c478bd9Sstevel@tonic-gate } 293*7c478bd9Sstevel@tonic-gate break; 294*7c478bd9Sstevel@tonic-gate } 295*7c478bd9Sstevel@tonic-gate 296*7c478bd9Sstevel@tonic-gate return (DCMD_OK); 297*7c478bd9Sstevel@tonic-gate } 298*7c478bd9Sstevel@tonic-gate 299*7c478bd9Sstevel@tonic-gate static int 300*7c478bd9Sstevel@tonic-gate uc_walk_step(mdb_walk_state_t *wsp) 301*7c478bd9Sstevel@tonic-gate { 302*7c478bd9Sstevel@tonic-gate uintptr_t addr = wsp->walk_addr; 303*7c478bd9Sstevel@tonic-gate ucontext_t uc; 304*7c478bd9Sstevel@tonic-gate 305*7c478bd9Sstevel@tonic-gate if (addr == NULL) 306*7c478bd9Sstevel@tonic-gate return (WALK_DONE); 307*7c478bd9Sstevel@tonic-gate 308*7c478bd9Sstevel@tonic-gate if (mdb_vread(&uc, sizeof (uc), addr) != sizeof (uc)) { 309*7c478bd9Sstevel@tonic-gate mdb_warn("failed to read ucontext at %p", addr); 310*7c478bd9Sstevel@tonic-gate return (WALK_ERR); 311*7c478bd9Sstevel@tonic-gate } 312*7c478bd9Sstevel@tonic-gate 313*7c478bd9Sstevel@tonic-gate wsp->walk_addr = (uintptr_t)uc.uc_link; 314*7c478bd9Sstevel@tonic-gate return (wsp->walk_callback(addr, &uc, wsp->walk_cbdata)); 315*7c478bd9Sstevel@tonic-gate } 316*7c478bd9Sstevel@tonic-gate 317*7c478bd9Sstevel@tonic-gate static int 318*7c478bd9Sstevel@tonic-gate oldc_walk_init(mdb_walk_state_t *wsp) 319*7c478bd9Sstevel@tonic-gate { 320*7c478bd9Sstevel@tonic-gate ssize_t nbytes = mdb_get_xdata("lwpstatus", NULL, 0); 321*7c478bd9Sstevel@tonic-gate 322*7c478bd9Sstevel@tonic-gate if (nbytes <= 0) { 323*7c478bd9Sstevel@tonic-gate mdb_warn("lwpstatus information not available"); 324*7c478bd9Sstevel@tonic-gate return (WALK_ERR); 325*7c478bd9Sstevel@tonic-gate } 326*7c478bd9Sstevel@tonic-gate 327*7c478bd9Sstevel@tonic-gate if (wsp->walk_addr != NULL) { 328*7c478bd9Sstevel@tonic-gate mdb_warn("walker only supports global walk\n"); 329*7c478bd9Sstevel@tonic-gate return (WALK_ERR); 330*7c478bd9Sstevel@tonic-gate } 331*7c478bd9Sstevel@tonic-gate 332*7c478bd9Sstevel@tonic-gate wsp->walk_addr = nbytes; /* Use walk_addr to track size */ 333*7c478bd9Sstevel@tonic-gate wsp->walk_data = mdb_alloc(nbytes, UM_SLEEP); 334*7c478bd9Sstevel@tonic-gate 335*7c478bd9Sstevel@tonic-gate if (mdb_get_xdata("lwpstatus", wsp->walk_data, nbytes) != nbytes) { 336*7c478bd9Sstevel@tonic-gate mdb_warn("failed to read lwpstatus information"); 337*7c478bd9Sstevel@tonic-gate mdb_free(wsp->walk_data, nbytes); 338*7c478bd9Sstevel@tonic-gate return (WALK_ERR); 339*7c478bd9Sstevel@tonic-gate } 340*7c478bd9Sstevel@tonic-gate 341*7c478bd9Sstevel@tonic-gate wsp->walk_arg = wsp->walk_data; /* Use walk_arg to track pointer */ 342*7c478bd9Sstevel@tonic-gate return (WALK_NEXT); 343*7c478bd9Sstevel@tonic-gate } 344*7c478bd9Sstevel@tonic-gate 345*7c478bd9Sstevel@tonic-gate static int 346*7c478bd9Sstevel@tonic-gate oldc_walk_step(mdb_walk_state_t *wsp) 347*7c478bd9Sstevel@tonic-gate { 348*7c478bd9Sstevel@tonic-gate const lwpstatus_t *lsp, *end; 349*7c478bd9Sstevel@tonic-gate 350*7c478bd9Sstevel@tonic-gate end = (const lwpstatus_t *)((uintptr_t)wsp->walk_data + wsp->walk_addr); 351*7c478bd9Sstevel@tonic-gate lsp = wsp->walk_arg; 352*7c478bd9Sstevel@tonic-gate 353*7c478bd9Sstevel@tonic-gate wsp->walk_arg = (void *)(lsp + 1); 354*7c478bd9Sstevel@tonic-gate 355*7c478bd9Sstevel@tonic-gate if (lsp < end) { 356*7c478bd9Sstevel@tonic-gate uintptr_t addr = lsp->pr_oldcontext; 357*7c478bd9Sstevel@tonic-gate ucontext_t uc; 358*7c478bd9Sstevel@tonic-gate 359*7c478bd9Sstevel@tonic-gate if (addr == NULL) 360*7c478bd9Sstevel@tonic-gate return (WALK_NEXT); 361*7c478bd9Sstevel@tonic-gate 362*7c478bd9Sstevel@tonic-gate if (mdb_vread(&uc, sizeof (uc), addr) != sizeof (uc)) { 363*7c478bd9Sstevel@tonic-gate mdb_warn("failed to read ucontext at %p", addr); 364*7c478bd9Sstevel@tonic-gate return (WALK_NEXT); 365*7c478bd9Sstevel@tonic-gate } 366*7c478bd9Sstevel@tonic-gate 367*7c478bd9Sstevel@tonic-gate return (wsp->walk_callback(addr, &uc, wsp->walk_cbdata)); 368*7c478bd9Sstevel@tonic-gate } 369*7c478bd9Sstevel@tonic-gate 370*7c478bd9Sstevel@tonic-gate return (WALK_DONE); 371*7c478bd9Sstevel@tonic-gate } 372*7c478bd9Sstevel@tonic-gate 373*7c478bd9Sstevel@tonic-gate static void 374*7c478bd9Sstevel@tonic-gate oldc_walk_fini(mdb_walk_state_t *wsp) 375*7c478bd9Sstevel@tonic-gate { 376*7c478bd9Sstevel@tonic-gate mdb_free(wsp->walk_data, wsp->walk_addr); /* walk_addr has size */ 377*7c478bd9Sstevel@tonic-gate } 378*7c478bd9Sstevel@tonic-gate 379*7c478bd9Sstevel@tonic-gate /* 380*7c478bd9Sstevel@tonic-gate * ==================== threads ========================== 381*7c478bd9Sstevel@tonic-gate * These are the interfaces that used to require libthread. 382*7c478bd9Sstevel@tonic-gate * Now, libthread has been folded into libc. 383*7c478bd9Sstevel@tonic-gate * ======================================================= 384*7c478bd9Sstevel@tonic-gate */ 385*7c478bd9Sstevel@tonic-gate 386*7c478bd9Sstevel@tonic-gate /* 387*7c478bd9Sstevel@tonic-gate * prt_addr() is called up to three times to generate arguments for 388*7c478bd9Sstevel@tonic-gate * one call to mdb_printf(). We must return at least three different 389*7c478bd9Sstevel@tonic-gate * pointers to static storage for consecutive calls to prt_addr(). 390*7c478bd9Sstevel@tonic-gate */ 391*7c478bd9Sstevel@tonic-gate static const char * 392*7c478bd9Sstevel@tonic-gate prt_addr(void *addr, int pad) 393*7c478bd9Sstevel@tonic-gate { 394*7c478bd9Sstevel@tonic-gate static char buffer[4][24]; 395*7c478bd9Sstevel@tonic-gate static int ix = 0; 396*7c478bd9Sstevel@tonic-gate char *buf; 397*7c478bd9Sstevel@tonic-gate 398*7c478bd9Sstevel@tonic-gate if (ix == 4) /* use buffers in sequence: 0, 1, 2, 3 */ 399*7c478bd9Sstevel@tonic-gate ix = 0; 400*7c478bd9Sstevel@tonic-gate buf = buffer[ix++]; 401*7c478bd9Sstevel@tonic-gate if (addr == NULL) 402*7c478bd9Sstevel@tonic-gate return (pad? "<NULL> " : "<NULL>"); 403*7c478bd9Sstevel@tonic-gate else { 404*7c478bd9Sstevel@tonic-gate #ifdef _LP64 405*7c478bd9Sstevel@tonic-gate (void) mdb_snprintf(buf, sizeof (buffer[0]), "0x%016lx", addr); 406*7c478bd9Sstevel@tonic-gate if (pad) 407*7c478bd9Sstevel@tonic-gate (void) strcpy(buf + 18, " "); 408*7c478bd9Sstevel@tonic-gate #else 409*7c478bd9Sstevel@tonic-gate (void) mdb_snprintf(buf, sizeof (buffer[0]), "0x%08lx", addr); 410*7c478bd9Sstevel@tonic-gate if (pad) 411*7c478bd9Sstevel@tonic-gate (void) strcpy(buf + 10, " "); 412*7c478bd9Sstevel@tonic-gate #endif /* _LP64 */ 413*7c478bd9Sstevel@tonic-gate return (buf); 414*7c478bd9Sstevel@tonic-gate } 415*7c478bd9Sstevel@tonic-gate } 416*7c478bd9Sstevel@tonic-gate 417*7c478bd9Sstevel@tonic-gate #define HD(str) mdb_printf(" " str "\n") 418*7c478bd9Sstevel@tonic-gate #define OFFSTR "+0x%-7lx " 419*7c478bd9Sstevel@tonic-gate #define OFFSET(member) ((size_t)OFFSETOF(ulwp_t, member)) 420*7c478bd9Sstevel@tonic-gate 421*7c478bd9Sstevel@tonic-gate /*ARGSUSED*/ 422*7c478bd9Sstevel@tonic-gate static int 423*7c478bd9Sstevel@tonic-gate d_ulwp(uintptr_t addr, uint_t flags, int argc, const mdb_arg_t *argv) 424*7c478bd9Sstevel@tonic-gate { 425*7c478bd9Sstevel@tonic-gate ulwp_t ulwp; 426*7c478bd9Sstevel@tonic-gate 427*7c478bd9Sstevel@tonic-gate if (argc != 0 || !(flags & DCMD_ADDRSPEC)) 428*7c478bd9Sstevel@tonic-gate return (DCMD_USAGE); 429*7c478bd9Sstevel@tonic-gate 430*7c478bd9Sstevel@tonic-gate if (mdb_vread(&ulwp, sizeof (ulwp), addr) != sizeof (ulwp) && 431*7c478bd9Sstevel@tonic-gate (bzero(&ulwp, sizeof (ulwp)), 432*7c478bd9Sstevel@tonic-gate mdb_vread(&ulwp, REPLACEMENT_SIZE, addr)) != REPLACEMENT_SIZE) { 433*7c478bd9Sstevel@tonic-gate mdb_warn("failed to read ulwp at 0x%p", addr); 434*7c478bd9Sstevel@tonic-gate return (DCMD_ERR); 435*7c478bd9Sstevel@tonic-gate } 436*7c478bd9Sstevel@tonic-gate 437*7c478bd9Sstevel@tonic-gate mdb_printf("%#a\n", addr); 438*7c478bd9Sstevel@tonic-gate 439*7c478bd9Sstevel@tonic-gate HD("self uberdata"); 440*7c478bd9Sstevel@tonic-gate mdb_printf(OFFSTR "%s %s\n", 441*7c478bd9Sstevel@tonic-gate OFFSET(ul_self), 442*7c478bd9Sstevel@tonic-gate prt_addr(ulwp.ul_self, 1), 443*7c478bd9Sstevel@tonic-gate prt_addr(ulwp.ul_uberdata, 0)); 444*7c478bd9Sstevel@tonic-gate 445*7c478bd9Sstevel@tonic-gate HD("tlsent ntlsent"); 446*7c478bd9Sstevel@tonic-gate mdb_printf(OFFSTR "%s %ld\n", 447*7c478bd9Sstevel@tonic-gate OFFSET(ul_tlsent), 448*7c478bd9Sstevel@tonic-gate prt_addr(ulwp.ul_tlsent, 1), 449*7c478bd9Sstevel@tonic-gate ulwp.ul_ntlsent); 450*7c478bd9Sstevel@tonic-gate 451*7c478bd9Sstevel@tonic-gate HD("forw back next"); 452*7c478bd9Sstevel@tonic-gate mdb_printf(OFFSTR "%s %s %s\n", 453*7c478bd9Sstevel@tonic-gate OFFSET(ul_forw), 454*7c478bd9Sstevel@tonic-gate prt_addr(ulwp.ul_forw, 1), 455*7c478bd9Sstevel@tonic-gate prt_addr(ulwp.ul_back, 1), 456*7c478bd9Sstevel@tonic-gate prt_addr(ulwp.ul_next, 0)); 457*7c478bd9Sstevel@tonic-gate 458*7c478bd9Sstevel@tonic-gate HD("hash rval stk"); 459*7c478bd9Sstevel@tonic-gate mdb_printf(OFFSTR "%s %s %s\n", 460*7c478bd9Sstevel@tonic-gate OFFSET(ul_hash), 461*7c478bd9Sstevel@tonic-gate prt_addr(ulwp.ul_hash, 1), 462*7c478bd9Sstevel@tonic-gate prt_addr(ulwp.ul_rval, 1), 463*7c478bd9Sstevel@tonic-gate prt_addr(ulwp.ul_stk, 0)); 464*7c478bd9Sstevel@tonic-gate 465*7c478bd9Sstevel@tonic-gate HD("mapsiz guardsize stktop stksiz"); 466*7c478bd9Sstevel@tonic-gate mdb_printf(OFFSTR "%-10ld %-10ld %s %ld\n", 467*7c478bd9Sstevel@tonic-gate OFFSET(ul_mapsiz), 468*7c478bd9Sstevel@tonic-gate ulwp.ul_mapsiz, 469*7c478bd9Sstevel@tonic-gate ulwp.ul_guardsize, 470*7c478bd9Sstevel@tonic-gate prt_addr((void *)ulwp.ul_stktop, 1), 471*7c478bd9Sstevel@tonic-gate ulwp.ul_stksiz); 472*7c478bd9Sstevel@tonic-gate 473*7c478bd9Sstevel@tonic-gate HD("ustack.ss_sp ustack.ss_size ustack.ss_flags"); 474*7c478bd9Sstevel@tonic-gate mdb_printf(OFFSTR "%s %-21ld %s\n", 475*7c478bd9Sstevel@tonic-gate OFFSET(ul_ustack.ss_sp), 476*7c478bd9Sstevel@tonic-gate prt_addr(ulwp.ul_ustack.ss_sp, 1), 477*7c478bd9Sstevel@tonic-gate ulwp.ul_ustack.ss_size, 478*7c478bd9Sstevel@tonic-gate stack_flags(&ulwp.ul_ustack)); 479*7c478bd9Sstevel@tonic-gate 480*7c478bd9Sstevel@tonic-gate HD("ix lwpid pri mappedpri policy pri_mapped"); 481*7c478bd9Sstevel@tonic-gate mdb_printf(OFFSTR "%-10d %-10d %-10d %-10d %-10d %d\n", 482*7c478bd9Sstevel@tonic-gate OFFSET(ul_ix), 483*7c478bd9Sstevel@tonic-gate ulwp.ul_ix, 484*7c478bd9Sstevel@tonic-gate ulwp.ul_lwpid, 485*7c478bd9Sstevel@tonic-gate ulwp.ul_pri, 486*7c478bd9Sstevel@tonic-gate ulwp.ul_mappedpri, 487*7c478bd9Sstevel@tonic-gate ulwp.ul_policy, 488*7c478bd9Sstevel@tonic-gate ulwp.ul_pri_mapped); 489*7c478bd9Sstevel@tonic-gate 490*7c478bd9Sstevel@tonic-gate HD("cursig pleasestop stop signalled dead unwind"); 491*7c478bd9Sstevel@tonic-gate mdb_printf(OFFSTR "%-10d ", 492*7c478bd9Sstevel@tonic-gate OFFSET(ul_cursig), 493*7c478bd9Sstevel@tonic-gate ulwp.ul_cursig); 494*7c478bd9Sstevel@tonic-gate mdb_printf(ulwp.ul_pleasestop? "0x%-8x " : "%-10d ", 495*7c478bd9Sstevel@tonic-gate ulwp.ul_pleasestop); 496*7c478bd9Sstevel@tonic-gate mdb_printf(ulwp.ul_stop? "0x%-8x " : "%-10d ", 497*7c478bd9Sstevel@tonic-gate ulwp.ul_stop); 498*7c478bd9Sstevel@tonic-gate mdb_printf("%-10d %-10d %d\n", 499*7c478bd9Sstevel@tonic-gate ulwp.ul_signalled, 500*7c478bd9Sstevel@tonic-gate ulwp.ul_dead, 501*7c478bd9Sstevel@tonic-gate ulwp.ul_unwind); 502*7c478bd9Sstevel@tonic-gate 503*7c478bd9Sstevel@tonic-gate HD("detached writer stopping pad4 preempt savpreempt"); 504*7c478bd9Sstevel@tonic-gate mdb_printf(OFFSTR "%-10d %-10d %-10d %-10d %-10d %d\n", 505*7c478bd9Sstevel@tonic-gate OFFSET(ul_detached), 506*7c478bd9Sstevel@tonic-gate ulwp.ul_detached, 507*7c478bd9Sstevel@tonic-gate ulwp.ul_writer, 508*7c478bd9Sstevel@tonic-gate ulwp.ul_stopping, 509*7c478bd9Sstevel@tonic-gate ulwp.ul_pad4, 510*7c478bd9Sstevel@tonic-gate ulwp.ul_preempt, 511*7c478bd9Sstevel@tonic-gate ulwp.ul_savpreempt); 512*7c478bd9Sstevel@tonic-gate 513*7c478bd9Sstevel@tonic-gate HD("sigsuspend main fork primarymap m'spinners d'noreserv"); 514*7c478bd9Sstevel@tonic-gate mdb_printf(OFFSTR "%-10d %-10d %-10d %-10d %-10d %d\n", 515*7c478bd9Sstevel@tonic-gate OFFSET(ul_sigsuspend), 516*7c478bd9Sstevel@tonic-gate ulwp.ul_sigsuspend, 517*7c478bd9Sstevel@tonic-gate ulwp.ul_main, 518*7c478bd9Sstevel@tonic-gate ulwp.ul_fork, 519*7c478bd9Sstevel@tonic-gate ulwp.ul_primarymap, 520*7c478bd9Sstevel@tonic-gate ulwp.ul_max_spinners, 521*7c478bd9Sstevel@tonic-gate ulwp.ul_door_noreserve); 522*7c478bd9Sstevel@tonic-gate 523*7c478bd9Sstevel@tonic-gate HD("queue_fifo c'w'defer e'detect' async_safe pad1[0] pad1[1]"); 524*7c478bd9Sstevel@tonic-gate mdb_printf(OFFSTR "%-10d %-10d %-10d %-10d %-10d %d\n", 525*7c478bd9Sstevel@tonic-gate OFFSET(ul_queue_fifo), 526*7c478bd9Sstevel@tonic-gate ulwp.ul_queue_fifo, 527*7c478bd9Sstevel@tonic-gate ulwp.ul_cond_wait_defer, 528*7c478bd9Sstevel@tonic-gate ulwp.ul_error_detection, 529*7c478bd9Sstevel@tonic-gate ulwp.ul_async_safe, 530*7c478bd9Sstevel@tonic-gate ulwp.ul_pad1[0], 531*7c478bd9Sstevel@tonic-gate ulwp.ul_pad1[1]); 532*7c478bd9Sstevel@tonic-gate 533*7c478bd9Sstevel@tonic-gate HD("adapt'spin rele'spin queue_spin critical sigdefer vfork"); 534*7c478bd9Sstevel@tonic-gate mdb_printf(OFFSTR "%-10d %-10d %-10d %-10d %-10d %d\n", 535*7c478bd9Sstevel@tonic-gate OFFSET(ul_adaptive_spin), 536*7c478bd9Sstevel@tonic-gate ulwp.ul_adaptive_spin, 537*7c478bd9Sstevel@tonic-gate ulwp.ul_release_spin, 538*7c478bd9Sstevel@tonic-gate ulwp.ul_queue_spin, 539*7c478bd9Sstevel@tonic-gate ulwp.ul_critical, 540*7c478bd9Sstevel@tonic-gate ulwp.ul_sigdefer, 541*7c478bd9Sstevel@tonic-gate ulwp.ul_vfork); 542*7c478bd9Sstevel@tonic-gate 543*7c478bd9Sstevel@tonic-gate HD("cancelable c'pending c'disabled c'async save_async mutator"); 544*7c478bd9Sstevel@tonic-gate mdb_printf(OFFSTR "%-10d %-10d %-10d %-10d %-10d %d\n", 545*7c478bd9Sstevel@tonic-gate OFFSET(ul_cancelable), 546*7c478bd9Sstevel@tonic-gate ulwp.ul_cancelable, 547*7c478bd9Sstevel@tonic-gate ulwp.ul_cancel_pending, 548*7c478bd9Sstevel@tonic-gate ulwp.ul_cancel_disabled, 549*7c478bd9Sstevel@tonic-gate ulwp.ul_cancel_async, 550*7c478bd9Sstevel@tonic-gate ulwp.ul_save_async, 551*7c478bd9Sstevel@tonic-gate ulwp.ul_mutator); 552*7c478bd9Sstevel@tonic-gate 553*7c478bd9Sstevel@tonic-gate HD("created replace nocancel errno errnop"); 554*7c478bd9Sstevel@tonic-gate mdb_printf(OFFSTR "%-10d %-10d %-10d %-10d %s\n", 555*7c478bd9Sstevel@tonic-gate OFFSET(ul_created), 556*7c478bd9Sstevel@tonic-gate ulwp.ul_created, 557*7c478bd9Sstevel@tonic-gate ulwp.ul_replace, 558*7c478bd9Sstevel@tonic-gate ulwp.ul_nocancel, 559*7c478bd9Sstevel@tonic-gate ulwp.ul_errno, 560*7c478bd9Sstevel@tonic-gate prt_addr(ulwp.ul_errnop, 0)); 561*7c478bd9Sstevel@tonic-gate 562*7c478bd9Sstevel@tonic-gate HD("clnup_hdr schedctl_called schedctl"); 563*7c478bd9Sstevel@tonic-gate mdb_printf(OFFSTR "%s %s %s\n", 564*7c478bd9Sstevel@tonic-gate OFFSET(ul_clnup_hdr), 565*7c478bd9Sstevel@tonic-gate prt_addr(ulwp.ul_clnup_hdr, 1), 566*7c478bd9Sstevel@tonic-gate prt_addr(ulwp.ul_schedctl_called, 1), 567*7c478bd9Sstevel@tonic-gate prt_addr((void *)ulwp.ul_schedctl, 0)); 568*7c478bd9Sstevel@tonic-gate 569*7c478bd9Sstevel@tonic-gate HD("bindflags gs stsd &ftsd"); 570*7c478bd9Sstevel@tonic-gate mdb_printf(OFFSTR, 571*7c478bd9Sstevel@tonic-gate OFFSET(ul_bindflags)); 572*7c478bd9Sstevel@tonic-gate mdb_printf(ulwp.ul_bindflags? "0x%-8x " : "%-10d ", 573*7c478bd9Sstevel@tonic-gate ulwp.ul_bindflags); 574*7c478bd9Sstevel@tonic-gate mdb_printf(ulwp.ul_gs? "0x%-8x " : "%-10d ", 575*7c478bd9Sstevel@tonic-gate ulwp.ul_gs); 576*7c478bd9Sstevel@tonic-gate mdb_printf("%s %s\n", 577*7c478bd9Sstevel@tonic-gate prt_addr(ulwp.ul_stsd, 1), 578*7c478bd9Sstevel@tonic-gate prt_addr((void *)(addr + OFFSET(ul_ftsd[0])), 0)); 579*7c478bd9Sstevel@tonic-gate 580*7c478bd9Sstevel@tonic-gate HD("eventmask[0..1] eventnum eventdata"); 581*7c478bd9Sstevel@tonic-gate mdb_printf(OFFSTR "0x%08x 0x%08x %-21d %s\n", 582*7c478bd9Sstevel@tonic-gate OFFSET(ul_td_evbuf.eventmask.event_bits[0]), 583*7c478bd9Sstevel@tonic-gate ulwp.ul_td_evbuf.eventmask.event_bits[0], 584*7c478bd9Sstevel@tonic-gate ulwp.ul_td_evbuf.eventmask.event_bits[1], 585*7c478bd9Sstevel@tonic-gate ulwp.ul_td_evbuf.eventnum, 586*7c478bd9Sstevel@tonic-gate prt_addr(ulwp.ul_td_evbuf.eventdata, 0)); 587*7c478bd9Sstevel@tonic-gate 588*7c478bd9Sstevel@tonic-gate HD("td'enable sync'reg qtype cv_wake usropts"); 589*7c478bd9Sstevel@tonic-gate mdb_printf(OFFSTR "%-10d %-10d %-10d %-10d ", 590*7c478bd9Sstevel@tonic-gate OFFSET(ul_td_events_enable), 591*7c478bd9Sstevel@tonic-gate ulwp.ul_td_events_enable, 592*7c478bd9Sstevel@tonic-gate ulwp.ul_sync_obj_reg, 593*7c478bd9Sstevel@tonic-gate ulwp.ul_qtype, 594*7c478bd9Sstevel@tonic-gate ulwp.ul_cv_wake); 595*7c478bd9Sstevel@tonic-gate mdb_printf(ulwp.ul_usropts? "0x%x\n" : "%d\n", 596*7c478bd9Sstevel@tonic-gate ulwp.ul_usropts); 597*7c478bd9Sstevel@tonic-gate 598*7c478bd9Sstevel@tonic-gate HD("startpc startarg wchan"); 599*7c478bd9Sstevel@tonic-gate mdb_printf(OFFSTR "%s %s %s\n", 600*7c478bd9Sstevel@tonic-gate OFFSET(ul_startpc), 601*7c478bd9Sstevel@tonic-gate prt_addr((void *)ulwp.ul_startpc, 1), 602*7c478bd9Sstevel@tonic-gate prt_addr(ulwp.ul_startarg, 1), 603*7c478bd9Sstevel@tonic-gate prt_addr(ulwp.ul_wchan, 0)); 604*7c478bd9Sstevel@tonic-gate 605*7c478bd9Sstevel@tonic-gate HD("link sleepq cvmutex"); 606*7c478bd9Sstevel@tonic-gate mdb_printf(OFFSTR "%s %s %s\n", 607*7c478bd9Sstevel@tonic-gate OFFSET(ul_link), 608*7c478bd9Sstevel@tonic-gate prt_addr(ulwp.ul_link, 1), 609*7c478bd9Sstevel@tonic-gate prt_addr(ulwp.ul_sleepq, 1), 610*7c478bd9Sstevel@tonic-gate prt_addr(ulwp.ul_cvmutex, 0)); 611*7c478bd9Sstevel@tonic-gate 612*7c478bd9Sstevel@tonic-gate HD("mxchain epri emappedpri rdlocks"); 613*7c478bd9Sstevel@tonic-gate mdb_printf(OFFSTR "%s %-10d %-10d %d\n", 614*7c478bd9Sstevel@tonic-gate OFFSET(ul_mxchain), 615*7c478bd9Sstevel@tonic-gate prt_addr(ulwp.ul_mxchain, 1), 616*7c478bd9Sstevel@tonic-gate ulwp.ul_epri, 617*7c478bd9Sstevel@tonic-gate ulwp.ul_emappedpri, 618*7c478bd9Sstevel@tonic-gate ulwp.ul_rdlocks); 619*7c478bd9Sstevel@tonic-gate 620*7c478bd9Sstevel@tonic-gate HD("rd_rwlock rd_count tpdp"); 621*7c478bd9Sstevel@tonic-gate mdb_printf(OFFSTR "%s %-21ld %s\n", 622*7c478bd9Sstevel@tonic-gate OFFSET(ul_readlock.single.rd_rwlock), 623*7c478bd9Sstevel@tonic-gate prt_addr(ulwp.ul_readlock.single.rd_rwlock, 1), 624*7c478bd9Sstevel@tonic-gate ulwp.ul_readlock.single.rd_count, 625*7c478bd9Sstevel@tonic-gate prt_addr(ulwp.ul_tpdp, 0)); 626*7c478bd9Sstevel@tonic-gate 627*7c478bd9Sstevel@tonic-gate HD("siglink s'l'spin s'l'spin2 s'l'sleep s'l'wakeup"); 628*7c478bd9Sstevel@tonic-gate mdb_printf(OFFSTR "%s %-10d %-10d %-10d %-10d\n", 629*7c478bd9Sstevel@tonic-gate OFFSET(ul_siglink), 630*7c478bd9Sstevel@tonic-gate prt_addr(ulwp.ul_siglink, 1), 631*7c478bd9Sstevel@tonic-gate ulwp.ul_spin_lock_spin, 632*7c478bd9Sstevel@tonic-gate ulwp.ul_spin_lock_spin2, 633*7c478bd9Sstevel@tonic-gate ulwp.ul_spin_lock_sleep, 634*7c478bd9Sstevel@tonic-gate ulwp.ul_spin_lock_wakeup); 635*7c478bd9Sstevel@tonic-gate 636*7c478bd9Sstevel@tonic-gate /* 637*7c478bd9Sstevel@tonic-gate * The remainder of the ulwp_t structure 638*7c478bd9Sstevel@tonic-gate * is invalid if this is a replacement. 639*7c478bd9Sstevel@tonic-gate */ 640*7c478bd9Sstevel@tonic-gate if (ulwp.ul_replace) 641*7c478bd9Sstevel@tonic-gate return (DCMD_OK); 642*7c478bd9Sstevel@tonic-gate 643*7c478bd9Sstevel@tonic-gate HD("sigmask[0..3]"); 644*7c478bd9Sstevel@tonic-gate mdb_printf(OFFSTR "0x%08x 0x%08x 0x%08x 0x%08x\n", 645*7c478bd9Sstevel@tonic-gate OFFSET(ul_sigmask.__sigbits[0]), 646*7c478bd9Sstevel@tonic-gate ulwp.ul_sigmask.__sigbits[0], 647*7c478bd9Sstevel@tonic-gate ulwp.ul_sigmask.__sigbits[1], 648*7c478bd9Sstevel@tonic-gate ulwp.ul_sigmask.__sigbits[2], 649*7c478bd9Sstevel@tonic-gate ulwp.ul_sigmask.__sigbits[3]); 650*7c478bd9Sstevel@tonic-gate 651*7c478bd9Sstevel@tonic-gate HD("tmpmask[0..3]"); 652*7c478bd9Sstevel@tonic-gate mdb_printf(OFFSTR "0x%08x 0x%08x 0x%08x 0x%08x\n", 653*7c478bd9Sstevel@tonic-gate OFFSET(ul_tmpmask.__sigbits[0]), 654*7c478bd9Sstevel@tonic-gate ulwp.ul_tmpmask.__sigbits[0], 655*7c478bd9Sstevel@tonic-gate ulwp.ul_tmpmask.__sigbits[1], 656*7c478bd9Sstevel@tonic-gate ulwp.ul_tmpmask.__sigbits[2], 657*7c478bd9Sstevel@tonic-gate ulwp.ul_tmpmask.__sigbits[3]); 658*7c478bd9Sstevel@tonic-gate 659*7c478bd9Sstevel@tonic-gate HD("&siginfo &spinlock &fpuenv"); 660*7c478bd9Sstevel@tonic-gate mdb_printf(OFFSTR "%s %s %s\n", 661*7c478bd9Sstevel@tonic-gate OFFSET(ul_siginfo), 662*7c478bd9Sstevel@tonic-gate prt_addr((void *)(addr + OFFSET(ul_siginfo)), 1), 663*7c478bd9Sstevel@tonic-gate prt_addr((void *)(addr + OFFSET(ul_spinlock)), 1), 664*7c478bd9Sstevel@tonic-gate prt_addr((void *)(addr + OFFSET(ul_fpuenv)), 0)); 665*7c478bd9Sstevel@tonic-gate 666*7c478bd9Sstevel@tonic-gate return (DCMD_OK); 667*7c478bd9Sstevel@tonic-gate } 668*7c478bd9Sstevel@tonic-gate 669*7c478bd9Sstevel@tonic-gate /* 670*7c478bd9Sstevel@tonic-gate * Get the address of the unique uberdata_t structure. 671*7c478bd9Sstevel@tonic-gate */ 672*7c478bd9Sstevel@tonic-gate static uintptr_t 673*7c478bd9Sstevel@tonic-gate uberdata_addr(void) 674*7c478bd9Sstevel@tonic-gate { 675*7c478bd9Sstevel@tonic-gate uintptr_t uaddr; 676*7c478bd9Sstevel@tonic-gate uintptr_t addr; 677*7c478bd9Sstevel@tonic-gate GElf_Sym sym; 678*7c478bd9Sstevel@tonic-gate 679*7c478bd9Sstevel@tonic-gate if (mdb_lookup_by_obj("libc.so.1", "_tdb_bootstrap", &sym) != 0) { 680*7c478bd9Sstevel@tonic-gate mdb_warn("cannot find libc.so.1`_tdb_bootstrap"); 681*7c478bd9Sstevel@tonic-gate return (NULL); 682*7c478bd9Sstevel@tonic-gate } 683*7c478bd9Sstevel@tonic-gate if (mdb_vread(&addr, sizeof (addr), sym.st_value) == sizeof (addr) && 684*7c478bd9Sstevel@tonic-gate addr != NULL && 685*7c478bd9Sstevel@tonic-gate mdb_vread(&uaddr, sizeof (uaddr), addr) == sizeof (uaddr) && 686*7c478bd9Sstevel@tonic-gate uaddr != NULL) { 687*7c478bd9Sstevel@tonic-gate return (uaddr); 688*7c478bd9Sstevel@tonic-gate } 689*7c478bd9Sstevel@tonic-gate if (mdb_lookup_by_obj("libc.so.1", "_uberdata", &sym) != 0) { 690*7c478bd9Sstevel@tonic-gate mdb_warn("cannot find libc.so.1`_uberdata"); 691*7c478bd9Sstevel@tonic-gate return (NULL); 692*7c478bd9Sstevel@tonic-gate } 693*7c478bd9Sstevel@tonic-gate return ((uintptr_t)sym.st_value); 694*7c478bd9Sstevel@tonic-gate } 695*7c478bd9Sstevel@tonic-gate 696*7c478bd9Sstevel@tonic-gate #undef OFFSET 697*7c478bd9Sstevel@tonic-gate #define OFFSET(member) ((size_t)OFFSETOF(uberdata_t, member)) 698*7c478bd9Sstevel@tonic-gate 699*7c478bd9Sstevel@tonic-gate /*ARGSUSED*/ 700*7c478bd9Sstevel@tonic-gate static int 701*7c478bd9Sstevel@tonic-gate d_uberdata(uintptr_t addr, uint_t flags, int argc, const mdb_arg_t *argv) 702*7c478bd9Sstevel@tonic-gate { 703*7c478bd9Sstevel@tonic-gate uberdata_t uberdata; 704*7c478bd9Sstevel@tonic-gate int i; 705*7c478bd9Sstevel@tonic-gate 706*7c478bd9Sstevel@tonic-gate if (argc != 0) 707*7c478bd9Sstevel@tonic-gate return (DCMD_USAGE); 708*7c478bd9Sstevel@tonic-gate if (!(flags & DCMD_ADDRSPEC) && (addr = uberdata_addr()) == NULL) 709*7c478bd9Sstevel@tonic-gate return (DCMD_ERR); 710*7c478bd9Sstevel@tonic-gate 711*7c478bd9Sstevel@tonic-gate if (mdb_vread(&uberdata, sizeof (uberdata), addr) != 712*7c478bd9Sstevel@tonic-gate sizeof (uberdata)) { 713*7c478bd9Sstevel@tonic-gate mdb_warn("failed to read uberdata at 0x%p", addr); 714*7c478bd9Sstevel@tonic-gate return (DCMD_ERR); 715*7c478bd9Sstevel@tonic-gate } 716*7c478bd9Sstevel@tonic-gate 717*7c478bd9Sstevel@tonic-gate mdb_printf("%#a\n", addr); 718*7c478bd9Sstevel@tonic-gate 719*7c478bd9Sstevel@tonic-gate HD("&link_lock &fork_lock fork_owner"); 720*7c478bd9Sstevel@tonic-gate mdb_printf(OFFSTR "%s %s %s\n", 721*7c478bd9Sstevel@tonic-gate OFFSET(link_lock), 722*7c478bd9Sstevel@tonic-gate prt_addr((void *)(addr + OFFSET(link_lock)), 1), 723*7c478bd9Sstevel@tonic-gate prt_addr((void *)(addr + OFFSET(fork_lock)), 1), 724*7c478bd9Sstevel@tonic-gate prt_addr((void *)uberdata.fork_owner, 0)); 725*7c478bd9Sstevel@tonic-gate 726*7c478bd9Sstevel@tonic-gate HD("&tdb_hash_lock &tdb_hash_lock_stats &siguaction[0]"); 727*7c478bd9Sstevel@tonic-gate mdb_printf(OFFSTR "%s %s %s\n", 728*7c478bd9Sstevel@tonic-gate OFFSET(tdb_hash_lock), 729*7c478bd9Sstevel@tonic-gate prt_addr((void *)(addr + OFFSET(tdb_hash_lock)), 1), 730*7c478bd9Sstevel@tonic-gate prt_addr((void *)(addr + OFFSET(tdb_hash_lock_stats)), 1), 731*7c478bd9Sstevel@tonic-gate prt_addr((void *)(addr + OFFSET(siguaction)), 0)); 732*7c478bd9Sstevel@tonic-gate 733*7c478bd9Sstevel@tonic-gate HD("&bucket free_list chunks"); 734*7c478bd9Sstevel@tonic-gate for (i = 0; i < NBUCKETS; i++) { 735*7c478bd9Sstevel@tonic-gate mdb_printf(OFFSTR "%s %s %ld\n", 736*7c478bd9Sstevel@tonic-gate OFFSET(bucket[i]), 737*7c478bd9Sstevel@tonic-gate prt_addr((void *)(addr + OFFSET(bucket[i])), 1), 738*7c478bd9Sstevel@tonic-gate prt_addr(uberdata.bucket[i].free_list, 1), 739*7c478bd9Sstevel@tonic-gate uberdata.bucket[i].chunks); 740*7c478bd9Sstevel@tonic-gate } 741*7c478bd9Sstevel@tonic-gate 742*7c478bd9Sstevel@tonic-gate HD("&atexit_root head exit_frame_monitor"); 743*7c478bd9Sstevel@tonic-gate mdb_printf(OFFSTR "%s %s %s\n", 744*7c478bd9Sstevel@tonic-gate OFFSET(atexit_root), 745*7c478bd9Sstevel@tonic-gate prt_addr((void *)(addr + OFFSET(atexit_root.exitfns_lock)), 1), 746*7c478bd9Sstevel@tonic-gate prt_addr(uberdata.atexit_root.head, 1), 747*7c478bd9Sstevel@tonic-gate prt_addr(uberdata.atexit_root.exit_frame_monitor, 0)); 748*7c478bd9Sstevel@tonic-gate 749*7c478bd9Sstevel@tonic-gate HD("&tsd_metadata tsdm_nkeys tsdm_nused tsdm_destro"); 750*7c478bd9Sstevel@tonic-gate mdb_printf(OFFSTR "%s %-10d %-10d %s\n", 751*7c478bd9Sstevel@tonic-gate OFFSET(tsd_metadata), 752*7c478bd9Sstevel@tonic-gate prt_addr((void *)(addr + OFFSET(tsd_metadata.tsdm_lock)), 1), 753*7c478bd9Sstevel@tonic-gate uberdata.tsd_metadata.tsdm_nkeys, 754*7c478bd9Sstevel@tonic-gate uberdata.tsd_metadata.tsdm_nused, 755*7c478bd9Sstevel@tonic-gate prt_addr((void *)uberdata.tsd_metadata.tsdm_destro, 0)); 756*7c478bd9Sstevel@tonic-gate 757*7c478bd9Sstevel@tonic-gate HD("&tls_metadata tls_modinfo.data tls_modinfo.size"); 758*7c478bd9Sstevel@tonic-gate mdb_printf(OFFSTR "%s %s %ld\n", 759*7c478bd9Sstevel@tonic-gate OFFSET(tls_metadata), 760*7c478bd9Sstevel@tonic-gate prt_addr((void *)(addr + OFFSET(tls_metadata.tls_lock)), 1), 761*7c478bd9Sstevel@tonic-gate prt_addr(uberdata.tls_metadata.tls_modinfo.tls_data, 1), 762*7c478bd9Sstevel@tonic-gate uberdata.tls_metadata.tls_modinfo.tls_size); 763*7c478bd9Sstevel@tonic-gate 764*7c478bd9Sstevel@tonic-gate HD(" static_tls.data static_tls.size"); 765*7c478bd9Sstevel@tonic-gate mdb_printf(OFFSTR "%s %s %ld\n", 766*7c478bd9Sstevel@tonic-gate OFFSET(tls_metadata.static_tls), 767*7c478bd9Sstevel@tonic-gate " ", 768*7c478bd9Sstevel@tonic-gate prt_addr(uberdata.tls_metadata.static_tls.tls_data, 1), 769*7c478bd9Sstevel@tonic-gate uberdata.tls_metadata.static_tls.tls_size); 770*7c478bd9Sstevel@tonic-gate 771*7c478bd9Sstevel@tonic-gate HD("primary_ma bucket_ini uflags.mt uflags.pad uflags.trs uflags.ted"); 772*7c478bd9Sstevel@tonic-gate mdb_printf(OFFSTR "%-10d %-10d %-10d %-10d %-10d %d\n", 773*7c478bd9Sstevel@tonic-gate OFFSET(primary_map), 774*7c478bd9Sstevel@tonic-gate uberdata.primary_map, 775*7c478bd9Sstevel@tonic-gate uberdata.bucket_init, 776*7c478bd9Sstevel@tonic-gate uberdata.uberflags.uf_x.x_mt, 777*7c478bd9Sstevel@tonic-gate uberdata.uberflags.uf_x.x_pad, 778*7c478bd9Sstevel@tonic-gate uberdata.uberflags.uf_x.x_tdb_register_sync, 779*7c478bd9Sstevel@tonic-gate uberdata.uberflags.uf_x.x_thread_error_detection); 780*7c478bd9Sstevel@tonic-gate 781*7c478bd9Sstevel@tonic-gate HD("queue_head thr_hash_table hash_size hash_mask"); 782*7c478bd9Sstevel@tonic-gate mdb_printf(OFFSTR "%s %s %-10d 0x%x\n", 783*7c478bd9Sstevel@tonic-gate OFFSET(queue_head), 784*7c478bd9Sstevel@tonic-gate prt_addr(uberdata.queue_head, 1), 785*7c478bd9Sstevel@tonic-gate prt_addr(uberdata.thr_hash_table, 1), 786*7c478bd9Sstevel@tonic-gate uberdata.hash_size, 787*7c478bd9Sstevel@tonic-gate uberdata.hash_mask); 788*7c478bd9Sstevel@tonic-gate 789*7c478bd9Sstevel@tonic-gate HD("ulwp_one all_lwps all_zombies"); 790*7c478bd9Sstevel@tonic-gate mdb_printf(OFFSTR "%s %s %s\n", 791*7c478bd9Sstevel@tonic-gate OFFSET(ulwp_one), 792*7c478bd9Sstevel@tonic-gate prt_addr(uberdata.ulwp_one, 1), 793*7c478bd9Sstevel@tonic-gate prt_addr(uberdata.all_lwps, 1), 794*7c478bd9Sstevel@tonic-gate prt_addr(uberdata.all_zombies, 0)); 795*7c478bd9Sstevel@tonic-gate 796*7c478bd9Sstevel@tonic-gate HD("nthreads nzombies ndaemons pid sigacthandler"); 797*7c478bd9Sstevel@tonic-gate mdb_printf(OFFSTR "%-10d %-10d %-10d %-10d %s\n", 798*7c478bd9Sstevel@tonic-gate OFFSET(nthreads), 799*7c478bd9Sstevel@tonic-gate uberdata.nthreads, 800*7c478bd9Sstevel@tonic-gate uberdata.nzombies, 801*7c478bd9Sstevel@tonic-gate uberdata.ndaemons, 802*7c478bd9Sstevel@tonic-gate (int)uberdata.pid, 803*7c478bd9Sstevel@tonic-gate prt_addr((void *)uberdata.sigacthandler, 0)); 804*7c478bd9Sstevel@tonic-gate 805*7c478bd9Sstevel@tonic-gate HD("lwp_stacks lwp_laststack nfreestack stk_cache"); 806*7c478bd9Sstevel@tonic-gate mdb_printf(OFFSTR "%s %s %-10d %d\n", 807*7c478bd9Sstevel@tonic-gate OFFSET(lwp_stacks), 808*7c478bd9Sstevel@tonic-gate prt_addr(uberdata.lwp_stacks, 1), 809*7c478bd9Sstevel@tonic-gate prt_addr(uberdata.lwp_laststack, 1), 810*7c478bd9Sstevel@tonic-gate uberdata.nfreestack, 811*7c478bd9Sstevel@tonic-gate uberdata.thread_stack_cache); 812*7c478bd9Sstevel@tonic-gate 813*7c478bd9Sstevel@tonic-gate HD("ulwp_freelist ulwp_lastfree"); 814*7c478bd9Sstevel@tonic-gate mdb_printf(OFFSTR "%s %s\n", 815*7c478bd9Sstevel@tonic-gate OFFSET(ulwp_freelist), 816*7c478bd9Sstevel@tonic-gate prt_addr(uberdata.ulwp_freelist, 1), 817*7c478bd9Sstevel@tonic-gate prt_addr(uberdata.ulwp_lastfree, 0)); 818*7c478bd9Sstevel@tonic-gate 819*7c478bd9Sstevel@tonic-gate HD("ulwp_replace_free ulwp_replace_last atforklist"); 820*7c478bd9Sstevel@tonic-gate mdb_printf(OFFSTR "%s %s %s\n", 821*7c478bd9Sstevel@tonic-gate OFFSET(ulwp_replace_free), 822*7c478bd9Sstevel@tonic-gate prt_addr(uberdata.ulwp_replace_free, 1), 823*7c478bd9Sstevel@tonic-gate prt_addr(uberdata.ulwp_replace_last, 1), 824*7c478bd9Sstevel@tonic-gate prt_addr(uberdata.atforklist, 0)); 825*7c478bd9Sstevel@tonic-gate 826*7c478bd9Sstevel@tonic-gate HD("tdb_bootstrap tdb_sync_addr_hash tdb_'count tdb_'fail"); 827*7c478bd9Sstevel@tonic-gate mdb_printf(OFFSTR "%s %s %-10d %d\n", 828*7c478bd9Sstevel@tonic-gate OFFSET(tdb_bootstrap), 829*7c478bd9Sstevel@tonic-gate prt_addr(uberdata.tdb_bootstrap, 1), 830*7c478bd9Sstevel@tonic-gate prt_addr(uberdata.tdb.tdb_sync_addr_hash, 1), 831*7c478bd9Sstevel@tonic-gate uberdata.tdb.tdb_register_count, 832*7c478bd9Sstevel@tonic-gate uberdata.tdb.tdb_hash_alloc_failed); 833*7c478bd9Sstevel@tonic-gate 834*7c478bd9Sstevel@tonic-gate HD("tdb_sync_addr_free tdb_sync_addr_last tdb_sync_alloc"); 835*7c478bd9Sstevel@tonic-gate mdb_printf(OFFSTR "%s %s %ld\n", 836*7c478bd9Sstevel@tonic-gate OFFSET(tdb.tdb_sync_addr_free), 837*7c478bd9Sstevel@tonic-gate prt_addr(uberdata.tdb.tdb_sync_addr_free, 1), 838*7c478bd9Sstevel@tonic-gate prt_addr(uberdata.tdb.tdb_sync_addr_last, 1), 839*7c478bd9Sstevel@tonic-gate uberdata.tdb.tdb_sync_alloc); 840*7c478bd9Sstevel@tonic-gate 841*7c478bd9Sstevel@tonic-gate HD("tdb_ev_global_mask tdb_events"); 842*7c478bd9Sstevel@tonic-gate mdb_printf(OFFSTR "0x%08x 0x%08x %s\n", 843*7c478bd9Sstevel@tonic-gate OFFSET(tdb.tdb_ev_global_mask), 844*7c478bd9Sstevel@tonic-gate uberdata.tdb.tdb_ev_global_mask.event_bits[0], 845*7c478bd9Sstevel@tonic-gate uberdata.tdb.tdb_ev_global_mask.event_bits[1], 846*7c478bd9Sstevel@tonic-gate prt_addr((void *)uberdata.tdb.tdb_events, 0)); 847*7c478bd9Sstevel@tonic-gate 848*7c478bd9Sstevel@tonic-gate return (DCMD_OK); 849*7c478bd9Sstevel@tonic-gate } 850*7c478bd9Sstevel@tonic-gate 851*7c478bd9Sstevel@tonic-gate static int 852*7c478bd9Sstevel@tonic-gate ulwp_walk_init(mdb_walk_state_t *wsp) 853*7c478bd9Sstevel@tonic-gate { 854*7c478bd9Sstevel@tonic-gate uintptr_t addr = wsp->walk_addr; 855*7c478bd9Sstevel@tonic-gate uintptr_t uber_addr; 856*7c478bd9Sstevel@tonic-gate 857*7c478bd9Sstevel@tonic-gate if (addr == NULL && 858*7c478bd9Sstevel@tonic-gate ((uber_addr = uberdata_addr()) == NULL || 859*7c478bd9Sstevel@tonic-gate mdb_vread(&addr, sizeof (addr), 860*7c478bd9Sstevel@tonic-gate uber_addr + OFFSETOF(uberdata_t, all_lwps)) 861*7c478bd9Sstevel@tonic-gate != sizeof (addr))) { 862*7c478bd9Sstevel@tonic-gate mdb_warn("cannot find 'uberdata.all_lwps'"); 863*7c478bd9Sstevel@tonic-gate return (WALK_ERR); 864*7c478bd9Sstevel@tonic-gate } 865*7c478bd9Sstevel@tonic-gate if (addr == NULL) 866*7c478bd9Sstevel@tonic-gate return (WALK_DONE); 867*7c478bd9Sstevel@tonic-gate wsp->walk_addr = addr; 868*7c478bd9Sstevel@tonic-gate wsp->walk_data = (void *)addr; 869*7c478bd9Sstevel@tonic-gate return (WALK_NEXT); 870*7c478bd9Sstevel@tonic-gate } 871*7c478bd9Sstevel@tonic-gate 872*7c478bd9Sstevel@tonic-gate static int 873*7c478bd9Sstevel@tonic-gate ulwp_walk_step(mdb_walk_state_t *wsp) 874*7c478bd9Sstevel@tonic-gate { 875*7c478bd9Sstevel@tonic-gate uintptr_t addr = wsp->walk_addr; 876*7c478bd9Sstevel@tonic-gate ulwp_t ulwp; 877*7c478bd9Sstevel@tonic-gate 878*7c478bd9Sstevel@tonic-gate if (addr == NULL) 879*7c478bd9Sstevel@tonic-gate return (WALK_DONE); 880*7c478bd9Sstevel@tonic-gate if (mdb_vread(&ulwp, sizeof (ulwp), addr) != sizeof (ulwp) && 881*7c478bd9Sstevel@tonic-gate (bzero(&ulwp, sizeof (ulwp)), 882*7c478bd9Sstevel@tonic-gate mdb_vread(&ulwp, REPLACEMENT_SIZE, addr)) != REPLACEMENT_SIZE) { 883*7c478bd9Sstevel@tonic-gate mdb_warn("failed to read ulwp at 0x%p", addr); 884*7c478bd9Sstevel@tonic-gate return (WALK_ERR); 885*7c478bd9Sstevel@tonic-gate } 886*7c478bd9Sstevel@tonic-gate /* 887*7c478bd9Sstevel@tonic-gate * If we have looped around to the beginning 888*7c478bd9Sstevel@tonic-gate * of the circular linked list, we are done. 889*7c478bd9Sstevel@tonic-gate */ 890*7c478bd9Sstevel@tonic-gate if ((wsp->walk_addr = (uintptr_t)ulwp.ul_forw) 891*7c478bd9Sstevel@tonic-gate == (uintptr_t)wsp->walk_data) 892*7c478bd9Sstevel@tonic-gate wsp->walk_addr = NULL; 893*7c478bd9Sstevel@tonic-gate return (wsp->walk_callback(addr, &ulwp, wsp->walk_cbdata)); 894*7c478bd9Sstevel@tonic-gate } 895*7c478bd9Sstevel@tonic-gate 896*7c478bd9Sstevel@tonic-gate /* 897*7c478bd9Sstevel@tonic-gate * ======================================================= 898*7c478bd9Sstevel@tonic-gate * End of thread (previously libthread) interfaces. 899*7c478bd9Sstevel@tonic-gate * ==================== threads ========================== 900*7c478bd9Sstevel@tonic-gate */ 901*7c478bd9Sstevel@tonic-gate 902*7c478bd9Sstevel@tonic-gate static const mdb_dcmd_t dcmds[] = { 903*7c478bd9Sstevel@tonic-gate { "jmp_buf", ":", "print jmp_buf contents", d_jmp_buf, NULL }, 904*7c478bd9Sstevel@tonic-gate { "sigjmp_buf", ":", "print sigjmp_buf contents", d_sigjmp_buf, NULL }, 905*7c478bd9Sstevel@tonic-gate { "siginfo", ":", "print siginfo_t structure", d_siginfo, NULL }, 906*7c478bd9Sstevel@tonic-gate { "ucontext", ":", "print ucontext_t structure", d_ucontext, NULL }, 907*7c478bd9Sstevel@tonic-gate { "ulwp", ":", "print ulwp_t structure", d_ulwp, NULL }, 908*7c478bd9Sstevel@tonic-gate { "uberdata", ":", "print uberdata_t structure", d_uberdata, NULL }, 909*7c478bd9Sstevel@tonic-gate { NULL } 910*7c478bd9Sstevel@tonic-gate }; 911*7c478bd9Sstevel@tonic-gate 912*7c478bd9Sstevel@tonic-gate static const mdb_walker_t walkers[] = { 913*7c478bd9Sstevel@tonic-gate { "ucontext", "walk ucontext_t uc_link list", 914*7c478bd9Sstevel@tonic-gate NULL, uc_walk_step, NULL, NULL }, 915*7c478bd9Sstevel@tonic-gate { "oldcontext", "walk per-lwp oldcontext pointers", 916*7c478bd9Sstevel@tonic-gate oldc_walk_init, oldc_walk_step, oldc_walk_fini, NULL }, 917*7c478bd9Sstevel@tonic-gate { "ulwps", "walk list of ulwp_t pointers", 918*7c478bd9Sstevel@tonic-gate ulwp_walk_init, ulwp_walk_step, NULL, NULL }, 919*7c478bd9Sstevel@tonic-gate { NULL } 920*7c478bd9Sstevel@tonic-gate }; 921*7c478bd9Sstevel@tonic-gate 922*7c478bd9Sstevel@tonic-gate static const mdb_modinfo_t modinfo = { MDB_API_VERSION, dcmds, walkers }; 923*7c478bd9Sstevel@tonic-gate 924*7c478bd9Sstevel@tonic-gate const mdb_modinfo_t * 925*7c478bd9Sstevel@tonic-gate _mdb_init(void) 926*7c478bd9Sstevel@tonic-gate { 927*7c478bd9Sstevel@tonic-gate return (&modinfo); 928*7c478bd9Sstevel@tonic-gate } 929