db_trace.c (121989) | db_trace.c (131952) |
---|---|
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 --- 11 unchanged lines hidden (view full) --- 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> | 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 --- 11 unchanged lines hidden (view full) --- 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: head/sys/i386/i386/db_trace.c 121989 2003-11-03 22:07:21Z jhb $"); | 28__FBSDID("$FreeBSD: head/sys/i386/i386/db_trace.c 131952 2004-07-10 23:47:20Z marcel $"); |
29 30#include <sys/param.h> 31#include <sys/systm.h> | 29 30#include <sys/param.h> 31#include <sys/systm.h> |
32#include <sys/kdb.h> |
|
32#include <sys/proc.h> 33#include <sys/sysent.h> 34 35#include <machine/cpu.h> 36#include <machine/md_var.h> 37#include <machine/pcb.h> 38#include <machine/reg.h> 39 40#include <vm/vm.h> 41#include <vm/vm_param.h> 42#include <vm/pmap.h> 43 44#include <ddb/ddb.h> 45#include <ddb/db_access.h> 46#include <ddb/db_sym.h> 47#include <ddb/db_variables.h> 48 | 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 41#include <vm/vm.h> 42#include <vm/vm_param.h> 43#include <vm/pmap.h> 44 45#include <ddb/ddb.h> 46#include <ddb/db_access.h> 47#include <ddb/db_sym.h> 48#include <ddb/db_variables.h> 49 |
49db_varfcn_t db_dr0; 50db_varfcn_t db_dr1; 51db_varfcn_t db_dr2; 52db_varfcn_t db_dr3; 53db_varfcn_t db_dr4; 54db_varfcn_t db_dr5; 55db_varfcn_t db_dr6; 56db_varfcn_t db_dr7; | 50static db_varfcn_t db_dr0; 51static db_varfcn_t db_dr1; 52static db_varfcn_t db_dr2; 53static db_varfcn_t db_dr3; 54static db_varfcn_t db_dr4; 55static db_varfcn_t db_dr5; 56static db_varfcn_t db_dr6; 57static db_varfcn_t db_dr7; 58static db_varfcn_t db_esp; 59static db_varfcn_t db_frame; 60static db_varfcn_t db_ss; |
57 58/* 59 * Machine register set. 60 */ | 61 62/* 63 * Machine register set. 64 */ |
65#define DB_OFFSET(x) (db_expr_t *)offsetof(struct trapframe, x) |
|
61struct db_variable db_regs[] = { | 66struct db_variable db_regs[] = { |
62 { "cs", &ddb_regs.tf_cs, FCN_NULL }, 63 { "ds", &ddb_regs.tf_ds, FCN_NULL }, 64 { "es", &ddb_regs.tf_es, FCN_NULL }, 65 { "fs", &ddb_regs.tf_fs, FCN_NULL }, 66#if 0 67 { "gs", &ddb_regs.tf_gs, FCN_NULL }, 68#endif 69 { "ss", &ddb_regs.tf_ss, FCN_NULL }, 70 { "eax", &ddb_regs.tf_eax, FCN_NULL }, 71 { "ecx", &ddb_regs.tf_ecx, FCN_NULL }, 72 { "edx", &ddb_regs.tf_edx, FCN_NULL }, 73 { "ebx", &ddb_regs.tf_ebx, FCN_NULL }, 74 { "esp", &ddb_regs.tf_esp, FCN_NULL }, 75 { "ebp", &ddb_regs.tf_ebp, FCN_NULL }, 76 { "esi", &ddb_regs.tf_esi, FCN_NULL }, 77 { "edi", &ddb_regs.tf_edi, FCN_NULL }, 78 { "eip", &ddb_regs.tf_eip, FCN_NULL }, 79 { "efl", &ddb_regs.tf_eflags, FCN_NULL }, 80 { "dr0", NULL, db_dr0 }, 81 { "dr1", NULL, db_dr1 }, 82 { "dr2", NULL, db_dr2 }, 83 { "dr3", NULL, db_dr3 }, 84 { "dr4", NULL, db_dr4 }, 85 { "dr5", NULL, db_dr5 }, 86 { "dr6", NULL, db_dr6 }, 87 { "dr7", NULL, db_dr7 }, | 67 { "cs", DB_OFFSET(tf_cs), db_frame }, 68 { "ds", DB_OFFSET(tf_ds), db_frame }, 69 { "es", DB_OFFSET(tf_es), db_frame }, 70 { "fs", DB_OFFSET(tf_fs), db_frame }, 71 { "ss", NULL, db_ss }, 72 { "eax", DB_OFFSET(tf_eax), db_frame }, 73 { "ecx", DB_OFFSET(tf_ecx), db_frame }, 74 { "edx", DB_OFFSET(tf_edx), db_frame }, 75 { "ebx", DB_OFFSET(tf_ebx), db_frame }, 76 { "esp", NULL, db_esp }, 77 { "ebp", DB_OFFSET(tf_ebp), db_frame }, 78 { "esi", DB_OFFSET(tf_esi), db_frame }, 79 { "edi", DB_OFFSET(tf_edi), db_frame }, 80 { "eip", DB_OFFSET(tf_eip), db_frame }, 81 { "efl", DB_OFFSET(tf_eflags), db_frame }, 82 { "dr0", NULL, db_dr0 }, 83 { "dr1", NULL, db_dr1 }, 84 { "dr2", NULL, db_dr2 }, 85 { "dr3", NULL, db_dr3 }, 86 { "dr4", NULL, db_dr4 }, 87 { "dr5", NULL, db_dr5 }, 88 { "dr6", NULL, db_dr6 }, 89 { "dr7", NULL, db_dr7 }, |
88}; 89struct db_variable *db_eregs = db_regs + sizeof(db_regs)/sizeof(db_regs[0]); 90 | 90}; 91struct db_variable *db_eregs = db_regs + sizeof(db_regs)/sizeof(db_regs[0]); 92 |
93#define DB_DRX_FUNC(reg) \ 94static int \ 95db_ ## reg (vp, valuep, op) \ 96 struct db_variable *vp; \ 97 db_expr_t * valuep; \ 98 int op; \ 99{ \ 100 if (op == DB_VAR_GET) \ 101 *valuep = r ## reg (); \ 102 else \ 103 load_ ## reg (*valuep); \ 104 return (1); \ 105} 106 107DB_DRX_FUNC(dr0) 108DB_DRX_FUNC(dr1) 109DB_DRX_FUNC(dr2) 110DB_DRX_FUNC(dr3) 111DB_DRX_FUNC(dr4) 112DB_DRX_FUNC(dr5) 113DB_DRX_FUNC(dr6) 114DB_DRX_FUNC(dr7) 115 116static __inline int 117get_esp(struct trapframe *tf) 118{ 119 return ((ISPL(tf->tf_cs)) ? tf->tf_esp : 120 (db_expr_t)tf + (uintptr_t)DB_OFFSET(tf_esp)); 121} 122 123static int 124db_frame(struct db_variable *vp, db_expr_t *valuep, int op) 125{ 126 int *reg; 127 128 if (kdb_frame == NULL) 129 return (0); 130 131 reg = (int *)((uintptr_t)kdb_frame + (db_expr_t)vp->valuep); 132 if (op == DB_VAR_GET) 133 *valuep = *reg; 134 else 135 *reg = *valuep; 136 return (1); 137} 138 139static int 140db_esp(struct db_variable *vp, db_expr_t *valuep, int op) 141{ 142 143 if (kdb_frame == NULL) 144 return (0); 145 146 if (op == DB_VAR_GET) 147 *valuep = get_esp(kdb_frame); 148 else if (ISPL(kdb_frame->tf_cs)) 149 kdb_frame->tf_esp = *valuep; 150 return (1); 151} 152 153static int 154db_ss(struct db_variable *vp, db_expr_t *valuep, int op) 155{ 156 157 if (kdb_frame == NULL) 158 return (0); 159 160 if (op == DB_VAR_GET) 161 *valuep = (ISPL(kdb_frame->tf_cs)) ? kdb_frame->tf_ss : rss(); 162 else if (ISPL(kdb_frame->tf_cs)) 163 kdb_frame->tf_ss = *valuep; 164 return (1); 165} 166 |
|
91/* 92 * Stack trace. 93 */ 94#define INKERNEL(va) (((vm_offset_t)(va)) >= USRSTACK) 95 96struct i386_frame { 97 struct i386_frame *f_frame; 98 int f_retaddr; 99 int f_arg0; 100}; 101 102#define NORMAL 0 103#define TRAP 1 104#define INTERRUPT 2 105#define SYSCALL 3 106 | 167/* 168 * Stack trace. 169 */ 170#define INKERNEL(va) (((vm_offset_t)(va)) >= USRSTACK) 171 172struct i386_frame { 173 struct i386_frame *f_frame; 174 int f_retaddr; 175 int f_arg0; 176}; 177 178#define NORMAL 0 179#define TRAP 1 180#define INTERRUPT 2 181#define SYSCALL 3 182 |
107static void db_nextframe(struct i386_frame **, db_addr_t *, struct proc *); | 183static void db_nextframe(struct i386_frame **, db_addr_t *, struct thread *); |
108static int db_numargs(struct i386_frame *); 109static void db_print_stack_entry(const char *, int, char **, int *, db_addr_t); | 184static int db_numargs(struct i386_frame *); 185static void db_print_stack_entry(const char *, int, char **, int *, db_addr_t); |
110static void decode_syscall(int, struct proc *); 111static void db_trace_one_stack(int count, boolean_t have_addr, 112 struct proc *p, struct i386_frame *frame, db_addr_t callpc); | 186static void decode_syscall(int, struct thread *); |
113 | 187 |
114 | |
115static char * watchtype_str(int type); 116int i386_set_watch(int watchnum, unsigned int watchaddr, int size, int access, 117 struct dbreg * d); 118int i386_clr_watch(int watchnum, struct dbreg * d); 119int db_md_set_watchpoint(db_expr_t addr, db_expr_t size); 120int db_md_clr_watchpoint(db_expr_t addr, db_expr_t size); 121void db_md_list_watchpoints(void); 122 | 188static char * watchtype_str(int type); 189int i386_set_watch(int watchnum, unsigned int watchaddr, int size, int access, 190 struct dbreg * d); 191int i386_clr_watch(int watchnum, struct dbreg * d); 192int db_md_set_watchpoint(db_expr_t addr, db_expr_t size); 193int db_md_clr_watchpoint(db_expr_t addr, db_expr_t size); 194void db_md_list_watchpoints(void); 195 |
123 | |
124/* 125 * Figure out how many arguments were passed into the frame at "fp". 126 */ 127static int 128db_numargs(fp) 129 struct i386_frame *fp; 130{ 131 int *argp; --- 38 unchanged lines hidden (view full) --- 170 db_printf(","); 171 } 172 db_printf(") at "); 173 db_printsym(callpc, DB_STGY_PROC); 174 db_printf("\n"); 175} 176 177static void | 196/* 197 * Figure out how many arguments were passed into the frame at "fp". 198 */ 199static int 200db_numargs(fp) 201 struct i386_frame *fp; 202{ 203 int *argp; --- 38 unchanged lines hidden (view full) --- 242 db_printf(","); 243 } 244 db_printf(") at "); 245 db_printsym(callpc, DB_STGY_PROC); 246 db_printf("\n"); 247} 248 249static void |
178decode_syscall(number, p) 179 int number; 180 struct proc *p; | 250decode_syscall(int number, struct thread *td) |
181{ | 251{ |
252 struct proc *p; |
|
182 c_db_sym_t sym; 183 db_expr_t diff; 184 sy_call_t *f; 185 const char *symname; 186 187 db_printf(" (%d", number); | 253 c_db_sym_t sym; 254 db_expr_t diff; 255 sy_call_t *f; 256 const char *symname; 257 258 db_printf(" (%d", number); |
259 p = (td != NULL) ? td->td_proc : NULL; |
|
188 if (p != NULL && 0 <= number && number < p->p_sysent->sv_size) { 189 f = p->p_sysent->sv_table[number].sy_call; 190 sym = db_search_symbol((db_addr_t)f, DB_STGY_ANY, &diff); 191 if (sym != DB_SYM_NULL && diff == 0) { 192 db_symbol_values(sym, &symname, NULL); 193 db_printf(", %s, %s", p->p_sysent->sv_name, symname); 194 } 195 } 196 db_printf(")"); 197} 198 199/* 200 * Figure out the next frame up in the call stack. 201 */ 202static void | 260 if (p != NULL && 0 <= number && number < p->p_sysent->sv_size) { 261 f = p->p_sysent->sv_table[number].sy_call; 262 sym = db_search_symbol((db_addr_t)f, DB_STGY_ANY, &diff); 263 if (sym != DB_SYM_NULL && diff == 0) { 264 db_symbol_values(sym, &symname, NULL); 265 db_printf(", %s, %s", p->p_sysent->sv_name, symname); 266 } 267 } 268 db_printf(")"); 269} 270 271/* 272 * Figure out the next frame up in the call stack. 273 */ 274static void |
203db_nextframe(fp, ip, p) 204 struct i386_frame **fp; /* in/out */ 205 db_addr_t *ip; /* out */ 206 struct proc *p; /* in */ | 275db_nextframe(struct i386_frame **fp, db_addr_t *ip, struct thread *td) |
207{ 208 struct trapframe *tf; 209 int frame_type; 210 int eip, esp, ebp; 211 db_expr_t offset; 212 c_db_sym_t sym; 213 const char *name; 214 --- 34 unchanged lines hidden (view full) --- 249 * current frame. 250 */ 251 if (frame_type == INTERRUPT) 252 tf = (struct trapframe *)((int)*fp + 12); 253 else 254 tf = (struct trapframe *)((int)*fp + 8); 255 256 if (INKERNEL((int) tf)) { | 276{ 277 struct trapframe *tf; 278 int frame_type; 279 int eip, esp, ebp; 280 db_expr_t offset; 281 c_db_sym_t sym; 282 const char *name; 283 --- 34 unchanged lines hidden (view full) --- 318 * current frame. 319 */ 320 if (frame_type == INTERRUPT) 321 tf = (struct trapframe *)((int)*fp + 12); 322 else 323 tf = (struct trapframe *)((int)*fp + 8); 324 325 if (INKERNEL((int) tf)) { |
257 esp = (ISPL(tf->tf_cs) == SEL_UPL) ? 258 tf->tf_esp : (int)&tf->tf_esp; | 326 esp = get_esp(tf); |
259 eip = tf->tf_eip; 260 ebp = tf->tf_ebp; 261 switch (frame_type) { 262 case TRAP: 263 db_printf("--- trap %#r", tf->tf_trapno); 264 break; 265 case SYSCALL: 266 db_printf("--- syscall"); | 327 eip = tf->tf_eip; 328 ebp = tf->tf_ebp; 329 switch (frame_type) { 330 case TRAP: 331 db_printf("--- trap %#r", tf->tf_trapno); 332 break; 333 case SYSCALL: 334 db_printf("--- syscall"); |
267 decode_syscall(tf->tf_eax, p); | 335 decode_syscall(tf->tf_eax, td); |
268 break; 269 case INTERRUPT: 270 db_printf("--- interrupt"); 271 break; 272 default: 273 panic("The moon has moved again."); 274 } 275 db_printf(", eip = %#r, esp = %#r, ebp = %#r ---\n", eip, 276 esp, ebp); 277 } 278 279 *ip = (db_addr_t) eip; 280 *fp = (struct i386_frame *) ebp; 281} 282 | 336 break; 337 case INTERRUPT: 338 db_printf("--- interrupt"); 339 break; 340 default: 341 panic("The moon has moved again."); 342 } 343 db_printf(", eip = %#r, esp = %#r, ebp = %#r ---\n", eip, 344 esp, ebp); 345 } 346 347 *ip = (db_addr_t) eip; 348 *fp = (struct i386_frame *) ebp; 349} 350 |
283void 284db_stack_trace_cmd(addr, have_addr, count, modif) 285 db_expr_t addr; 286 boolean_t have_addr; 287 db_expr_t count; 288 char *modif; | 351static int 352db_backtrace(struct thread *td, struct trapframe *tf, struct i386_frame *frame, 353 db_addr_t pc, int count) |
289{ | 354{ |
290 struct i386_frame *frame; 291 struct proc *p; 292 struct pcb *pcb; 293 struct thread *td; 294 db_addr_t callpc; 295 pid_t pid; | 355 struct i386_frame *actframe; 356#define MAXNARG 16 357 char *argnames[MAXNARG], **argnp = NULL; 358 const char *name; 359 int *argp; 360 db_expr_t offset; 361 c_db_sym_t sym; 362 int narg; 363 boolean_t first; |
296 297 if (count == -1) 298 count = 1024; 299 | 364 365 if (count == -1) 366 count = 1024; 367 |
300 if (!have_addr) { 301 td = curthread; 302 p = td->td_proc; 303 frame = (struct i386_frame *)ddb_regs.tf_ebp; 304 if (frame == NULL) 305 frame = (struct i386_frame *)(ddb_regs.tf_esp - 4); 306 callpc = (db_addr_t)ddb_regs.tf_eip; 307 } else if (!INKERNEL(addr)) { 308 pid = (addr % 16) + ((addr >> 4) % 16) * 10 + 309 ((addr >> 8) % 16) * 100 + ((addr >> 12) % 16) * 1000 + 310 ((addr >> 16) % 16) * 10000; 311 /* 312 * The pcb for curproc is not valid at this point, 313 * so fall back to the default case. 314 */ 315 if (pid == curthread->td_proc->p_pid) { 316 td = curthread; 317 p = td->td_proc; 318 frame = (struct i386_frame *)ddb_regs.tf_ebp; 319 if (frame == NULL) 320 frame = (struct i386_frame *) 321 (ddb_regs.tf_esp - 4); 322 callpc = (db_addr_t)ddb_regs.tf_eip; 323 } else { 324 325 /* sx_slock(&allproc_lock); */ 326 LIST_FOREACH(p, &allproc, p_list) { 327 if (p->p_pid == pid) 328 break; 329 } 330 /* sx_sunlock(&allproc_lock); */ 331 if (p == NULL) { 332 db_printf("pid %d not found\n", pid); 333 return; 334 } 335 if ((p->p_sflag & PS_INMEM) == 0) { 336 db_printf("pid %d swapped out\n", pid); 337 return; 338 } 339 pcb = FIRST_THREAD_IN_PROC(p)->td_pcb; /* XXXKSE */ 340 frame = (struct i386_frame *)pcb->pcb_ebp; 341 if (frame == NULL) 342 frame = (struct i386_frame *) 343 (pcb->pcb_esp - 4); 344 callpc = (db_addr_t)pcb->pcb_eip; 345 } 346 } else { 347 p = NULL; 348 frame = (struct i386_frame *)addr; 349 callpc = (db_addr_t)db_get_value((int)&frame->f_retaddr, 4, FALSE); 350 frame = frame->f_frame; 351 } 352 db_trace_one_stack(count, have_addr, p, frame, callpc); 353} 354 355void 356db_stack_thread(db_expr_t addr, boolean_t have_addr, 357 db_expr_t count, char *modif) 358{ 359 struct i386_frame *frame; 360 struct thread *td; 361 struct proc *p; 362 struct pcb *pcb; 363 db_addr_t callpc; 364 365 if (!have_addr) 366 return; 367 if (!INKERNEL(addr)) { 368 printf("bad thread address"); 369 return; 370 } 371 td = (struct thread *)addr; 372 /* quick sanity check */ 373 if ((p = td->td_proc) != td->td_ksegrp->kg_proc) 374 return; 375 if (TD_IS_SWAPPED(td)) { 376 db_printf("thread at %p swapped out\n", td); 377 return; 378 } 379 if (td == curthread) { 380 frame = (struct i386_frame *)ddb_regs.tf_ebp; 381 if (frame == NULL) 382 frame = (struct i386_frame *)(ddb_regs.tf_esp - 4); 383 callpc = (db_addr_t)ddb_regs.tf_eip; 384 } else { 385 pcb = td->td_pcb; 386 frame = (struct i386_frame *)pcb->pcb_ebp; 387 if (frame == NULL) 388 frame = (struct i386_frame *) (pcb->pcb_esp - 4); 389 callpc = (db_addr_t)pcb->pcb_eip; 390 } 391 db_trace_one_stack(count, have_addr, p, frame, callpc); 392} 393 394static void 395db_trace_one_stack(int count, boolean_t have_addr, 396 struct proc *p, struct i386_frame *frame, db_addr_t callpc) 397{ 398 int *argp; 399 boolean_t first; 400 | |
401 first = TRUE; 402 while (count--) { | 368 first = TRUE; 369 while (count--) { |
403 struct i386_frame *actframe; 404 int narg; 405 const char * name; 406 db_expr_t offset; 407 c_db_sym_t sym; 408#define MAXNARG 16 409 char *argnames[MAXNARG], **argnp = NULL; 410 411 sym = db_search_symbol(callpc, DB_STGY_ANY, &offset); | 370 sym = db_search_symbol(pc, DB_STGY_ANY, &offset); |
412 db_symbol_values(sym, &name, NULL); 413 414 /* 415 * Attempt to determine a (possibly fake) frame that gives 416 * the caller's pc. It may differ from `frame' if the 417 * current function never sets up a standard frame or hasn't 418 * set one up yet or has just discarded one. The last two 419 * cases can be guessed fairly reliably for code generated 420 * by gcc. The first case is too much trouble to handle in 421 * general because the amount of junk on the stack depends 422 * on the pc (the special handling of "calltrap", etc. in 423 * db_nextframe() works because the `next' pc is special). 424 */ 425 actframe = frame; 426 if (first) { | 371 db_symbol_values(sym, &name, NULL); 372 373 /* 374 * Attempt to determine a (possibly fake) frame that gives 375 * the caller's pc. It may differ from `frame' if the 376 * current function never sets up a standard frame or hasn't 377 * set one up yet or has just discarded one. The last two 378 * cases can be guessed fairly reliably for code generated 379 * by gcc. The first case is too much trouble to handle in 380 * general because the amount of junk on the stack depends 381 * on the pc (the special handling of "calltrap", etc. in 382 * db_nextframe() works because the `next' pc is special). 383 */ 384 actframe = frame; 385 if (first) { |
427 if (!have_addr) { | 386 if (tf != NULL) { |
428 int instr; 429 | 387 int instr; 388 |
430 instr = db_get_value(callpc, 4, FALSE); 431 if ((instr & 0x00ffffff) == 0x00e58955) { | 389 instr = db_get_value(pc, 4, FALSE); 390 if ((instr & 0xffffff) == 0x00e58955) { |
432 /* pushl %ebp; movl %esp, %ebp */ | 391 /* pushl %ebp; movl %esp, %ebp */ |
433 actframe = (struct i386_frame *) 434 (ddb_regs.tf_esp - 4); 435 } else if ((instr & 0x0000ffff) == 0x0000e589) { | 392 actframe = (void *)(get_esp(tf) - 4); 393 } else if ((instr & 0xffff) == 0x0000e589) { |
436 /* movl %esp, %ebp */ | 394 /* movl %esp, %ebp */ |
437 actframe = (struct i386_frame *) 438 ddb_regs.tf_esp; 439 if (ddb_regs.tf_ebp == 0) { 440 /* Fake caller's frame better. */ | 395 actframe = (void *)get_esp(tf); 396 if (tf->tf_ebp == 0) { 397 /* Fake frame better. */ |
441 frame = actframe; 442 } | 398 frame = actframe; 399 } |
443 } else if ((instr & 0x000000ff) == 0x000000c3) { | 400 } else if ((instr & 0xff) == 0x000000c3) { |
444 /* ret */ | 401 /* ret */ |
445 actframe = (struct i386_frame *) 446 (ddb_regs.tf_esp - 4); | 402 actframe = (void *)(get_esp(tf) - 4); |
447 } else if (offset == 0) { | 403 } else if (offset == 0) { |
448 /* Probably a symbol in assembler code. */ 449 actframe = (struct i386_frame *) 450 (ddb_regs.tf_esp - 4); | 404 /* Probably an assembler symbol. */ 405 actframe = (void *)(get_esp(tf) - 4); |
451 } 452 } else if (strcmp(name, "fork_trampoline") == 0) { 453 /* 454 * Don't try to walk back on a stack for a 455 * process that hasn't actually been run yet. 456 */ | 406 } 407 } else if (strcmp(name, "fork_trampoline") == 0) { 408 /* 409 * Don't try to walk back on a stack for a 410 * process that hasn't actually been run yet. 411 */ |
457 db_print_stack_entry(name, 0, 0, 0, callpc); | 412 db_print_stack_entry(name, 0, 0, 0, pc); |
458 break; 459 } 460 first = FALSE; 461 } 462 463 argp = &actframe->f_arg0; 464 narg = MAXNARG; 465 if (sym != NULL && db_sym_numargs(sym, &narg, argnames)) { 466 argnp = argnames; 467 } else { 468 narg = db_numargs(frame); 469 } 470 | 413 break; 414 } 415 first = FALSE; 416 } 417 418 argp = &actframe->f_arg0; 419 narg = MAXNARG; 420 if (sym != NULL && db_sym_numargs(sym, &narg, argnames)) { 421 argnp = argnames; 422 } else { 423 narg = db_numargs(frame); 424 } 425 |
471 db_print_stack_entry(name, narg, argnp, argp, callpc); | 426 db_print_stack_entry(name, narg, argnp, argp, pc); |
472 473 if (actframe != frame) { 474 /* `frame' belongs to caller. */ | 427 428 if (actframe != frame) { 429 /* `frame' belongs to caller. */ |
475 callpc = (db_addr_t) | 430 pc = (db_addr_t) |
476 db_get_value((int)&actframe->f_retaddr, 4, FALSE); 477 continue; 478 } 479 | 431 db_get_value((int)&actframe->f_retaddr, 4, FALSE); 432 continue; 433 } 434 |
480 db_nextframe(&frame, &callpc, p); | 435 db_nextframe(&frame, &pc, td); |
481 | 436 |
482 if (INKERNEL((int) callpc) && !INKERNEL((int) frame)) { 483 sym = db_search_symbol(callpc, DB_STGY_ANY, &offset); | 437 if (INKERNEL((int)pc) && !INKERNEL((int) frame)) { 438 sym = db_search_symbol(pc, DB_STGY_ANY, &offset); |
484 db_symbol_values(sym, &name, NULL); | 439 db_symbol_values(sym, &name, NULL); |
485 db_print_stack_entry(name, 0, 0, 0, callpc); | 440 db_print_stack_entry(name, 0, 0, 0, pc); |
486 break; 487 } 488 if (!INKERNEL((int) frame)) { 489 break; 490 } 491 } | 441 break; 442 } 443 if (!INKERNEL((int) frame)) { 444 break; 445 } 446 } |
447 448 return (0); |
|
492} 493 494void | 449} 450 451void |
495db_print_backtrace(void) | 452db_stack_trace_cmd(db_expr_t addr, boolean_t have_addr, db_expr_t count, 453 char *modif) |
496{ | 454{ |
455 struct thread *td; 456 457 td = (have_addr) ? kdb_thr_lookup(addr) : kdb_thread; 458 if (td == NULL) { 459 db_printf("Thread %d not found\n", addr); 460 return; 461 } 462 db_trace_thread(td, count); 463} 464 465void 466db_trace_self(void) 467{ 468 struct i386_frame *frame; 469 db_addr_t callpc; |
|
497 register_t ebp; 498 499 __asm __volatile("movl %%ebp,%0" : "=r" (ebp)); | 470 register_t ebp; 471 472 __asm __volatile("movl %%ebp,%0" : "=r" (ebp)); |
500 db_stack_trace_cmd(ebp, 1, -1, NULL); | 473 frame = (struct i386_frame *)ebp; 474 callpc = (db_addr_t)db_get_value((int)&frame->f_retaddr, 4, FALSE); 475 frame = frame->f_frame; 476 db_backtrace(curthread, NULL, frame, callpc, -1); |
501} 502 | 477} 478 |
503#define DB_DRX_FUNC(reg) \ 504int \ 505db_ ## reg (vp, valuep, op) \ 506 struct db_variable *vp; \ 507 db_expr_t * valuep; \ 508 int op; \ 509{ \ 510 if (op == DB_VAR_GET) \ 511 *valuep = r ## reg (); \ 512 else \ 513 load_ ## reg (*valuep); \ 514 return (0); \ 515} | 479int 480db_trace_thread(struct thread *thr, int count) 481{ 482 struct pcb *ctx; |
516 | 483 |
517DB_DRX_FUNC(dr0) 518DB_DRX_FUNC(dr1) 519DB_DRX_FUNC(dr2) 520DB_DRX_FUNC(dr3) 521DB_DRX_FUNC(dr4) 522DB_DRX_FUNC(dr5) 523DB_DRX_FUNC(dr6) 524DB_DRX_FUNC(dr7) | 484 ctx = kdb_thr_ctx(thr); 485 return (db_backtrace(thr, NULL, (struct i386_frame *)ctx->pcb_ebp, 486 ctx->pcb_eip, count)); 487} |
525 526int 527i386_set_watch(watchnum, watchaddr, size, access, d) 528 int watchnum; 529 unsigned int watchaddr; 530 int size; 531 int access; 532 struct dbreg * d; --- 178 unchanged lines hidden --- | 488 489int 490i386_set_watch(watchnum, watchaddr, size, access, d) 491 int watchnum; 492 unsigned int watchaddr; 493 int size; 494 int access; 495 struct dbreg * d; --- 178 unchanged lines hidden --- |