db_trace.c revision 290731
1/*- 2 * Mach Operating System 3 * Copyright (c) 1991,1990 Carnegie Mellon University 4 * All Rights Reserved. 5 * 6 * Permission to use, copy, modify and distribute this software and its 7 * documentation is hereby granted, provided that both the copyright 8 * notice and this permission notice appear in all copies of the 9 * software, derivative works or modified versions, and any portions 10 * thereof, and that both notices appear in supporting documentation. 11 * 12 * CARNEGIE MELLON ALLOWS FREE USE OF THIS SOFTWARE IN ITS 13 * CONDITION. CARNEGIE MELLON DISCLAIMS ANY LIABILITY OF ANY KIND FOR 14 * ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE. 15 * 16 * Carnegie Mellon requests users of this software to return to 17 * 18 * Software Distribution Coordinator or Software.Distribution@CS.CMU.EDU 19 * School of Computer Science 20 * Carnegie Mellon University 21 * Pittsburgh PA 15213-3890 22 * 23 * any improvements or extensions that they make and grant Carnegie the 24 * rights to redistribute these changes. 25 */ 26 27#include <sys/cdefs.h> 28__FBSDID("$FreeBSD: stable/10/sys/i386/i386/db_trace.c 290731 2015-11-12 23:49:47Z jhb $"); 29 30#include <sys/param.h> 31#include <sys/systm.h> 32#include <sys/kdb.h> 33#include <sys/proc.h> 34#include <sys/sysent.h> 35 36#include <machine/cpu.h> 37#include <machine/md_var.h> 38#include <machine/pcb.h> 39#include <machine/reg.h> 40#include <machine/stack.h> 41 42#include <vm/vm.h> 43#include <vm/vm_param.h> 44#include <vm/pmap.h> 45 46#include <ddb/ddb.h> 47#include <ddb/db_access.h> 48#include <ddb/db_sym.h> 49#include <ddb/db_variables.h> 50 51static db_varfcn_t db_esp; 52static db_varfcn_t db_frame; 53static db_varfcn_t db_frame_seg; 54static db_varfcn_t db_gs; 55static db_varfcn_t db_ss; 56 57/* 58 * Machine register set. 59 */ 60#define DB_OFFSET(x) (db_expr_t *)offsetof(struct trapframe, x) 61struct db_variable db_regs[] = { 62 { "cs", DB_OFFSET(tf_cs), db_frame_seg }, 63 { "ds", DB_OFFSET(tf_ds), db_frame_seg }, 64 { "es", DB_OFFSET(tf_es), db_frame_seg }, 65 { "fs", DB_OFFSET(tf_fs), db_frame_seg }, 66 { "gs", NULL, db_gs }, 67 { "ss", NULL, db_ss }, 68 { "eax", DB_OFFSET(tf_eax), db_frame }, 69 { "ecx", DB_OFFSET(tf_ecx), db_frame }, 70 { "edx", DB_OFFSET(tf_edx), db_frame }, 71 { "ebx", DB_OFFSET(tf_ebx), db_frame }, 72 { "esp", NULL, db_esp }, 73 { "ebp", DB_OFFSET(tf_ebp), db_frame }, 74 { "esi", DB_OFFSET(tf_esi), db_frame }, 75 { "edi", DB_OFFSET(tf_edi), db_frame }, 76 { "eip", DB_OFFSET(tf_eip), db_frame }, 77 { "efl", DB_OFFSET(tf_eflags), db_frame }, 78}; 79struct db_variable *db_eregs = db_regs + nitems(db_regs); 80 81static __inline int 82get_esp(struct trapframe *tf) 83{ 84 return ((ISPL(tf->tf_cs)) ? tf->tf_esp : 85 (db_expr_t)tf + (uintptr_t)DB_OFFSET(tf_esp)); 86} 87 88static int 89db_frame(struct db_variable *vp, db_expr_t *valuep, int op) 90{ 91 int *reg; 92 93 if (kdb_frame == NULL) 94 return (0); 95 96 reg = (int *)((uintptr_t)kdb_frame + (db_expr_t)vp->valuep); 97 if (op == DB_VAR_GET) 98 *valuep = *reg; 99 else 100 *reg = *valuep; 101 return (1); 102} 103 104static int 105db_frame_seg(struct db_variable *vp, db_expr_t *valuep, int op) 106{ 107 uint16_t *reg; 108 109 if (kdb_frame == NULL) 110 return (0); 111 112 reg = (uint16_t *)((uintptr_t)kdb_frame + (db_expr_t)vp->valuep); 113 if (op == DB_VAR_GET) 114 *valuep = *reg; 115 else 116 *reg = *valuep; 117 return (1); 118} 119 120static int 121db_esp(struct db_variable *vp, db_expr_t *valuep, int op) 122{ 123 124 if (kdb_frame == NULL) 125 return (0); 126 127 if (op == DB_VAR_GET) 128 *valuep = get_esp(kdb_frame); 129 else if (ISPL(kdb_frame->tf_cs)) 130 kdb_frame->tf_esp = *valuep; 131 return (1); 132} 133 134static int 135db_gs(struct db_variable *vp, db_expr_t *valuep, int op) 136{ 137 138 if (op == DB_VAR_GET) 139 *valuep = rgs(); 140 else 141 load_gs(*valuep); 142 return (1); 143} 144 145static int 146db_ss(struct db_variable *vp, db_expr_t *valuep, int op) 147{ 148 149 if (kdb_frame == NULL) 150 return (0); 151 152 if (op == DB_VAR_GET) 153 *valuep = (ISPL(kdb_frame->tf_cs)) ? kdb_frame->tf_ss : rss(); 154 else if (ISPL(kdb_frame->tf_cs)) 155 kdb_frame->tf_ss = *valuep; 156 return (1); 157} 158 159#define NORMAL 0 160#define TRAP 1 161#define INTERRUPT 2 162#define SYSCALL 3 163#define DOUBLE_FAULT 4 164#define TRAP_INTERRUPT 5 165#define TRAP_TIMERINT 6 166 167static void db_nextframe(struct i386_frame **, db_addr_t *, struct thread *); 168static int db_numargs(struct i386_frame *); 169static void db_print_stack_entry(const char *, int, char **, int *, db_addr_t, 170 void *); 171static void decode_syscall(int, struct thread *); 172 173static const char * watchtype_str(int type); 174int i386_set_watch(int watchnum, unsigned int watchaddr, int size, int access, 175 struct dbreg *d); 176int i386_clr_watch(int watchnum, struct dbreg *d); 177 178/* 179 * Figure out how many arguments were passed into the frame at "fp". 180 */ 181static int 182db_numargs(fp) 183 struct i386_frame *fp; 184{ 185 char *argp; 186 int inst; 187 int args; 188 189 argp = (char *)db_get_value((int)&fp->f_retaddr, 4, FALSE); 190 /* 191 * XXX etext is wrong for LKMs. We should attempt to interpret 192 * the instruction at the return address in all cases. This 193 * may require better fault handling. 194 */ 195 if (argp < btext || argp >= etext) { 196 args = -1; 197 } else { 198retry: 199 inst = db_get_value((int)argp, 4, FALSE); 200 if ((inst & 0xff) == 0x59) /* popl %ecx */ 201 args = 1; 202 else if ((inst & 0xffff) == 0xc483) /* addl $Ibs, %esp */ 203 args = ((inst >> 16) & 0xff) / 4; 204 else if ((inst & 0xf8ff) == 0xc089) { /* movl %eax, %Reg */ 205 argp += 2; 206 goto retry; 207 } else 208 args = -1; 209 } 210 return (args); 211} 212 213static void 214db_print_stack_entry(name, narg, argnp, argp, callpc, frame) 215 const char *name; 216 int narg; 217 char **argnp; 218 int *argp; 219 db_addr_t callpc; 220 void *frame; 221{ 222 int n = narg >= 0 ? narg : 5; 223 224 db_printf("%s(", name); 225 while (n) { 226 if (argnp) 227 db_printf("%s=", *argnp++); 228 db_printf("%r", db_get_value((int)argp, 4, FALSE)); 229 argp++; 230 if (--n != 0) 231 db_printf(","); 232 } 233 if (narg < 0) 234 db_printf(",..."); 235 db_printf(") at "); 236 db_printsym(callpc, DB_STGY_PROC); 237 if (frame != NULL) 238 db_printf("/frame 0x%r", (register_t)frame); 239 db_printf("\n"); 240} 241 242static void 243decode_syscall(int number, struct thread *td) 244{ 245 struct proc *p; 246 c_db_sym_t sym; 247 db_expr_t diff; 248 sy_call_t *f; 249 const char *symname; 250 251 db_printf(" (%d", number); 252 p = (td != NULL) ? td->td_proc : NULL; 253 if (p != NULL && 0 <= number && number < p->p_sysent->sv_size) { 254 f = p->p_sysent->sv_table[number].sy_call; 255 sym = db_search_symbol((db_addr_t)f, DB_STGY_ANY, &diff); 256 if (sym != DB_SYM_NULL && diff == 0) { 257 db_symbol_values(sym, &symname, NULL); 258 db_printf(", %s, %s", p->p_sysent->sv_name, symname); 259 } 260 } 261 db_printf(")"); 262} 263 264/* 265 * Figure out the next frame up in the call stack. 266 */ 267static void 268db_nextframe(struct i386_frame **fp, db_addr_t *ip, struct thread *td) 269{ 270 struct trapframe *tf; 271 int frame_type; 272 int eip, esp, ebp; 273 db_expr_t offset; 274 c_db_sym_t sym; 275 const char *name; 276 277 eip = db_get_value((int) &(*fp)->f_retaddr, 4, FALSE); 278 ebp = db_get_value((int) &(*fp)->f_frame, 4, FALSE); 279 280 /* 281 * Figure out frame type. We look at the address just before 282 * the saved instruction pointer as the saved EIP is after the 283 * call function, and if the function being called is marked as 284 * dead (such as panic() at the end of dblfault_handler()), then 285 * the instruction at the saved EIP will be part of a different 286 * function (syscall() in this example) rather than the one that 287 * actually made the call. 288 */ 289 frame_type = NORMAL; 290 sym = db_search_symbol(eip - 1, DB_STGY_ANY, &offset); 291 db_symbol_values(sym, &name, NULL); 292 if (name != NULL) { 293 if (strcmp(name, "calltrap") == 0 || 294 strcmp(name, "fork_trampoline") == 0) 295 frame_type = TRAP; 296 else if (strncmp(name, "Xatpic_intr", 11) == 0 || 297 strncmp(name, "Xapic_isr", 9) == 0) 298 frame_type = INTERRUPT; 299 else if (strcmp(name, "Xlcall_syscall") == 0 || 300 strcmp(name, "Xint0x80_syscall") == 0) 301 frame_type = SYSCALL; 302 else if (strcmp(name, "dblfault_handler") == 0) 303 frame_type = DOUBLE_FAULT; 304 /* XXX: These are interrupts with trap frames. */ 305 else if (strcmp(name, "Xtimerint") == 0) 306 frame_type = TRAP_TIMERINT; 307 else if (strcmp(name, "Xcpustop") == 0 || 308 strcmp(name, "Xrendezvous") == 0 || 309 strcmp(name, "Xipi_intr_bitmap_handler") == 0 || 310 strcmp(name, "Xlazypmap") == 0) 311 frame_type = TRAP_INTERRUPT; 312 } 313 314 /* 315 * Normal frames need no special processing. 316 */ 317 if (frame_type == NORMAL) { 318 *ip = (db_addr_t) eip; 319 *fp = (struct i386_frame *) ebp; 320 return; 321 } 322 323 db_print_stack_entry(name, 0, 0, 0, eip, &(*fp)->f_frame); 324 325 /* 326 * For a double fault, we have to snag the values from the 327 * previous TSS since a double fault uses a task gate to 328 * switch to a known good state. 329 */ 330 if (frame_type == DOUBLE_FAULT) { 331 esp = PCPU_GET(common_tss.tss_esp); 332 eip = PCPU_GET(common_tss.tss_eip); 333 ebp = PCPU_GET(common_tss.tss_ebp); 334 db_printf( 335 "--- trap 0x17, eip = %#r, esp = %#r, ebp = %#r ---\n", 336 eip, esp, ebp); 337 *ip = (db_addr_t) eip; 338 *fp = (struct i386_frame *) ebp; 339 return; 340 } 341 342 /* 343 * Point to base of trapframe which is just above the 344 * current frame. 345 */ 346 if (frame_type == INTERRUPT) 347 tf = (struct trapframe *)((int)*fp + 16); 348 else if (frame_type == TRAP_INTERRUPT) 349 tf = (struct trapframe *)((int)*fp + 8); 350 else 351 tf = (struct trapframe *)((int)*fp + 12); 352 353 if (INKERNEL((int) tf)) { 354 esp = get_esp(tf); 355 eip = tf->tf_eip; 356 ebp = tf->tf_ebp; 357 switch (frame_type) { 358 case TRAP: 359 db_printf("--- trap %#r", tf->tf_trapno); 360 break; 361 case SYSCALL: 362 db_printf("--- syscall"); 363 decode_syscall(tf->tf_eax, td); 364 break; 365 case TRAP_TIMERINT: 366 case TRAP_INTERRUPT: 367 case INTERRUPT: 368 db_printf("--- interrupt"); 369 break; 370 default: 371 panic("The moon has moved again."); 372 } 373 db_printf(", eip = %#r, esp = %#r, ebp = %#r ---\n", eip, 374 esp, ebp); 375 } 376 377 *ip = (db_addr_t) eip; 378 *fp = (struct i386_frame *) ebp; 379} 380 381static int 382db_backtrace(struct thread *td, struct trapframe *tf, struct i386_frame *frame, 383 db_addr_t pc, register_t sp, int count) 384{ 385 struct i386_frame *actframe; 386#define MAXNARG 16 387 char *argnames[MAXNARG], **argnp = NULL; 388 const char *name; 389 int *argp; 390 db_expr_t offset; 391 c_db_sym_t sym; 392 int instr, narg; 393 boolean_t first; 394 395 /* 396 * If an indirect call via an invalid pointer caused a trap, 397 * %pc contains the invalid address while the return address 398 * of the unlucky caller has been saved by CPU on the stack 399 * just before the trap frame. In this case, try to recover 400 * the caller's address so that the first frame is assigned 401 * to the right spot in the right function, for that is where 402 * the failure actually happened. 403 * 404 * This trick depends on the fault address stashed in tf_err 405 * by trap_fatal() before entering KDB. 406 */ 407 if (kdb_frame && pc == kdb_frame->tf_err) { 408 /* 409 * Find where the trap frame actually ends. 410 * It won't contain tf_esp or tf_ss unless crossing rings. 411 */ 412 if (ISPL(kdb_frame->tf_cs)) 413 instr = (int)(kdb_frame + 1); 414 else 415 instr = (int)&kdb_frame->tf_esp; 416 pc = db_get_value(instr, 4, FALSE); 417 } 418 419 if (count == -1) 420 count = 1024; 421 422 first = TRUE; 423 while (count-- && !db_pager_quit) { 424 sym = db_search_symbol(pc, DB_STGY_ANY, &offset); 425 db_symbol_values(sym, &name, NULL); 426 427 /* 428 * Attempt to determine a (possibly fake) frame that gives 429 * the caller's pc. It may differ from `frame' if the 430 * current function never sets up a standard frame or hasn't 431 * set one up yet or has just discarded one. The last two 432 * cases can be guessed fairly reliably for code generated 433 * by gcc. The first case is too much trouble to handle in 434 * general because the amount of junk on the stack depends 435 * on the pc (the special handling of "calltrap", etc. in 436 * db_nextframe() works because the `next' pc is special). 437 */ 438 actframe = frame; 439 if (first) { 440 first = FALSE; 441 if (sym == C_DB_SYM_NULL && sp != 0) { 442 /* 443 * If a symbol couldn't be found, we've probably 444 * jumped to a bogus location, so try and use 445 * the return address to find our caller. 446 */ 447 db_print_stack_entry(name, 0, 0, 0, pc, 448 NULL); 449 pc = db_get_value(sp, 4, FALSE); 450 if (db_search_symbol(pc, DB_STGY_PROC, 451 &offset) == C_DB_SYM_NULL) 452 break; 453 continue; 454 } else if (tf != NULL) { 455 instr = db_get_value(pc, 4, FALSE); 456 if ((instr & 0xffffff) == 0x00e58955) { 457 /* pushl %ebp; movl %esp, %ebp */ 458 actframe = (void *)(get_esp(tf) - 4); 459 } else if ((instr & 0xffff) == 0x0000e589) { 460 /* movl %esp, %ebp */ 461 actframe = (void *)get_esp(tf); 462 if (tf->tf_ebp == 0) { 463 /* Fake frame better. */ 464 frame = actframe; 465 } 466 } else if ((instr & 0xff) == 0x000000c3) { 467 /* ret */ 468 actframe = (void *)(get_esp(tf) - 4); 469 } else if (offset == 0) { 470 /* Probably an assembler symbol. */ 471 actframe = (void *)(get_esp(tf) - 4); 472 } 473 } else if (strcmp(name, "fork_trampoline") == 0) { 474 /* 475 * Don't try to walk back on a stack for a 476 * process that hasn't actually been run yet. 477 */ 478 db_print_stack_entry(name, 0, 0, 0, pc, 479 actframe); 480 break; 481 } 482 } 483 484 argp = &actframe->f_arg0; 485 narg = MAXNARG; 486 if (sym != NULL && db_sym_numargs(sym, &narg, argnames)) { 487 argnp = argnames; 488 } else { 489 narg = db_numargs(frame); 490 } 491 492 db_print_stack_entry(name, narg, argnp, argp, pc, actframe); 493 494 if (actframe != frame) { 495 /* `frame' belongs to caller. */ 496 pc = (db_addr_t) 497 db_get_value((int)&actframe->f_retaddr, 4, FALSE); 498 continue; 499 } 500 501 db_nextframe(&frame, &pc, td); 502 503 if (INKERNEL((int)pc) && !INKERNEL((int) frame)) { 504 sym = db_search_symbol(pc, DB_STGY_ANY, &offset); 505 db_symbol_values(sym, &name, NULL); 506 db_print_stack_entry(name, 0, 0, 0, pc, frame); 507 break; 508 } 509 if (!INKERNEL((int) frame)) { 510 break; 511 } 512 } 513 514 return (0); 515} 516 517void 518db_trace_self(void) 519{ 520 struct i386_frame *frame; 521 db_addr_t callpc; 522 register_t ebp; 523 524 __asm __volatile("movl %%ebp,%0" : "=r" (ebp)); 525 frame = (struct i386_frame *)ebp; 526 callpc = (db_addr_t)db_get_value((int)&frame->f_retaddr, 4, FALSE); 527 frame = frame->f_frame; 528 db_backtrace(curthread, NULL, frame, callpc, 0, -1); 529} 530 531int 532db_trace_thread(struct thread *thr, int count) 533{ 534 struct pcb *ctx; 535 struct trapframe *tf; 536 537 ctx = kdb_thr_ctx(thr); 538 tf = thr == kdb_thread ? kdb_frame : NULL; 539 return (db_backtrace(thr, tf, (struct i386_frame *)ctx->pcb_ebp, 540 ctx->pcb_eip, ctx->pcb_esp, count)); 541} 542 543int 544i386_set_watch(watchnum, watchaddr, size, access, d) 545 int watchnum; 546 unsigned int watchaddr; 547 int size; 548 int access; 549 struct dbreg *d; 550{ 551 int i, len; 552 553 if (watchnum == -1) { 554 for (i = 0; i < 4; i++) 555 if (!DBREG_DR7_ENABLED(d->dr[7], i)) 556 break; 557 if (i < 4) 558 watchnum = i; 559 else 560 return (-1); 561 } 562 563 switch (access) { 564 case DBREG_DR7_EXEC: 565 size = 1; /* size must be 1 for an execution breakpoint */ 566 /* fall through */ 567 case DBREG_DR7_WRONLY: 568 case DBREG_DR7_RDWR: 569 break; 570 default: 571 return (-1); 572 } 573 574 /* 575 * we can watch a 1, 2, or 4 byte sized location 576 */ 577 switch (size) { 578 case 1: 579 len = DBREG_DR7_LEN_1; 580 break; 581 case 2: 582 len = DBREG_DR7_LEN_2; 583 break; 584 case 4: 585 len = DBREG_DR7_LEN_4; 586 break; 587 default: 588 return (-1); 589 } 590 591 /* clear the bits we are about to affect */ 592 d->dr[7] &= ~DBREG_DR7_MASK(watchnum); 593 594 /* set drN register to the address, N=watchnum */ 595 DBREG_DRX(d, watchnum) = watchaddr; 596 597 /* enable the watchpoint */ 598 d->dr[7] |= DBREG_DR7_SET(watchnum, len, access, 599 DBREG_DR7_GLOBAL_ENABLE); 600 601 return (watchnum); 602} 603 604 605int 606i386_clr_watch(watchnum, d) 607 int watchnum; 608 struct dbreg *d; 609{ 610 611 if (watchnum < 0 || watchnum >= 4) 612 return (-1); 613 614 d->dr[7] &= ~DBREG_DR7_MASK(watchnum); 615 DBREG_DRX(d, watchnum) = 0; 616 617 return (0); 618} 619 620 621int 622db_md_set_watchpoint(addr, size) 623 db_expr_t addr; 624 db_expr_t size; 625{ 626 struct dbreg d; 627 int avail, i, wsize; 628 629 fill_dbregs(NULL, &d); 630 631 avail = 0; 632 for(i = 0; i < 4; i++) { 633 if (!DBREG_DR7_ENABLED(d.dr[7], i)) 634 avail++; 635 } 636 637 if (avail * 4 < size) 638 return (-1); 639 640 for (i = 0; i < 4 && (size > 0); i++) { 641 if (!DBREG_DR7_ENABLED(d.dr[7], i)) { 642 if (size > 2) 643 wsize = 4; 644 else 645 wsize = size; 646 i386_set_watch(i, addr, wsize, 647 DBREG_DR7_WRONLY, &d); 648 addr += wsize; 649 size -= wsize; 650 } 651 } 652 653 set_dbregs(NULL, &d); 654 655 return(0); 656} 657 658 659int 660db_md_clr_watchpoint(addr, size) 661 db_expr_t addr; 662 db_expr_t size; 663{ 664 struct dbreg d; 665 int i; 666 667 fill_dbregs(NULL, &d); 668 669 for(i = 0; i < 4; i++) { 670 if (DBREG_DR7_ENABLED(d.dr[7], i)) { 671 if ((DBREG_DRX((&d), i) >= addr) && 672 (DBREG_DRX((&d), i) < addr+size)) 673 i386_clr_watch(i, &d); 674 675 } 676 } 677 678 set_dbregs(NULL, &d); 679 680 return(0); 681} 682 683 684static const char * 685watchtype_str(type) 686 int type; 687{ 688 switch (type) { 689 case DBREG_DR7_EXEC : return "execute"; break; 690 case DBREG_DR7_RDWR : return "read/write"; break; 691 case DBREG_DR7_WRONLY : return "write"; break; 692 default : return "invalid"; break; 693 } 694} 695 696 697void 698db_md_list_watchpoints() 699{ 700 struct dbreg d; 701 int i, len, type; 702 703 fill_dbregs(NULL, &d); 704 705 db_printf("\nhardware watchpoints:\n"); 706 db_printf(" watch status type len address\n"); 707 db_printf(" ----- -------- ---------- --- ----------\n"); 708 for (i = 0; i < 4; i++) { 709 if (DBREG_DR7_ENABLED(d.dr[7], i)) { 710 type = DBREG_DR7_ACCESS(d.dr[7], i); 711 len = DBREG_DR7_LEN(d.dr[7], i); 712 db_printf(" %-5d %-8s %10s %3d ", 713 i, "enabled", watchtype_str(type), len + 1); 714 db_printsym((db_addr_t)DBREG_DRX((&d), i), DB_STGY_ANY); 715 db_printf("\n"); 716 } else { 717 db_printf(" %-5d disabled\n", i); 718 } 719 } 720 721 db_printf("\ndebug register values:\n"); 722 for (i = 0; i < 8; i++) { 723 db_printf(" dr%d 0x%08x\n", i, DBREG_DRX((&d), i)); 724 } 725 db_printf("\n"); 726} 727 728 729