1/*- 2 * Copyright (c) 2003-2005 Marcel Moolenaar 3 * Copyright (c) 2000-2001 Doug Rabson 4 * All rights reserved. 5 * 6 * Redistribution and use in source and binary forms, with or without 7 * modification, are permitted provided that the following conditions 8 * are met: 9 * 10 * 1. Redistributions of source code must retain the above copyright 11 * notice, this list of conditions and the following disclaimer. 12 * 2. Redistributions in binary form must reproduce the above copyright 13 * notice, this list of conditions and the following disclaimer in the 14 * documentation and/or other materials provided with the distribution. 15 * 16 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND 17 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 18 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 19 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 20 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 21 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 22 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 23 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 24 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 25 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 26 * SUCH DAMAGE. 27 */ 28 29#include "opt_xtrace.h" 30 31#include <sys/cdefs.h> 32__FBSDID("$FreeBSD$"); 33 34#include <sys/param.h> 35#include <sys/systm.h> 36#include <sys/cons.h> 37#include <sys/kdb.h> 38#include <sys/ktr.h> 39#include <sys/kernel.h> 40#include <sys/proc.h> 41#include <sys/reboot.h> 42#include <sys/smp.h> 43#include <sys/stack.h> 44 45#include <vm/vm.h> 46 47#include <machine/db_machdep.h> 48#include <machine/frame.h> 49#include <machine/kdb.h> 50#include <machine/md_var.h> 51#include <machine/pcb.h> 52#include <machine/setjmp.h> 53#include <machine/unwind.h> 54#include <machine/vmparam.h> 55 56#include <ddb/ddb.h> 57#include <ddb/db_access.h> 58#include <ddb/db_output.h> 59#include <ddb/db_sym.h> 60#include <ddb/db_variables.h> 61 62#include <ia64/disasm/disasm.h> 63 64#define TMPL_BITS 5 65#define TMPL_MASK ((1 << TMPL_BITS) - 1) 66#define SLOT_BITS 41 67#define SLOT_COUNT 3 68#define SLOT_MASK ((1ULL << SLOT_BITS) - 1ULL) 69#define SLOT_SHIFT(i) (TMPL_BITS+((i)<<3)+(i)) 70 71typedef db_expr_t __db_f(db_expr_t, db_expr_t, db_expr_t, db_expr_t, db_expr_t, 72 db_expr_t, db_expr_t, db_expr_t); 73 74register uint64_t __db_gp __asm__("gp"); 75 76static db_varfcn_t db_frame; 77static db_varfcn_t db_getip; 78static db_varfcn_t db_getrse; 79 80#define DB_OFFSET(x) (db_expr_t *)offsetof(struct trapframe, x) 81struct db_variable db_regs[] = { 82 {"ip", NULL, db_getip}, 83 {"cr.ifs", DB_OFFSET(tf_special.cfm), db_frame}, 84 {"cr.ifa", DB_OFFSET(tf_special.ifa), db_frame}, 85 {"ar.bspstore", DB_OFFSET(tf_special.bspstore), db_frame}, 86 {"ndirty", DB_OFFSET(tf_special.ndirty), db_frame}, 87 {"rp", DB_OFFSET(tf_special.rp), db_frame}, 88 {"ar.pfs", DB_OFFSET(tf_special.pfs), db_frame}, 89 {"psr", DB_OFFSET(tf_special.psr), db_frame}, 90 {"cr.isr", DB_OFFSET(tf_special.isr), db_frame}, 91 {"pr", DB_OFFSET(tf_special.pr), db_frame}, 92 {"ar.rsc", DB_OFFSET(tf_special.rsc), db_frame}, 93 {"ar.rnat", DB_OFFSET(tf_special.rnat), db_frame}, 94 {"ar.unat", DB_OFFSET(tf_special.unat), db_frame}, 95 {"ar.fpsr", DB_OFFSET(tf_special.fpsr), db_frame}, 96 {"gp", DB_OFFSET(tf_special.gp), db_frame}, 97 {"sp", DB_OFFSET(tf_special.sp), db_frame}, 98 {"tp", DB_OFFSET(tf_special.tp), db_frame}, 99 {"b6", DB_OFFSET(tf_scratch.br6), db_frame}, 100 {"b7", DB_OFFSET(tf_scratch.br7), db_frame}, 101 {"r2", DB_OFFSET(tf_scratch.gr2), db_frame}, 102 {"r3", DB_OFFSET(tf_scratch.gr3), db_frame}, 103 {"r8", DB_OFFSET(tf_scratch.gr8), db_frame}, 104 {"r9", DB_OFFSET(tf_scratch.gr9), db_frame}, 105 {"r10", DB_OFFSET(tf_scratch.gr10), db_frame}, 106 {"r11", DB_OFFSET(tf_scratch.gr11), db_frame}, 107 {"r14", DB_OFFSET(tf_scratch.gr14), db_frame}, 108 {"r15", DB_OFFSET(tf_scratch.gr15), db_frame}, 109 {"r16", DB_OFFSET(tf_scratch.gr16), db_frame}, 110 {"r17", DB_OFFSET(tf_scratch.gr17), db_frame}, 111 {"r18", DB_OFFSET(tf_scratch.gr18), db_frame}, 112 {"r19", DB_OFFSET(tf_scratch.gr19), db_frame}, 113 {"r20", DB_OFFSET(tf_scratch.gr20), db_frame}, 114 {"r21", DB_OFFSET(tf_scratch.gr21), db_frame}, 115 {"r22", DB_OFFSET(tf_scratch.gr22), db_frame}, 116 {"r23", DB_OFFSET(tf_scratch.gr23), db_frame}, 117 {"r24", DB_OFFSET(tf_scratch.gr24), db_frame}, 118 {"r25", DB_OFFSET(tf_scratch.gr25), db_frame}, 119 {"r26", DB_OFFSET(tf_scratch.gr26), db_frame}, 120 {"r27", DB_OFFSET(tf_scratch.gr27), db_frame}, 121 {"r28", DB_OFFSET(tf_scratch.gr28), db_frame}, 122 {"r29", DB_OFFSET(tf_scratch.gr29), db_frame}, 123 {"r30", DB_OFFSET(tf_scratch.gr30), db_frame}, 124 {"r31", DB_OFFSET(tf_scratch.gr31), db_frame}, 125 {"r32", (db_expr_t*)0, db_getrse}, 126 {"r33", (db_expr_t*)1, db_getrse}, 127 {"r34", (db_expr_t*)2, db_getrse}, 128 {"r35", (db_expr_t*)3, db_getrse}, 129 {"r36", (db_expr_t*)4, db_getrse}, 130 {"r37", (db_expr_t*)5, db_getrse}, 131 {"r38", (db_expr_t*)6, db_getrse}, 132 {"r39", (db_expr_t*)7, db_getrse}, 133 {"r40", (db_expr_t*)8, db_getrse}, 134 {"r41", (db_expr_t*)9, db_getrse}, 135 {"r42", (db_expr_t*)10, db_getrse}, 136 {"r43", (db_expr_t*)11, db_getrse}, 137 {"r44", (db_expr_t*)12, db_getrse}, 138 {"r45", (db_expr_t*)13, db_getrse}, 139 {"r46", (db_expr_t*)14, db_getrse}, 140 {"r47", (db_expr_t*)15, db_getrse}, 141 {"r48", (db_expr_t*)16, db_getrse}, 142 {"r49", (db_expr_t*)17, db_getrse}, 143 {"r50", (db_expr_t*)18, db_getrse}, 144 {"r51", (db_expr_t*)19, db_getrse}, 145 {"r52", (db_expr_t*)20, db_getrse}, 146 {"r53", (db_expr_t*)21, db_getrse}, 147 {"r54", (db_expr_t*)22, db_getrse}, 148 {"r55", (db_expr_t*)23, db_getrse}, 149 {"r56", (db_expr_t*)24, db_getrse}, 150 {"r57", (db_expr_t*)25, db_getrse}, 151 {"r58", (db_expr_t*)26, db_getrse}, 152 {"r59", (db_expr_t*)27, db_getrse}, 153 {"r60", (db_expr_t*)28, db_getrse}, 154 {"r61", (db_expr_t*)29, db_getrse}, 155 {"r62", (db_expr_t*)30, db_getrse}, 156 {"r63", (db_expr_t*)31, db_getrse}, 157 {"r64", (db_expr_t*)32, db_getrse}, 158 {"r65", (db_expr_t*)33, db_getrse}, 159 {"r66", (db_expr_t*)34, db_getrse}, 160 {"r67", (db_expr_t*)35, db_getrse}, 161 {"r68", (db_expr_t*)36, db_getrse}, 162 {"r69", (db_expr_t*)37, db_getrse}, 163 {"r70", (db_expr_t*)38, db_getrse}, 164 {"r71", (db_expr_t*)39, db_getrse}, 165 {"r72", (db_expr_t*)40, db_getrse}, 166 {"r73", (db_expr_t*)41, db_getrse}, 167 {"r74", (db_expr_t*)42, db_getrse}, 168 {"r75", (db_expr_t*)43, db_getrse}, 169 {"r76", (db_expr_t*)44, db_getrse}, 170 {"r77", (db_expr_t*)45, db_getrse}, 171 {"r78", (db_expr_t*)46, db_getrse}, 172 {"r79", (db_expr_t*)47, db_getrse}, 173 {"r80", (db_expr_t*)48, db_getrse}, 174 {"r81", (db_expr_t*)49, db_getrse}, 175 {"r82", (db_expr_t*)50, db_getrse}, 176 {"r83", (db_expr_t*)51, db_getrse}, 177 {"r84", (db_expr_t*)52, db_getrse}, 178 {"r85", (db_expr_t*)53, db_getrse}, 179 {"r86", (db_expr_t*)54, db_getrse}, 180 {"r87", (db_expr_t*)55, db_getrse}, 181 {"r88", (db_expr_t*)56, db_getrse}, 182 {"r89", (db_expr_t*)57, db_getrse}, 183 {"r90", (db_expr_t*)58, db_getrse}, 184 {"r91", (db_expr_t*)59, db_getrse}, 185 {"r92", (db_expr_t*)60, db_getrse}, 186 {"r93", (db_expr_t*)61, db_getrse}, 187 {"r94", (db_expr_t*)62, db_getrse}, 188 {"r95", (db_expr_t*)63, db_getrse}, 189 {"r96", (db_expr_t*)64, db_getrse}, 190 {"r97", (db_expr_t*)65, db_getrse}, 191 {"r98", (db_expr_t*)66, db_getrse}, 192 {"r99", (db_expr_t*)67, db_getrse}, 193 {"r100", (db_expr_t*)68, db_getrse}, 194 {"r101", (db_expr_t*)69, db_getrse}, 195 {"r102", (db_expr_t*)70, db_getrse}, 196 {"r103", (db_expr_t*)71, db_getrse}, 197 {"r104", (db_expr_t*)72, db_getrse}, 198 {"r105", (db_expr_t*)73, db_getrse}, 199 {"r106", (db_expr_t*)74, db_getrse}, 200 {"r107", (db_expr_t*)75, db_getrse}, 201 {"r108", (db_expr_t*)76, db_getrse}, 202 {"r109", (db_expr_t*)77, db_getrse}, 203 {"r110", (db_expr_t*)78, db_getrse}, 204 {"r111", (db_expr_t*)79, db_getrse}, 205 {"r112", (db_expr_t*)80, db_getrse}, 206 {"r113", (db_expr_t*)81, db_getrse}, 207 {"r114", (db_expr_t*)82, db_getrse}, 208 {"r115", (db_expr_t*)83, db_getrse}, 209 {"r116", (db_expr_t*)84, db_getrse}, 210 {"r117", (db_expr_t*)85, db_getrse}, 211 {"r118", (db_expr_t*)86, db_getrse}, 212 {"r119", (db_expr_t*)87, db_getrse}, 213 {"r120", (db_expr_t*)88, db_getrse}, 214 {"r121", (db_expr_t*)89, db_getrse}, 215 {"r122", (db_expr_t*)90, db_getrse}, 216 {"r123", (db_expr_t*)91, db_getrse}, 217 {"r124", (db_expr_t*)92, db_getrse}, 218 {"r125", (db_expr_t*)93, db_getrse}, 219 {"r126", (db_expr_t*)94, db_getrse}, 220 {"r127", (db_expr_t*)95, db_getrse}, 221}; 222struct db_variable *db_eregs = db_regs + sizeof(db_regs)/sizeof(db_regs[0]); 223 224static int 225db_backtrace(struct thread *td, struct pcb *pcb, int count) 226{ 227 struct unw_regstate rs; 228 struct trapframe *tf; 229 const char *name; 230 db_expr_t offset; 231 uint64_t bsp, cfm, ip, pfs, reg, sp; 232 c_db_sym_t sym; 233 int args, error, i; 234 235 error = unw_create_from_pcb(&rs, pcb); 236 while (!error && count-- && !db_pager_quit) { 237 error = unw_get_cfm(&rs, &cfm); 238 if (!error) 239 error = unw_get_bsp(&rs, &bsp); 240 if (!error) 241 error = unw_get_ip(&rs, &ip); 242 if (!error) 243 error = unw_get_sp(&rs, &sp); 244 if (error) 245 break; 246 247 args = IA64_CFM_SOL(cfm); 248 if (args > 8) 249 args = 8; 250 251 error = unw_step(&rs); 252 if (!error) { 253 if (!unw_get_cfm(&rs, &pfs)) { 254 i = IA64_CFM_SOF(pfs) - IA64_CFM_SOL(pfs); 255 if (args > i) 256 args = i; 257 } 258 } 259 260 sym = db_search_symbol(ip, DB_STGY_ANY, &offset); 261 db_symbol_values(sym, &name, NULL); 262 db_printf("%s(", name); 263 if (bsp >= VM_MAXUSER_ADDRESS) { 264 for (i = 0; i < args; i++) { 265 if ((bsp & 0x1ff) == 0x1f8) 266 bsp += 8; 267 db_read_bytes(bsp, sizeof(reg), (void*)®); 268 if (i > 0) 269 db_printf(", "); 270 db_printf("0x%lx", reg); 271 bsp += 8; 272 } 273 } else 274 db_printf("..."); 275 db_printf(") at "); 276 277 db_printsym(ip, DB_STGY_PROC); 278 db_printf("\n"); 279 280 if (error != ERESTART) 281 continue; 282 if (sp < VM_MAXUSER_ADDRESS) 283 break; 284 285 tf = (struct trapframe *)(sp + 16); 286 if ((tf->tf_flags & FRAME_SYSCALL) != 0 || 287 tf->tf_special.iip < VM_MAXUSER_ADDRESS) 288 break; 289 290 /* XXX ask if we should unwind across the trapframe. */ 291 db_printf("--- trapframe at %p\n", tf); 292 unw_delete(&rs); 293 error = unw_create_from_frame(&rs, tf); 294 } 295 296 unw_delete(&rs); 297 /* 298 * EJUSTRETURN and ERESTART signal the end of a trace and 299 * are not really errors. 300 */ 301 return ((error > 0) ? error : 0); 302} 303 304void 305db_bkpt_clear(db_addr_t addr, BKPT_INST_TYPE *storage) 306{ 307 BKPT_INST_TYPE tmp; 308 db_addr_t loc; 309 int slot; 310 311 slot = addr & 0xfUL; 312 if (slot >= SLOT_COUNT) 313 return; 314 loc = (addr & ~0xfUL) + (slot << 2); 315 316 db_read_bytes(loc, sizeof(BKPT_INST_TYPE), (char *)&tmp); 317 tmp &= ~(SLOT_MASK << SLOT_SHIFT(slot)); 318 tmp |= *storage << SLOT_SHIFT(slot); 319 db_write_bytes(loc, sizeof(BKPT_INST_TYPE), (char *)&tmp); 320} 321 322void 323db_bkpt_skip(void) 324{ 325 326 if (kdb_frame == NULL) 327 return; 328 329 kdb_frame->tf_special.psr += IA64_PSR_RI_1; 330 if ((kdb_frame->tf_special.psr & IA64_PSR_RI) > IA64_PSR_RI_2) { 331 kdb_frame->tf_special.psr &= ~IA64_PSR_RI; 332 kdb_frame->tf_special.iip += 16; 333 } 334} 335 336void 337db_bkpt_write(db_addr_t addr, BKPT_INST_TYPE *storage) 338{ 339 BKPT_INST_TYPE tmp; 340 db_addr_t loc; 341 int slot; 342 343 slot = addr & 0xfUL; 344 if (slot >= SLOT_COUNT) 345 return; 346 loc = (addr & ~0xfUL) + (slot << 2); 347 348 db_read_bytes(loc, sizeof(BKPT_INST_TYPE), (char *)&tmp); 349 *storage = (tmp >> SLOT_SHIFT(slot)) & SLOT_MASK; 350 351 tmp &= ~(SLOT_MASK << SLOT_SHIFT(slot)); 352 tmp |= (0x84000 << 6) << SLOT_SHIFT(slot); 353 db_write_bytes(loc, sizeof(BKPT_INST_TYPE), (char *)&tmp); 354} 355 356db_addr_t 357db_disasm(db_addr_t loc, boolean_t altfmt) 358{ 359 char buf[32]; 360 struct asm_bundle bundle; 361 const struct asm_inst *i; 362 const char *tmpl; 363 int n, slot; 364 365 slot = loc & 0xf; 366 loc &= ~0xful; 367 db_read_bytes(loc, 16, buf); 368 if (asm_decode((uintptr_t)buf, &bundle)) { 369 i = bundle.b_inst + slot; 370 tmpl = bundle.b_templ + slot; 371 if (*tmpl == ';' || (slot == 2 && bundle.b_templ[1] == ';')) 372 tmpl++; 373 if (*tmpl == 'L' || i->i_op == ASM_OP_NONE) { 374 db_printf("\n"); 375 goto out; 376 } 377 378 /* Unit + slot. */ 379 db_printf("[%c%d] ", *tmpl, slot); 380 381 /* Predicate. */ 382 if (i->i_oper[0].o_value != 0) { 383 asm_operand(i->i_oper+0, buf, loc); 384 db_printf("(%s) ", buf); 385 } else 386 db_printf(" "); 387 388 /* Mnemonic & completers. */ 389 asm_mnemonic(i->i_op, buf); 390 db_printf(buf); 391 n = 0; 392 while (n < i->i_ncmpltrs) { 393 asm_completer(i->i_cmpltr + n, buf); 394 db_printf(buf); 395 n++; 396 } 397 db_printf(" "); 398 399 /* Operands. */ 400 n = 1; 401 while (n < 7 && i->i_oper[n].o_type != ASM_OPER_NONE) { 402 if (n > 1) { 403 if (n == i->i_srcidx) 404 db_printf("="); 405 else 406 db_printf(","); 407 } 408 asm_operand(i->i_oper + n, buf, loc); 409 db_printf(buf); 410 n++; 411 } 412 if (tmpl[1] == ';') 413 db_printf(" ;;"); 414 } else { 415 tmpl = NULL; 416 slot = 2; 417 } 418 db_printf("\n"); 419 420out: 421 slot++; 422 if (slot == 1 && tmpl[1] == 'L') 423 slot++; 424 if (slot > 2) 425 slot = 16; 426 return (loc + slot); 427} 428 429int 430db_fncall_ia64(db_expr_t addr, db_expr_t *rv, int nargs, db_expr_t args[]) 431{ 432 struct ia64_fdesc fdesc; 433 __db_f *f; 434 435 f = (__db_f *)&fdesc; 436 fdesc.func = addr; 437 fdesc.gp = __db_gp; /* XXX doesn't work for modules. */ 438 *rv = (*f)(args[0], args[1], args[2], args[3], args[4], args[5], 439 args[6], args[7]); 440 return (1); 441} 442 443static int 444db_frame(struct db_variable *vp, db_expr_t *valuep, int op) 445{ 446 uint64_t *reg; 447 448 if (kdb_frame == NULL) 449 return (0); 450 reg = (uint64_t*)((uintptr_t)kdb_frame + (uintptr_t)vp->valuep); 451 if (op == DB_VAR_GET) 452 *valuep = *reg; 453 else 454 *reg = *valuep; 455 return (1); 456} 457 458static int 459db_getip(struct db_variable *vp, db_expr_t *valuep, int op) 460{ 461 u_long iip, slot; 462 463 if (kdb_frame == NULL) 464 return (0); 465 466 if (op == DB_VAR_GET) { 467 iip = kdb_frame->tf_special.iip; 468 slot = (kdb_frame->tf_special.psr >> 41) & 3; 469 *valuep = iip + slot; 470 } else { 471 iip = *valuep & ~0xf; 472 slot = *valuep & 0xf; 473 if (slot > 2) 474 return (0); 475 kdb_frame->tf_special.iip = iip; 476 kdb_frame->tf_special.psr &= ~IA64_PSR_RI; 477 kdb_frame->tf_special.psr |= slot << 41; 478 } 479 return (1); 480} 481 482static int 483db_getrse(struct db_variable *vp, db_expr_t *valuep, int op) 484{ 485 u_int64_t *reg; 486 uint64_t bsp; 487 int nats, regno, sof; 488 489 if (kdb_frame == NULL) 490 return (0); 491 492 regno = (int)(intptr_t)valuep; 493 bsp = kdb_frame->tf_special.bspstore + kdb_frame->tf_special.ndirty; 494 sof = (int)(kdb_frame->tf_special.cfm & 0x7f); 495 496 if (regno >= sof) 497 return (0); 498 499 nats = (sof - regno + 63 - ((int)(bsp >> 3) & 0x3f)) / 63; 500 reg = (void*)(bsp - ((sof - regno + nats) << 3)); 501 if (op == DB_VAR_GET) 502 *valuep = *reg; 503 else 504 *reg = *valuep; 505 return (1); 506} 507 508int 509db_md_clr_watchpoint(db_expr_t addr, db_expr_t size) 510{ 511 512 return (-1); 513} 514 515void 516db_md_list_watchpoints() 517{ 518 519 return; 520} 521 522int 523db_md_set_watchpoint(db_expr_t addr, db_expr_t size) 524{ 525 526 return (-1); 527} 528 529/* 530 * Read bytes from kernel address space for debugger. 531 */ 532int 533db_read_bytes(vm_offset_t addr, size_t size, char *data) 534{ 535 jmp_buf jb; 536 void *prev_jb; 537 char *src; 538 int ret; 539 540 prev_jb = kdb_jmpbuf(jb); 541 ret = setjmp(jb); 542 if (ret == 0) { 543 src = (char *)addr; 544 while (size-- > 0) 545 *data++ = *src++; 546 } 547 (void)kdb_jmpbuf(prev_jb); 548 return (ret); 549} 550 551/* 552 * Write bytes to kernel address space for debugger. 553 */ 554int 555db_write_bytes(vm_offset_t addr, size_t size, char *data) 556{ 557 jmp_buf jb; 558 void *prev_jb; 559 size_t cnt; 560 char *dst; 561 int ret; 562 563 prev_jb = kdb_jmpbuf(jb); 564 ret = setjmp(jb); 565 if (ret == 0) { 566 dst = (char *)addr; 567 cnt = size; 568 while (cnt-- > 0) 569 *dst++ = *data++; 570 kdb_cpu_sync_icache((void *)addr, size); 571 } 572 (void)kdb_jmpbuf(prev_jb); 573 return (ret); 574} 575 576void 577db_show_mdpcpu(struct pcpu *pc) 578{ 579 struct pcpu_md *md = &pc->pc_md; 580 581 db_printf("MD: vhpt = %#lx\n", md->vhpt); 582 db_printf("MD: lid = %#lx\n", md->lid); 583 db_printf("MD: clock = %#lx\n", md->clock); 584 db_printf("MD: clock_mode = %u\n", md->clock_mode); 585 db_printf("MD: clock_load = %#lx\n", md->clock_load); 586 db_printf("MD: stats = %p\n", &md->stats); 587 db_printf("MD: pmap = %p\n", md->current_pmap); 588#ifdef XTRACE 589 db_printf("MD: xtrace_buffer = %p\n", md->xtrace_buffer); 590 db_printf("MD: xtrace_tail = %#lx\n", md->xtrace_tail); 591#endif 592} 593 594void 595db_trace_self(void) 596{ 597 struct pcb pcb; 598 599 savectx(&pcb); 600 db_backtrace(curthread, &pcb, -1); 601} 602 603int 604db_trace_thread(struct thread *td, int count) 605{ 606 struct pcb *ctx; 607 608 ctx = kdb_thr_ctx(td); 609 return (db_backtrace(td, ctx, count)); 610} 611