1 /* 2 * CDDL HEADER START 3 * 4 * The contents of this file are subject to the terms of the 5 * Common Development and Distribution License, Version 1.0 only 6 * (the "License"). You may not use this file except in compliance 7 * with the License. 8 * 9 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 10 * or http://www.opensolaris.org/os/licensing. 11 * See the License for the specific language governing permissions 12 * and limitations under the License. 13 * 14 * When distributing Covered Code, include this CDDL HEADER in each 15 * file and include the License file at usr/src/OPENSOLARIS.LICENSE. 16 * If applicable, add the following below this CDDL HEADER, with the 17 * fields enclosed by brackets "[]" replaced with your own identifying 18 * information: Portions Copyright [yyyy] [name of copyright owner] 19 * 20 * CDDL HEADER END 21 */ 22 /* 23 * Copyright 2004 Sun Microsystems, Inc. All rights reserved. 24 * Use is subject to license terms. 25 */ 26 27 #pragma ident "%Z%%M% %I% %E% SMI" 28 29 #include <sys/mdb_modapi.h> 30 31 #include <fmd_trace.h> 32 #include <fmd_module.h> 33 #include <fmd_thread.h> 34 #include <fmd_ustat.h> 35 #include <fmd_event.h> 36 #include <fmd_case.h> 37 #include <fmd_buf.h> 38 #include <fmd_asru.h> 39 #include <fmd_ckpt.h> 40 #include <fmd_timerq.h> 41 42 #include <fmd.h> 43 44 typedef struct trwalk_state { 45 struct trwalk_state *trw_next; 46 fmd_tracebuf_t trw_data; 47 pthread_t trw_tid; 48 uintptr_t trw_base; 49 const fmd_tracerec_t *trw_stop; 50 fmd_tracerec_t *trw_xrec; 51 } trwalk_state_t; 52 53 typedef struct hashwalk_data { 54 uintptr_t *hw_hash; 55 uint_t hw_hashlen; 56 uint_t hw_hashidx; 57 const char *hw_name; 58 void *hw_data; 59 size_t hw_size; 60 size_t hw_next; 61 } hashwalk_data_t; 62 63 static int 64 trwalk_init(mdb_walk_state_t *wsp) 65 { 66 uintptr_t addr; 67 fmd_thread_t thr; 68 fmd_t F; 69 70 if (wsp->walk_addr != NULL) { 71 mdb_warn("fmd_trace only supports global walks\n"); 72 return (WALK_ERR); 73 } 74 75 if (mdb_readvar(&F, "fmd") != sizeof (F)) { 76 mdb_warn("failed to read fmd meta-data"); 77 return (WALK_ERR); 78 } 79 80 for (addr = (uintptr_t)F.d_thr_list.l_next; addr != NULL; 81 addr = (uintptr_t)thr.thr_list.l_next) { 82 83 size_t len, ptr_off, end_off; 84 fmd_tracerec_t *buf; 85 trwalk_state_t *t; 86 87 if (mdb_vread(&thr, sizeof (thr), addr) != sizeof (thr)) { 88 mdb_warn("failed to read thread at %p " 89 "(some trace data will be unavailable)", addr); 90 break; 91 } 92 93 t = mdb_zalloc(sizeof (trwalk_state_t), UM_SLEEP); 94 t->trw_next = wsp->walk_data; 95 wsp->walk_data = t; 96 97 (void) mdb_vread(&t->trw_data, 98 sizeof (t->trw_data), (uintptr_t)thr.thr_trdata); 99 100 if (t->trw_data.tb_recs == 0) 101 continue; /* no trace buffer allocated for thread */ 102 103 len = t->trw_data.tb_recs * t->trw_data.tb_size; 104 buf = mdb_alloc(len, UM_SLEEP); 105 106 t->trw_tid = thr.thr_tid; 107 t->trw_base = (uintptr_t)t->trw_data.tb_buf; 108 109 if (mdb_vread(buf, len, t->trw_base) == -1) { 110 mdb_warn("failed to read buffer for t%u", t->trw_tid); 111 bzero(buf, len); 112 } 113 114 end_off = (uintptr_t)t->trw_data.tb_end - t->trw_base; 115 ptr_off = (uintptr_t)t->trw_data.tb_ptr - t->trw_base; 116 117 t->trw_data.tb_buf = buf; 118 t->trw_data.tb_end = (void *)((uintptr_t)buf + end_off); 119 t->trw_data.tb_ptr = (void *)((uintptr_t)buf + ptr_off); 120 121 if (t->trw_data.tb_ptr < t->trw_data.tb_buf || 122 t->trw_data.tb_ptr > t->trw_data.tb_end) { 123 mdb_warn("trace record ptr for t%u is corrupt " 124 "(some data may be unavailable)\n", t->trw_tid); 125 t->trw_data.tb_ptr = t->trw_data.tb_buf; 126 } 127 128 t->trw_stop = t->trw_data.tb_ptr; 129 t->trw_xrec = mdb_alloc( 130 t->trw_data.tb_size + sizeof (uintptr_t), UM_SLEEP); 131 } 132 133 return (WALK_NEXT); 134 } 135 136 static fmd_tracerec_t * 137 trwalk_nextrec(trwalk_state_t *t) 138 { 139 if (t->trw_stop == NULL) 140 return (t->trw_data.tb_ptr); 141 142 if (t->trw_data.tb_ptr == t->trw_data.tb_buf) 143 t->trw_data.tb_ptr = t->trw_data.tb_end; 144 else 145 t->trw_data.tb_ptr = (fmd_tracerec_t *) 146 ((uintptr_t)t->trw_data.tb_ptr - t->trw_data.tb_size); 147 148 if (t->trw_data.tb_ptr == t->trw_stop) 149 t->trw_stop = NULL; /* mark buffer as empty */ 150 151 return (t->trw_data.tb_ptr); 152 } 153 154 static int 155 trwalk_step(mdb_walk_state_t *wsp) 156 { 157 trwalk_state_t *t, *oldest_t; 158 hrtime_t oldest_time = 0; 159 fmd_tracerec_t *trp; 160 int status; 161 162 for (t = wsp->walk_data; t != NULL; t = t->trw_next) { 163 for (trp = t->trw_data.tb_ptr; t->trw_stop != NULL && 164 trp->tr_time == 0; trp = trwalk_nextrec(t)) 165 continue; 166 167 if (t->trw_stop == NULL) 168 continue; /* buffer has been emptied */ 169 170 if (trp->tr_time > oldest_time) { 171 oldest_time = trp->tr_time; 172 oldest_t = t; 173 } 174 } 175 176 if (oldest_time == 0) 177 return (WALK_DONE); 178 179 t = oldest_t; 180 trp = t->trw_data.tb_ptr; 181 182 bcopy(trp, t->trw_xrec, t->trw_data.tb_size); 183 t->trw_xrec->tr_depth = MIN(trp->tr_depth, t->trw_data.tb_frames); 184 t->trw_xrec->tr_stack[t->trw_xrec->tr_depth] = t->trw_tid; 185 186 status = wsp->walk_callback((uintptr_t)trp - (uintptr_t) 187 t->trw_data.tb_buf + t->trw_base, t->trw_xrec, wsp->walk_cbdata); 188 189 (void) trwalk_nextrec(t); 190 return (status); 191 } 192 193 static void 194 trwalk_fini(mdb_walk_state_t *wsp) 195 { 196 trwalk_state_t *t, *u; 197 198 for (t = wsp->walk_data; t != NULL; t = u) { 199 u = t->trw_next; 200 mdb_free(t->trw_data.tb_buf, 201 t->trw_data.tb_recs * t->trw_data.tb_size); 202 mdb_free(t->trw_xrec, t->trw_data.tb_size + sizeof (uintptr_t)); 203 mdb_free(t, sizeof (trwalk_state_t)); 204 } 205 } 206 207 /*ARGSUSED*/ 208 static int 209 trprint_msg(uintptr_t addr, const fmd_tracerec_t *trp, uintptr_t tid) 210 { 211 if (tid == 0) 212 mdb_printf("%3lu ", trp->tr_stack[trp->tr_depth]); 213 else if (trp->tr_stack[trp->tr_depth] != tid) 214 return (WALK_NEXT); 215 216 mdb_printf("%016llx %04x %-5u %s\n", 217 trp->tr_time, trp->tr_tag, trp->tr_errno, trp->tr_msg); 218 219 return (WALK_NEXT); 220 } 221 222 /*ARGSUSED*/ 223 static int 224 trprint_cpp(uintptr_t addr, const fmd_tracerec_t *trp, uintptr_t tid) 225 { 226 char file[64]; 227 228 if (tid == 0) 229 mdb_printf("%3lu ", trp->tr_stack[trp->tr_depth]); 230 else if (trp->tr_stack[trp->tr_depth] != tid) 231 return (WALK_NEXT); 232 233 if (mdb_readstr(file, sizeof (file), (uintptr_t)trp->tr_file) <= 0) 234 (void) strcpy(file, "???"); 235 236 mdb_printf("%016llx %04x %s: %u\n", 237 trp->tr_time, trp->tr_tag, file, trp->tr_line); 238 239 return (WALK_NEXT); 240 } 241 242 static void 243 trprint_stack(const fmd_tracerec_t *trp) 244 { 245 uint8_t i; 246 247 for (i = 0; i < trp->tr_depth; i++) 248 mdb_printf("\t%a\n", trp->tr_stack[i]); 249 250 if (trp->tr_depth != 0) 251 mdb_printf("\n"); 252 } 253 254 static int 255 trprint_msg_stack(uintptr_t addr, const fmd_tracerec_t *trp, uintptr_t tid) 256 { 257 int status = trprint_msg(addr, trp, tid); 258 trprint_stack(trp); 259 return (status); 260 } 261 262 static int 263 trprint_cpp_stack(uintptr_t addr, const fmd_tracerec_t *trp, uintptr_t tid) 264 { 265 int status = trprint_cpp(addr, trp, tid); 266 trprint_stack(trp); 267 return (status); 268 } 269 270 static int 271 fmd_trace(uintptr_t tid, uint_t flags, int argc, const mdb_arg_t *argv) 272 { 273 int (*func)(uintptr_t, const fmd_tracerec_t *, uintptr_t); 274 uint_t opt_c = FALSE, opt_s = FALSE; 275 276 if (mdb_getopts(argc, argv, 277 'c', MDB_OPT_SETBITS, TRUE, &opt_c, 278 's', MDB_OPT_SETBITS, TRUE, &opt_s, NULL) != argc) 279 return (DCMD_USAGE); 280 281 if (!(flags & DCMD_ADDRSPEC)) { 282 mdb_printf("TID "); 283 tid = 0; 284 } 285 286 if (opt_c) { 287 mdb_printf("%-16s %-4s FILE:LINE\n", "TIME", "TAG"); 288 func = opt_s ? trprint_cpp_stack : trprint_cpp; 289 } else { 290 mdb_printf("%-16s %-4s %-5s MSG\n", "TIME", "TAG", "ERRNO"); 291 func = opt_s ? trprint_msg_stack : trprint_msg; 292 } 293 294 if (mdb_walk("fmd_trace", (mdb_walk_cb_t)func, (void *)tid) == -1) { 295 mdb_warn("failed to walk fmd_trace"); 296 return (DCMD_ERR); 297 } 298 299 return (DCMD_OK); 300 } 301 302 static int 303 hash_walk_init(mdb_walk_state_t *wsp, uintptr_t addr, uint_t hashlen, 304 const char *name, size_t size, size_t next) 305 { 306 hashwalk_data_t *hwp = mdb_alloc(sizeof (hashwalk_data_t), UM_SLEEP); 307 size_t len = sizeof (uintptr_t) * hashlen; 308 309 hwp->hw_hash = mdb_zalloc(len, UM_SLEEP); 310 (void) mdb_vread(hwp->hw_hash, len, addr); 311 hwp->hw_hashlen = hashlen; 312 hwp->hw_hashidx = 0; 313 hwp->hw_name = name; 314 hwp->hw_data = mdb_zalloc(size, UM_SLEEP); 315 hwp->hw_size = size; 316 hwp->hw_next = next; 317 318 wsp->walk_addr = hwp->hw_hash[0]; 319 wsp->walk_data = hwp; 320 321 return (WALK_NEXT); 322 } 323 324 static int 325 hash_walk_step(mdb_walk_state_t *wsp) 326 { 327 hashwalk_data_t *hwp = wsp->walk_data; 328 int rv; 329 330 while (wsp->walk_addr == NULL) { 331 if (++hwp->hw_hashidx < hwp->hw_hashlen) 332 wsp->walk_addr = hwp->hw_hash[hwp->hw_hashidx]; 333 else 334 return (WALK_DONE); 335 } 336 337 if (mdb_vread(hwp->hw_data, hwp->hw_size, wsp->walk_addr) == -1) { 338 mdb_warn("failed to read %s at %p", 339 hwp->hw_name, wsp->walk_addr); 340 return (WALK_ERR); 341 } 342 343 rv = wsp->walk_callback(wsp->walk_addr, hwp->hw_data, wsp->walk_cbdata); 344 wsp->walk_addr = *(uintptr_t *)((uintptr_t)hwp->hw_data + hwp->hw_next); 345 return (rv); 346 } 347 348 static void 349 hash_walk_fini(mdb_walk_state_t *wsp) 350 { 351 hashwalk_data_t *hwp = wsp->walk_data; 352 353 mdb_free(hwp->hw_hash, sizeof (uintptr_t) * hwp->hw_hashlen); 354 mdb_free(hwp->hw_data, hwp->hw_size); 355 mdb_free(hwp, sizeof (hashwalk_data_t)); 356 } 357 358 static int 359 ustat_walk_init(mdb_walk_state_t *wsp) 360 { 361 fmd_ustat_t us; 362 363 if (mdb_vread(&us, sizeof (us), wsp->walk_addr) != sizeof (us)) { 364 mdb_warn("failed to read fmd_ustat_t at %p", wsp->walk_addr); 365 return (WALK_ERR); 366 } 367 368 return (hash_walk_init(wsp, 369 (uintptr_t)us.us_hash, us.us_hashlen, NULL, 0, 0)); 370 } 371 372 static int 373 ustat_walk_step(mdb_walk_state_t *wsp) 374 { 375 hashwalk_data_t *hwp = wsp->walk_data; 376 fmd_ustat_elem_t ue; 377 fmd_stat_t s; 378 379 while (wsp->walk_addr == NULL) { 380 if (++hwp->hw_hashidx < hwp->hw_hashlen) 381 wsp->walk_addr = hwp->hw_hash[hwp->hw_hashidx]; 382 else 383 return (WALK_DONE); 384 } 385 386 if (mdb_vread(&ue, sizeof (ue), wsp->walk_addr) != sizeof (ue) || 387 mdb_vread(&s, sizeof (s), (uintptr_t)ue.use_stat) != sizeof (s)) { 388 mdb_warn("failed to read stat element at %p", wsp->walk_addr); 389 return (WALK_ERR); 390 } 391 392 wsp->walk_addr = (uintptr_t)ue.use_next; 393 394 return (wsp->walk_callback( 395 (uintptr_t)ue.use_stat, &s, wsp->walk_cbdata)); 396 } 397 398 static int 399 fmd_ustat(uintptr_t addr, uint_t flags, int argc, const mdb_arg_t *argv) 400 { 401 if (!(flags & DCMD_ADDRSPEC)) 402 return (DCMD_USAGE); 403 404 if (mdb_pwalk_dcmd("fmd_ustat", "fmd_stat", argc, argv, addr) != 0) { 405 mdb_warn("failed to walk fmd_ustat at %p", addr); 406 return (DCMD_ERR); 407 } 408 409 return (DCMD_OK); 410 } 411 412 /*ARGSUSED*/ 413 static int 414 fmd_stat(uintptr_t addr, uint_t flags, int argc, const mdb_arg_t *argv) 415 { 416 char buf[512]; 417 fmd_stat_t s; 418 419 if (!(flags & DCMD_ADDRSPEC) || argc != 0) 420 return (DCMD_USAGE); 421 422 if (DCMD_HDRSPEC(flags)) 423 mdb_printf("%<u>%-11s %-4s %-32s %s%</u>\n", 424 "ADDR", "TYPE", "NAME", "VALUE"); 425 426 if (mdb_vread(&s, sizeof (s), addr) != sizeof (s)) { 427 mdb_warn("failed to read statistic at %p", addr); 428 return (DCMD_ERR); 429 } 430 431 switch (s.fmds_type) { 432 case FMD_TYPE_BOOL: 433 mdb_printf("%-11p %-4s %-32s %s\n", addr, "bool", 434 s.fmds_name, s.fmds_value.bool ? "true" : "false"); 435 break; 436 case FMD_TYPE_INT32: 437 mdb_printf("%-11p %-4s %-32s %d\n", addr, "i32", 438 s.fmds_name, s.fmds_value.i32); 439 break; 440 case FMD_TYPE_UINT32: 441 mdb_printf("%-11p %-4s %-32s %u\n", addr, "ui32", 442 s.fmds_name, s.fmds_value.i32); 443 break; 444 case FMD_TYPE_INT64: 445 mdb_printf("%-11p %-4s %-32s %lld\n", addr, "i64", 446 s.fmds_name, s.fmds_value.i64); 447 break; 448 case FMD_TYPE_UINT64: 449 mdb_printf("%-11p %-4s %-32s %llu\n", addr, "ui64", 450 s.fmds_name, s.fmds_value.ui64); 451 break; 452 case FMD_TYPE_STRING: 453 if (mdb_readstr(buf, sizeof (buf), 454 (uintptr_t)s.fmds_value.str) < 0) { 455 (void) mdb_snprintf(buf, sizeof (buf), "<%p>", 456 s.fmds_value.str); 457 } 458 mdb_printf("%-11p %-4s %-32s %s\n", addr, "str", 459 s.fmds_name, buf); 460 break; 461 case FMD_TYPE_TIME: 462 mdb_printf("%-11p %-4s %-32s %llu\n", addr, "time", 463 s.fmds_name, s.fmds_value.ui64); 464 break; 465 case FMD_TYPE_SIZE: 466 mdb_printf("%-11p %-4s %-32s %llu\n", addr, "size", 467 s.fmds_name, s.fmds_value.ui64); 468 break; 469 default: 470 mdb_printf("%-11p %-4u %-32s ???\n", addr, 471 s.fmds_type, s.fmds_name); 472 break; 473 } 474 475 return (DCMD_OK); 476 } 477 478 /*ARGSUSED*/ 479 static int 480 fmd_event(uintptr_t addr, uint_t flags, int argc, const mdb_arg_t *argv) 481 { 482 char type[16], name[16]; 483 fmd_event_impl_t ev; 484 485 if (argc != 0) 486 return (DCMD_USAGE); 487 488 if (mdb_vread(&ev, sizeof (ev), addr) != sizeof (ev)) { 489 mdb_warn("failed to read fmd_event at %p", addr); 490 return (DCMD_ERR); 491 } 492 493 if (DCMD_HDRSPEC(flags)) { 494 mdb_printf("%<u>%-11s %-4s %-5s %-3s %-?s%</u>\n", 495 "ADDR", "TYPE", "STATE", "REF", "NVPAIR"); 496 } 497 498 switch (ev.ev_type) { 499 case FMD_EVT_PROTOCOL: 500 (void) strcpy(type, "PROT"); 501 break; 502 case FMD_EVT_GC: 503 (void) strcpy(type, "GC"); 504 break; 505 case FMD_EVT_CLOSE: 506 (void) strcpy(type, "CLSE"); 507 break; 508 case FMD_EVT_TIMEOUT: 509 (void) strcpy(type, "TIME"); 510 break; 511 case FMD_EVT_STATS: 512 (void) strcpy(type, "STAT"); 513 break; 514 default: 515 (void) mdb_snprintf(type, sizeof (type), "%u", ev.ev_type); 516 } 517 518 switch (ev.ev_state) { 519 case FMD_EVS_RECEIVED: 520 (void) strcpy(name, "RECVD"); 521 break; 522 case FMD_EVS_ACCEPTED: 523 (void) strcpy(name, "ACCPT"); 524 break; 525 case FMD_EVS_DISCARDED: 526 (void) strcpy(name, "DSCRD"); 527 break; 528 case FMD_EVS_DIAGNOSED: 529 (void) strcpy(name, "DIAGN"); 530 break; 531 default: 532 (void) mdb_snprintf(name, sizeof (name), "%u", ev.ev_state); 533 } 534 535 mdb_printf("%-11p %-4s %-5s %-3u %p\n", 536 addr, type, name, ev.ev_refs, ev.ev_nvl); 537 538 return (DCMD_OK); 539 } 540 541 static int 542 thread_walk_init(mdb_walk_state_t *wsp) 543 { 544 fmd_t F; 545 546 if (mdb_readvar(&F, "fmd") != sizeof (F)) { 547 mdb_warn("failed to read fmd meta-data"); 548 return (WALK_ERR); 549 } 550 551 wsp->walk_addr = (uintptr_t)F.d_thr_list.l_next; 552 return (WALK_NEXT); 553 } 554 555 static int 556 thread_walk_step(mdb_walk_state_t *wsp) 557 { 558 uintptr_t addr = wsp->walk_addr; 559 fmd_thread_t t; 560 561 if (addr == NULL) 562 return (WALK_DONE); 563 564 if (mdb_vread(&t, sizeof (t), addr) != sizeof (t)) { 565 mdb_warn("failed to read fmd_thread at %p", addr); 566 return (WALK_ERR); 567 } 568 569 wsp->walk_addr = (uintptr_t)t.thr_list.l_next; 570 return (wsp->walk_callback(addr, &t, wsp->walk_cbdata)); 571 } 572 573 static int 574 fmd_thread(uintptr_t addr, uint_t flags, int argc, const mdb_arg_t *argv) 575 { 576 fmd_thread_t thr; 577 578 if (!(flags & DCMD_ADDRSPEC)) 579 return (mdb_walk_dcmd("fmd_thread", "fmd_thread", argc, argv)); 580 581 if (argc != 0) 582 return (DCMD_USAGE); 583 584 if (mdb_vread(&thr, sizeof (thr), addr) != sizeof (thr)) { 585 mdb_warn("failed to read fmd_thread at %p", addr); 586 return (DCMD_ERR); 587 } 588 589 if (DCMD_HDRSPEC(flags)) { 590 mdb_printf("%<u>%-11s %-11s %-8s %-16s%</u>\n", 591 "ADDR", "MOD", "TID", "FUNC"); 592 } 593 594 mdb_printf("%-11p %-11p %-8u %a\n", 595 addr, thr.thr_mod, thr.thr_tid, thr.thr_func); 596 597 return (DCMD_OK); 598 } 599 600 static int 601 mod_walk_init(mdb_walk_state_t *wsp) 602 { 603 fmd_t F; 604 605 if (mdb_readvar(&F, "fmd") != sizeof (F)) { 606 mdb_warn("failed to read fmd meta-data"); 607 return (WALK_ERR); 608 } 609 610 wsp->walk_addr = (uintptr_t)F.d_mod_list.l_next; 611 return (WALK_NEXT); 612 } 613 614 static int 615 mod_walk_step(mdb_walk_state_t *wsp) 616 { 617 uintptr_t addr = wsp->walk_addr; 618 fmd_module_t m; 619 620 if (addr == NULL) 621 return (WALK_DONE); 622 623 if (mdb_vread(&m, sizeof (m), addr) != sizeof (m)) { 624 mdb_warn("failed to read fmd_module at %p", addr); 625 return (WALK_ERR); 626 } 627 628 wsp->walk_addr = (uintptr_t)m.mod_list.l_next; 629 return (wsp->walk_callback(addr, &m, wsp->walk_cbdata)); 630 } 631 632 static int 633 fmd_module(uintptr_t addr, uint_t flags, int argc, const mdb_arg_t *argv) 634 { 635 fmd_module_t mod; 636 char name[256]; 637 638 if (!(flags & DCMD_ADDRSPEC)) 639 return (mdb_walk_dcmd("fmd_module", "fmd_module", argc, argv)); 640 641 if (argc != 0) 642 return (DCMD_USAGE); 643 644 if (mdb_vread(&mod, sizeof (mod), addr) != sizeof (mod)) { 645 mdb_warn("failed to read fmd_module at %p", addr); 646 return (DCMD_ERR); 647 } 648 649 if (DCMD_HDRSPEC(flags)) { 650 mdb_printf("%<u>%-11s %-16s %-11s %-4s %-?s %-16s%</u>\n", 651 "ADDR", "OPS", "DATA", "FLAG", "USTAT", "NAME"); 652 } 653 654 if (mdb_readstr(name, sizeof (name), (uintptr_t)mod.mod_name) <= 0) 655 (void) mdb_snprintf(name, sizeof (name), "<%p>", mod.mod_name); 656 657 mdb_printf("%-11p %-16a %-11p 0x%02x %-?p %s\n", addr, 658 mod.mod_ops, mod.mod_data, mod.mod_flags, mod.mod_ustat, name); 659 660 return (DCMD_OK); 661 } 662 663 static int 664 case_walk_init(mdb_walk_state_t *wsp) 665 { 666 fmd_module_t mod; 667 fmd_case_hash_t ch; 668 fmd_t F; 669 670 if (wsp->walk_addr != NULL) { 671 if (mdb_vread(&mod, sizeof (mod), wsp->walk_addr) == -1) { 672 mdb_warn("failed to read module at %p", wsp->walk_addr); 673 return (WALK_ERR); 674 } 675 676 wsp->walk_addr = (uintptr_t)mod.mod_cases.l_next; 677 return (WALK_NEXT); 678 } 679 680 if (mdb_readvar(&F, "fmd") != sizeof (F) || 681 mdb_vread(&ch, sizeof (ch), (uintptr_t)F.d_cases) != sizeof (ch)) { 682 mdb_warn("failed to read fmd meta-data"); 683 return (WALK_ERR); 684 } 685 686 return (hash_walk_init(wsp, (uintptr_t)ch.ch_hash, ch.ch_hashlen, 687 "fmd_case", sizeof (fmd_case_impl_t), 688 OFFSETOF(fmd_case_impl_t, ci_next))); 689 } 690 691 static int 692 case_walk_step(mdb_walk_state_t *wsp) 693 { 694 uintptr_t addr = wsp->walk_addr; 695 fmd_case_impl_t ci; 696 697 if (wsp->walk_data != NULL) 698 return (hash_walk_step(wsp)); 699 700 if (addr == NULL) 701 return (WALK_DONE); 702 703 if (mdb_vread(&ci, sizeof (ci), addr) != sizeof (ci)) { 704 mdb_warn("failed to read fmd_case at %p", addr); 705 return (WALK_ERR); 706 } 707 708 wsp->walk_addr = (uintptr_t)ci.ci_list.l_next; 709 return (wsp->walk_callback(addr, &ci, wsp->walk_cbdata)); 710 } 711 712 static void 713 case_walk_fini(mdb_walk_state_t *wsp) 714 { 715 if (wsp->walk_data != NULL) 716 hash_walk_fini(wsp); 717 } 718 719 static int 720 fmd_case(uintptr_t addr, uint_t flags, int argc, const mdb_arg_t *argv) 721 { 722 char uuid[48], name[16]; 723 fmd_case_impl_t ci; 724 725 if (!(flags & DCMD_ADDRSPEC)) { 726 if (mdb_walk_dcmd("fmd_case", "fmd_case", argc, argv) != 0) { 727 mdb_warn("failed to walk fmd_case hash"); 728 return (DCMD_ERR); 729 } 730 return (DCMD_OK); 731 } 732 733 if (mdb_vread(&ci, sizeof (ci), addr) != sizeof (ci)) { 734 mdb_warn("failed to read fmd_case at %p", addr); 735 return (DCMD_ERR); 736 } 737 738 if (DCMD_HDRSPEC(flags)) { 739 mdb_printf("%<u>%-11s %-5s %-3s %-?s %-36s%</u>\n", 740 "ADDR", "STATE", "REF", "DATA", "UUID"); 741 } 742 743 if (mdb_readstr(uuid, sizeof (uuid), (uintptr_t)ci.ci_uuid) <= 0) 744 (void) mdb_snprintf(uuid, sizeof (uuid), "<%p>", ci.ci_uuid); 745 746 switch (ci.ci_state) { 747 case FMD_CASE_UNSOLVED: 748 (void) strcpy(name, "UNSLV"); 749 break; 750 case FMD_CASE_SOLVED: 751 (void) strcpy(name, "SOLVE"); 752 break; 753 case FMD_CASE_CLOSED: 754 (void) strcpy(name, "CLOSE"); 755 break; 756 default: 757 (void) mdb_snprintf(name, sizeof (name), "%u", ci.ci_state); 758 } 759 760 mdb_printf("%-11p %-5s %-3u %-?p %s\n", 761 addr, name, ci.ci_refs, ci.ci_data, uuid); 762 763 return (DCMD_OK); 764 } 765 766 static int 767 buf_walk_init(mdb_walk_state_t *wsp) 768 { 769 fmd_buf_hash_t bh; 770 771 if (mdb_vread(&bh, sizeof (bh), wsp->walk_addr) != sizeof (bh)) { 772 mdb_warn("failed to read fmd_buf_hash_t at %p", wsp->walk_addr); 773 return (WALK_ERR); 774 } 775 776 return (hash_walk_init(wsp, (uintptr_t)bh.bh_hash, bh.bh_hashlen, 777 "fmd_buf", sizeof (fmd_buf_t), OFFSETOF(fmd_buf_t, buf_next))); 778 } 779 780 /*ARGSUSED*/ 781 static int 782 fmd_buf(uintptr_t addr, uint_t flags, int argc, const mdb_arg_t *argv) 783 { 784 char name[256]; 785 fmd_buf_t b; 786 787 if (argc != 0 || !(flags & DCMD_ADDRSPEC)) 788 return (DCMD_USAGE); 789 790 if (mdb_vread(&b, sizeof (b), addr) != sizeof (b)) { 791 mdb_warn("failed to read fmd_buf at %p", addr); 792 return (DCMD_ERR); 793 } 794 795 if (DCMD_HDRSPEC(flags)) { 796 mdb_printf("%<u>%-11s %-32s %-5s %-?s %s%</u>\n", 797 "ADDR", "NAME", "FLAGS", "DATA", "SIZE"); 798 } 799 800 if (mdb_readstr(name, sizeof (name), (uintptr_t)b.buf_name) <= 0) 801 (void) mdb_snprintf(name, sizeof (name), "<%p>", b.buf_name); 802 803 mdb_printf("%-11p %-32s %-#5x %-?p %lu\n", 804 addr, name, b.buf_flags, b.buf_data, b.buf_size); 805 806 return (DCMD_OK); 807 } 808 809 static int 810 serd_walk_init(mdb_walk_state_t *wsp) 811 { 812 fmd_serd_hash_t sh; 813 814 if (mdb_vread(&sh, sizeof (sh), wsp->walk_addr) != sizeof (sh)) { 815 mdb_warn("failed to read fmd_serd_hash at %p", wsp->walk_addr); 816 return (WALK_ERR); 817 } 818 819 return (hash_walk_init(wsp, (uintptr_t)sh.sh_hash, sh.sh_hashlen, 820 "fmd_serd_eng", sizeof (fmd_serd_eng_t), 821 OFFSETOF(fmd_serd_eng_t, sg_next))); 822 } 823 824 /*ARGSUSED*/ 825 static int 826 fmd_serd(uintptr_t addr, uint_t flags, int argc, const mdb_arg_t *argv) 827 { 828 char name[256]; 829 fmd_serd_eng_t sg; 830 831 if (argc != 0 || !(flags & DCMD_ADDRSPEC)) 832 return (DCMD_USAGE); 833 834 if (mdb_vread(&sg, sizeof (sg), addr) != sizeof (sg)) { 835 mdb_warn("failed to read fmd_serd_eng at %p", addr); 836 return (DCMD_ERR); 837 } 838 839 if (DCMD_HDRSPEC(flags)) { 840 mdb_printf("%<u>%-11s %-32s %-3s F >%-2s %-16s%</u>\n", 841 "ADDR", "NAME", "CNT", "N", "T"); 842 } 843 844 if (mdb_readstr(name, sizeof (name), (uintptr_t)sg.sg_name) <= 0) 845 (void) mdb_snprintf(name, sizeof (name), "<%p>", sg.sg_name); 846 847 mdb_printf("%-11p %-32s %-3u %c >%-2u %lluns\n", 848 addr, name, sg.sg_count, (sg.sg_flags & FMD_SERD_FIRED) ? 'F' : ' ', 849 sg.sg_n, (u_longlong_t)sg.sg_t); 850 851 return (DCMD_OK); 852 } 853 854 static int 855 asru_walk_init(mdb_walk_state_t *wsp) 856 { 857 fmd_asru_hash_t ah; 858 fmd_t F; 859 860 if (wsp->walk_addr == NULL && mdb_readvar(&F, "fmd") != sizeof (F)) { 861 mdb_warn("failed to read fmd meta-data"); 862 return (WALK_ERR); 863 } 864 865 if (wsp->walk_addr == NULL) 866 wsp->walk_addr = (uintptr_t)F.d_asrus; 867 868 if (mdb_vread(&ah, sizeof (ah), wsp->walk_addr) != sizeof (ah)) { 869 mdb_warn("failed to read asru_hash at %p", wsp->walk_addr); 870 return (WALK_ERR); 871 } 872 873 return (hash_walk_init(wsp, (uintptr_t)ah.ah_hash, ah.ah_hashlen, 874 "fmd_asru", sizeof (fmd_asru_t), OFFSETOF(fmd_asru_t, asru_next))); 875 } 876 877 static int 878 fmd_asru(uintptr_t addr, uint_t flags, int argc, const mdb_arg_t *argv) 879 { 880 char uuid[48], name[256]; 881 fmd_asru_t a; 882 883 if (!(flags & DCMD_ADDRSPEC)) { 884 if (mdb_walk_dcmd("fmd_asru", "fmd_asru", argc, argv) != 0) { 885 mdb_warn("failed to walk fmd_asru hash"); 886 return (DCMD_ERR); 887 } 888 return (DCMD_OK); 889 } 890 891 if (mdb_vread(&a, sizeof (a), addr) != sizeof (a)) { 892 mdb_warn("failed to read fmd_asru at %p", addr); 893 return (DCMD_ERR); 894 } 895 896 if (DCMD_HDRSPEC(flags)) 897 mdb_printf("%<u>%-8s %-36s %s%</u>\n", "ADDR", "UUID", "NAME"); 898 899 if (mdb_readstr(uuid, sizeof (uuid), (uintptr_t)a.asru_uuid) <= 0) 900 (void) mdb_snprintf(uuid, sizeof (uuid), "<%p>", a.asru_uuid); 901 if (mdb_readstr(name, sizeof (name), (uintptr_t)a.asru_name) <= 0) 902 (void) mdb_snprintf(name, sizeof (name), "<%p>", a.asru_name); 903 904 mdb_printf("%-8p %-36s %s\n", addr, uuid, name); 905 return (DCMD_OK); 906 } 907 908 /*ARGSUSED*/ 909 static int 910 fcf_hdr(uintptr_t addr, uint_t flags, int argc, const mdb_arg_t *argv) 911 { 912 fcf_hdr_t h; 913 914 if (argc != 0) 915 return (DCMD_USAGE); 916 917 if (!(flags & DCMD_ADDRSPEC)) 918 addr = 0; /* assume base of file in file target */ 919 920 if (mdb_vread(&h, sizeof (h), addr) != sizeof (h)) { 921 mdb_warn("failed to read header at %p", addr); 922 return (DCMD_ERR); 923 } 924 925 mdb_printf("fcfh_ident.id_magic = 0x%x, %c, %c, %c\n", 926 h.fcfh_ident[FCF_ID_MAG0], h.fcfh_ident[FCF_ID_MAG1], 927 h.fcfh_ident[FCF_ID_MAG2], h.fcfh_ident[FCF_ID_MAG3]); 928 929 switch (h.fcfh_ident[FCF_ID_MODEL]) { 930 case FCF_MODEL_ILP32: 931 mdb_printf("fcfh_ident.id_model = ILP32\n"); 932 break; 933 case FCF_MODEL_LP64: 934 mdb_printf("fcfh_ident.id_model = LP64\n"); 935 break; 936 default: 937 mdb_printf("fcfh_ident.id_model = 0x%x\n", 938 h.fcfh_ident[FCF_ID_MODEL]); 939 } 940 941 switch (h.fcfh_ident[FCF_ID_ENCODING]) { 942 case FCF_ENCODE_LSB: 943 mdb_printf("fcfh_ident.id_encoding = LSB\n"); 944 break; 945 case FCF_ENCODE_MSB: 946 mdb_printf("fcfh_ident.id_encoding = MSB\n"); 947 break; 948 default: 949 mdb_printf("fcfh_ident.id_encoding = 0x%x\n", 950 h.fcfh_ident[FCF_ID_ENCODING]); 951 } 952 953 mdb_printf("fcfh_ident.id_version = %u\n", 954 h.fcfh_ident[FCF_ID_VERSION]); 955 956 mdb_printf("fcfh_flags = 0x%x\n", h.fcfh_flags); 957 mdb_printf("fcfh_hdrsize = %u\n", h.fcfh_hdrsize); 958 mdb_printf("fcfh_secsize = %u\n", h.fcfh_secsize); 959 mdb_printf("fcfh_secnum = %u\n", h.fcfh_secnum); 960 mdb_printf("fcfh_secoff = %llu\n", h.fcfh_secoff); 961 mdb_printf("fcfh_filesz = %llu\n", h.fcfh_filesz); 962 mdb_printf("fcfh_cgen = %llu\n", h.fcfh_cgen); 963 964 return (DCMD_OK); 965 } 966 967 /*ARGSUSED*/ 968 static int 969 fcf_sec_one(uintptr_t addr, void *ignored, uint_t *secp) 970 { 971 static int fcf_sec(uintptr_t, uint_t, int, const mdb_arg_t *); 972 973 mdb_printf("%3d ", (*secp)++); 974 (void) fcf_sec(addr, DCMD_ADDRSPEC | DCMD_LOOP, 0, NULL); 975 return (WALK_NEXT); 976 } 977 978 /*ARGSUSED*/ 979 static int 980 fcf_sec(uintptr_t addr, uint_t flags, int argc, const mdb_arg_t *argv) 981 { 982 static const char *const types[] = { 983 "none", /* FCF_SECT_NONE */ 984 "strtab", /* FCF_SECT_STRTAB */ 985 "module", /* FCF_SECT_MODULE */ 986 "case", /* FCF_SECT_CASE */ 987 "bufs", /* FCF_SECT_BUFS */ 988 "buffer", /* FCF_SECT_BUFFER */ 989 "serd", /* FCF_SECT_SERD */ 990 "events", /* FCF_SECT_EVENTS */ 991 "nvlists", /* FCF_SECT_NVLISTS */ 992 }; 993 994 uint_t sec = 0; 995 fcf_sec_t s; 996 997 if (!(flags & DCMD_ADDRSPEC)) 998 mdb_printf("%<u>%-3s ", "NDX"); 999 1000 if (!(flags & DCMD_ADDRSPEC) || DCMD_HDRSPEC(flags)) { 1001 mdb_printf("%<u>%?s %-10s %-5s %-5s %-5s %-6s %-5s%</u>\n", 1002 "ADDR", "TYPE", "ALIGN", "FLAGS", "ENTSZ", "OFF", "SIZE"); 1003 } 1004 1005 if (!(flags & DCMD_ADDRSPEC)) { 1006 if (mdb_walk("fcf_sec", (mdb_walk_cb_t)fcf_sec_one, &sec) < 0) { 1007 mdb_warn("failed to walk fcf_sec"); 1008 return (DCMD_ERR); 1009 } 1010 return (DCMD_OK); 1011 } 1012 1013 if (argc != 0) 1014 return (DCMD_USAGE); 1015 1016 if (mdb_vread(&s, sizeof (s), addr) != sizeof (s)) { 1017 mdb_warn("failed to read section header at %p", addr); 1018 return (DCMD_ERR); 1019 } 1020 1021 mdb_printf("%?p ", addr); 1022 1023 if (s.fcfs_type < sizeof (types) / sizeof (types[0])) 1024 mdb_printf("%-10s ", types[s.fcfs_type]); 1025 else 1026 mdb_printf("%-10u ", s.fcfs_type); 1027 1028 mdb_printf("%-5u %-#5x %-#5x %-6llx %-#5llx\n", s.fcfs_align, 1029 s.fcfs_flags, s.fcfs_entsize, s.fcfs_offset, s.fcfs_size); 1030 1031 return (DCMD_OK); 1032 } 1033 1034 static int 1035 fcf_sec_walk_init(mdb_walk_state_t *wsp) 1036 { 1037 fcf_hdr_t h, *hp; 1038 size_t size; 1039 1040 if (mdb_vread(&h, sizeof (h), wsp->walk_addr) != sizeof (h)) { 1041 mdb_warn("failed to read FCF header at %p", wsp->walk_addr); 1042 return (WALK_ERR); 1043 } 1044 1045 size = sizeof (fcf_hdr_t) + sizeof (fcf_sec_t) * h.fcfh_secnum; 1046 hp = mdb_alloc(size, UM_SLEEP); 1047 1048 if (mdb_vread(hp, size, wsp->walk_addr) != size) { 1049 mdb_warn("failed to read FCF sections at %p", wsp->walk_addr); 1050 mdb_free(hp, size); 1051 return (WALK_ERR); 1052 } 1053 1054 wsp->walk_data = hp; 1055 wsp->walk_arg = 0; 1056 1057 return (WALK_NEXT); 1058 } 1059 1060 static int 1061 fcf_sec_walk_step(mdb_walk_state_t *wsp) 1062 { 1063 uint_t i = (uint_t)wsp->walk_arg; 1064 size_t off = sizeof (fcf_hdr_t) + sizeof (fcf_sec_t) * i; 1065 fcf_hdr_t *hp = wsp->walk_data; 1066 fcf_sec_t *sp = (fcf_sec_t *)((uintptr_t)hp + off); 1067 1068 if (i >= hp->fcfh_secnum) 1069 return (WALK_DONE); 1070 1071 wsp->walk_arg = (void *)(i + 1); 1072 return (wsp->walk_callback(wsp->walk_addr + off, sp, wsp->walk_cbdata)); 1073 } 1074 1075 static void 1076 fcf_sec_walk_fini(mdb_walk_state_t *wsp) 1077 { 1078 fcf_hdr_t *hp = wsp->walk_data; 1079 mdb_free(hp, sizeof (fcf_hdr_t) + sizeof (fcf_sec_t) * hp->fcfh_secnum); 1080 } 1081 1082 /*ARGSUSED*/ 1083 static int 1084 fcf_case(uintptr_t addr, uint_t flags, int argc, const mdb_arg_t *argv) 1085 { 1086 fcf_case_t fcfc; 1087 1088 if (argc != 0) 1089 return (DCMD_USAGE); 1090 1091 if (mdb_vread(&fcfc, sizeof (fcfc), addr) != sizeof (fcfc)) { 1092 mdb_warn("failed to read case at %p", addr); 1093 return (DCMD_ERR); 1094 } 1095 1096 mdb_printf("fcfc_uuid = 0x%x\n", fcfc.fcfc_uuid); 1097 mdb_printf("fcfc_state = %u\n", fcfc.fcfc_state); 1098 mdb_printf("fcfc_bufs = %u\n", fcfc.fcfc_bufs); 1099 mdb_printf("fcfc_events = %u\n", fcfc.fcfc_events); 1100 mdb_printf("fcfc_suspects = %u\n", fcfc.fcfc_suspects); 1101 1102 return (DCMD_OK); 1103 } 1104 1105 /*ARGSUSED*/ 1106 static int 1107 fcf_event(uintptr_t addr, uint_t flags, int argc, const mdb_arg_t *argv) 1108 { 1109 fcf_event_t fcfe; 1110 1111 if (argc != 0) 1112 return (DCMD_USAGE); 1113 1114 if (mdb_vread(&fcfe, sizeof (fcfe), addr) != sizeof (fcfe)) { 1115 mdb_warn("failed to read event at %p", addr); 1116 return (DCMD_ERR); 1117 } 1118 1119 mdb_printf("fcfe_todsec = %llu (%Y)\n", 1120 fcfe.fcfe_todsec, (time_t)fcfe.fcfe_todsec); 1121 mdb_printf("fcfe_todnsec = %llu\n", fcfe.fcfe_todnsec); 1122 mdb_printf("fcfe_major = %u\n", fcfe.fcfe_major); 1123 mdb_printf("fcfe_minor = %u\n", fcfe.fcfe_minor); 1124 mdb_printf("fcfe_inode = %llu\n", fcfe.fcfe_inode); 1125 mdb_printf("fcfe_offset = %llu\n", fcfe.fcfe_offset); 1126 1127 return (DCMD_OK); 1128 } 1129 1130 /*ARGSUSED*/ 1131 static int 1132 fcf_serd(uintptr_t addr, uint_t flags, int argc, const mdb_arg_t *argv) 1133 { 1134 fcf_serd_t fcfd; 1135 1136 if (argc != 0) 1137 return (DCMD_USAGE); 1138 1139 if (mdb_vread(&fcfd, sizeof (fcfd), addr) != sizeof (fcfd)) { 1140 mdb_warn("failed to read serd at %p", addr); 1141 return (DCMD_ERR); 1142 } 1143 1144 mdb_printf("fcfd_name = 0x%x\n", fcfd.fcfd_name); 1145 mdb_printf("fcfd_events = %u\n", fcfd.fcfd_events); 1146 mdb_printf("fcfd_n = >%u\n", fcfd.fcfd_n); 1147 mdb_printf("fcfd_t = %lluns\n", fcfd.fcfd_t); 1148 1149 return (DCMD_OK); 1150 } 1151 1152 static int 1153 tmq_walk_init(mdb_walk_state_t *wsp) 1154 { 1155 fmd_timerq_t tmq; 1156 fmd_t F; 1157 1158 if (wsp->walk_addr == NULL && mdb_readvar(&F, "fmd") != sizeof (F)) { 1159 mdb_warn("failed to read fmd meta-data"); 1160 return (WALK_ERR); 1161 } 1162 1163 if (wsp->walk_addr == NULL) 1164 wsp->walk_addr = (uintptr_t)F.d_timers; 1165 1166 if (mdb_vread(&tmq, sizeof (tmq), wsp->walk_addr) != sizeof (tmq)) { 1167 mdb_warn("failed to read timerq at %p", wsp->walk_addr); 1168 return (WALK_ERR); 1169 } 1170 1171 wsp->walk_addr = (uintptr_t)tmq.tmq_list.l_next; 1172 return (WALK_NEXT); 1173 } 1174 1175 static int 1176 tmq_walk_step(mdb_walk_state_t *wsp) 1177 { 1178 uintptr_t addr = wsp->walk_addr; 1179 fmd_timer_t tmr; 1180 1181 if (addr == NULL) 1182 return (WALK_DONE); 1183 1184 if (mdb_vread(&tmr, sizeof (tmr), addr) != sizeof (tmr)) { 1185 mdb_warn("failed to read fmd_timer at %p", addr); 1186 return (WALK_ERR); 1187 } 1188 1189 wsp->walk_addr = (uintptr_t)tmr.tmr_list.l_next; 1190 return (wsp->walk_callback(addr, &tmr, wsp->walk_cbdata)); 1191 } 1192 1193 static int 1194 fmd_timer(uintptr_t addr, uint_t flags, int argc, const mdb_arg_t *argv) 1195 { 1196 char name[32], func[MDB_SYM_NAMLEN]; 1197 fmd_timer_t t; 1198 1199 if (!(flags & DCMD_ADDRSPEC)) { 1200 if (mdb_walk_dcmd("fmd_timerq", "fmd_timer", argc, argv) != 0) { 1201 mdb_warn("failed to walk fmd_timerq"); 1202 return (DCMD_ERR); 1203 } 1204 return (DCMD_OK); 1205 } 1206 1207 if (mdb_vread(&t, sizeof (t), addr) != sizeof (t)) { 1208 mdb_warn("failed to read fmd_timer at %p", addr); 1209 return (DCMD_ERR); 1210 } 1211 1212 if (DCMD_HDRSPEC(flags)) { 1213 mdb_printf("%<u>%-8s %-20s %-4s %-18s %-8s %s%</u>\n", 1214 "ADDR", "MODULE", "ID", "HRTIME", "ARG", "FUNC"); 1215 } 1216 1217 if (mdb_readstr(name, sizeof (name), (uintptr_t) 1218 t.tmr_ids + OFFSETOF(fmd_idspace_t, ids_name)) <= 0) 1219 (void) mdb_snprintf(name, sizeof (name), "<%p>", t.tmr_ids); 1220 1221 if (mdb_lookup_by_addr((uintptr_t)t.tmr_func, MDB_SYM_FUZZY, 1222 func, sizeof (func), NULL) != 0) 1223 (void) mdb_snprintf(func, sizeof (func), "<%p>", t.tmr_func); 1224 1225 mdb_printf("%-8p %-20s %4d 0x%-16llx %-8p %s\n", 1226 addr, name, t.tmr_id, t.tmr_hrt, t.tmr_arg, func); 1227 return (DCMD_OK); 1228 } 1229 1230 static const mdb_dcmd_t dcmds[] = { 1231 { "fcf_case", "?", "print a FCF case", fcf_case }, 1232 { "fcf_event", "?", "print a FCF event", fcf_event }, 1233 { "fcf_hdr", "?", "print a FCF header", fcf_hdr }, 1234 { "fcf_sec", ":", "print a FCF section header", fcf_sec }, 1235 { "fcf_serd", "?", "print a FCF serd engine", fcf_serd }, 1236 { "fmd_trace", "?[-cs]", "display thread trace buffer(s)", fmd_trace }, 1237 { "fmd_ustat", ":", "display statistics collection", fmd_ustat }, 1238 { "fmd_stat", ":", "display statistic structure", fmd_stat }, 1239 { "fmd_event", NULL, "display event structure", fmd_event }, 1240 { "fmd_thread", "?", "display thread or list of threads", fmd_thread }, 1241 { "fmd_module", "?", "display module or list of modules", fmd_module }, 1242 { "fmd_case", ":", "display case file structure", fmd_case }, 1243 { "fmd_buf", ":", "display buffer structure", fmd_buf }, 1244 { "fmd_serd", ":", "display serd engine structure", fmd_serd }, 1245 { "fmd_asru", "?", "display asru resource structure", fmd_asru }, 1246 { "fmd_timer", "?", "display pending timer(s)", fmd_timer }, 1247 { NULL } 1248 }; 1249 1250 static const mdb_walker_t walkers[] = { 1251 { "fcf_sec", "walk FCF section header table given header address", 1252 fcf_sec_walk_init, fcf_sec_walk_step, fcf_sec_walk_fini }, 1253 { "fmd_trace", "walk per-thread trace buffers", 1254 trwalk_init, trwalk_step, trwalk_fini }, 1255 { "fmd_ustat", "walk per-collection statistics", 1256 ustat_walk_init, ustat_walk_step, hash_walk_fini }, 1257 { "fmd_thread", "walk list of all fmd_thread_t's", 1258 thread_walk_init, thread_walk_step, NULL }, 1259 { "fmd_module", "walk list of all fmd_module_t's", 1260 mod_walk_init, mod_walk_step, NULL }, 1261 { "fmd_case", "walk per-module case objects", 1262 case_walk_init, case_walk_step, case_walk_fini }, 1263 { "fmd_buf", "walk per-buf_hash buffers", 1264 buf_walk_init, hash_walk_step, hash_walk_fini }, 1265 { "fmd_serd", "walk per-serd_hash engines", 1266 serd_walk_init, hash_walk_step, hash_walk_fini }, 1267 { "fmd_asru", "walk asru resource hash", 1268 asru_walk_init, hash_walk_step, hash_walk_fini }, 1269 { "fmd_timerq", "walk timer queue", 1270 tmq_walk_init, tmq_walk_step, NULL }, 1271 { NULL, NULL, NULL, NULL, NULL } 1272 }; 1273 1274 static const mdb_modinfo_t modinfo = { MDB_API_VERSION, dcmds, walkers }; 1275 1276 const mdb_modinfo_t * 1277 _mdb_init(void) 1278 { 1279 return (&modinfo); 1280 } 1281