X-Git-Url: https://git.saurik.com/apple/xnu.git/blobdiff_plain/de355530ae67247cbd0da700edb3a2a1dae884c2..0c530ab8987f0ae6a1a3d9284f40182b88852816:/osfmk/i386/db_trace.c diff --git a/osfmk/i386/db_trace.c b/osfmk/i386/db_trace.c index 41349103f..49d6a465e 100644 --- a/osfmk/i386/db_trace.c +++ b/osfmk/i386/db_trace.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2000 Apple Computer, Inc. All rights reserved. + * Copyright (c) 2000-2005 Apple Computer, Inc. All rights reserved. * * @APPLE_LICENSE_HEADER_START@ * @@ -61,6 +61,13 @@ #include #include #include +#include + +#include +#include +#include +#include +#include #include #include @@ -70,37 +77,17 @@ #include extern jmp_buf_t *db_recover; -extern struct i386_saved_state *saved_state[]; +struct x86_kernel_state32 ddb_null_kregs; +extern kmod_info_t *kmod; -struct i386_kernel_state ddb_null_kregs; /* * Stack trace. */ -extern vm_offset_t vm_min_inks_addr; /* set by db_clone_symtabXXX */ -#define INKSERVER(va) (((vm_offset_t)(va)) >= vm_min_inks_addr) - -#if NCPUS > 1 -extern vm_offset_t interrupt_stack[]; -#define ININTSTACK(va) \ - (((vm_offset_t)(va)) >= interrupt_stack[cpu_number()] &&\ - (((vm_offset_t)(va)) < interrupt_stack[cpu_number()] + \ - INTSTACK_SIZE)) -#else /* NCPUS > 1 */ -extern char intstack[]; -#define ININTSTACK(va) \ - (((vm_offset_t)(va)) >= (vm_offset_t)intstack && \ - (((vm_offset_t)(va)) < ((vm_offset_t)&intstack) + \ - INTSTACK_SIZE)) -#endif /* NCPUS > 1 */ - -#define INKERNELSTACK(va, th) \ - (th == THR_ACT_NULL || \ - (((vm_offset_t)(va)) >= th->thread->kernel_stack && \ - (((vm_offset_t)(va)) < th->thread->kernel_stack + \ - KERNEL_STACK_SIZE)) || \ - ININTSTACK(va)) +#define INKERNELSTACK(va, th) 1 + +#define DB_NUMARGS_MAX 5 struct i386_frame { struct i386_frame *f_frame; @@ -121,20 +108,20 @@ boolean_t db_trace_symbols_found = FALSE; struct i386_kregs { char *name; - int offset; + unsigned int offset; } i386_kregs[] = { - { "ebx", (int)(&((struct i386_kernel_state *)0)->k_ebx) }, - { "esp", (int)(&((struct i386_kernel_state *)0)->k_esp) }, - { "ebp", (int)(&((struct i386_kernel_state *)0)->k_ebp) }, - { "edi", (int)(&((struct i386_kernel_state *)0)->k_edi) }, - { "esi", (int)(&((struct i386_kernel_state *)0)->k_esi) }, - { "eip", (int)(&((struct i386_kernel_state *)0)->k_eip) }, - { 0 }, + { "ebx", (unsigned int)(&((struct x86_kernel_state32 *)0)->k_ebx) }, + { "esp", (unsigned int)(&((struct x86_kernel_state32 *)0)->k_esp) }, + { "ebp", (unsigned int)(&((struct x86_kernel_state32 *)0)->k_ebp) }, + { "edi", (unsigned int)(&((struct x86_kernel_state32 *)0)->k_edi) }, + { "esi", (unsigned int)(&((struct x86_kernel_state32 *)0)->k_esi) }, + { "eip", (unsigned int)(&((struct x86_kernel_state32 *)0)->k_eip) }, + { 0 } }; /* Forward */ -extern int * db_lookup_i386_kreg( +extern unsigned int * db_lookup_i386_kreg( char *name, int *kregp); extern int db_i386_reg_value( @@ -151,7 +138,7 @@ extern void db_nextframe( struct i386_frame **fp, db_addr_t *ip, int frame_type, - thread_act_t thr_act); + thread_t thr_act); extern int _setjmp( jmp_buf_t * jb); @@ -159,26 +146,26 @@ extern int _setjmp( * Machine register set. */ struct db_variable db_regs[] = { - { "cs", (int *)&ddb_regs.cs, db_i386_reg_value, 0, 0, 0, 0, TRUE }, - { "ds", (int *)&ddb_regs.ds, db_i386_reg_value, 0, 0, 0, 0, TRUE }, - { "es", (int *)&ddb_regs.es, db_i386_reg_value, 0, 0, 0, 0, TRUE }, - { "fs", (int *)&ddb_regs.fs, db_i386_reg_value, 0, 0, 0, 0, TRUE }, - { "gs", (int *)&ddb_regs.gs, db_i386_reg_value, 0, 0, 0, 0, TRUE }, - { "ss", (int *)&ddb_regs.ss, db_i386_reg_value, 0, 0, 0, 0, TRUE }, - { "eax",(int *)&ddb_regs.eax, db_i386_reg_value, 0, 0, 0, 0, TRUE }, - { "ecx",(int *)&ddb_regs.ecx, db_i386_reg_value, 0, 0, 0, 0, TRUE }, - { "edx",(int *)&ddb_regs.edx, db_i386_reg_value, 0, 0, 0, 0, TRUE }, - { "ebx",(int *)&ddb_regs.ebx, db_i386_reg_value, 0, 0, 0, 0, TRUE }, - { "esp",(int *)&ddb_regs.uesp,db_i386_reg_value, 0, 0, 0, 0, TRUE }, - { "ebp",(int *)&ddb_regs.ebp, db_i386_reg_value, 0, 0, 0, 0, TRUE }, - { "esi",(int *)&ddb_regs.esi, db_i386_reg_value, 0, 0, 0, 0, TRUE }, - { "edi",(int *)&ddb_regs.edi, db_i386_reg_value, 0, 0, 0, 0, TRUE }, - { "eip",(int *)&ddb_regs.eip, db_i386_reg_value, 0, 0, 0, 0, TRUE }, - { "efl",(int *)&ddb_regs.efl, db_i386_reg_value, 0, 0, 0, 0, TRUE }, + { "cs", (unsigned int *)&ddb_regs.cs, db_i386_reg_value, 0, 0, 0, 0, TRUE, 0, 0, (int *)0, 0 }, + { "ds", (unsigned int *)&ddb_regs.ds, db_i386_reg_value, 0, 0, 0, 0, TRUE, 0, 0, (int *)0, 0 }, + { "es", (unsigned int *)&ddb_regs.es, db_i386_reg_value, 0, 0, 0, 0, TRUE, 0, 0, (int *)0, 0 }, + { "fs", (unsigned int *)&ddb_regs.fs, db_i386_reg_value, 0, 0, 0, 0, TRUE, 0, 0, (int *)0, 0 }, + { "gs", (unsigned int *)&ddb_regs.gs, db_i386_reg_value, 0, 0, 0, 0, TRUE, 0, 0, (int *)0, 0 }, + { "ss", (unsigned int *)&ddb_regs.ss, db_i386_reg_value, 0, 0, 0, 0, TRUE, 0, 0, (int *)0, 0 }, + { "eax",(unsigned int *)&ddb_regs.eax, db_i386_reg_value, 0, 0, 0, 0, TRUE, 0, 0, (int *)0, 0 }, + { "ecx",(unsigned int *)&ddb_regs.ecx, db_i386_reg_value, 0, 0, 0, 0, TRUE, 0, 0, (int *)0, 0 }, + { "edx",(unsigned int *)&ddb_regs.edx, db_i386_reg_value, 0, 0, 0, 0, TRUE, 0, 0, (int *)0, 0 }, + { "ebx",(unsigned int *)&ddb_regs.ebx, db_i386_reg_value, 0, 0, 0, 0, TRUE, 0, 0, (int *)0, 0 }, + { "esp",(unsigned int *)&ddb_regs.uesp,db_i386_reg_value, 0, 0, 0, 0, TRUE, 0, 0, (int *)0, 0 }, + { "ebp",(unsigned int *)&ddb_regs.ebp, db_i386_reg_value, 0, 0, 0, 0, TRUE, 0, 0, (int *)0, 0 }, + { "esi",(unsigned int *)&ddb_regs.esi, db_i386_reg_value, 0, 0, 0, 0, TRUE, 0, 0, (int *)0, 0 }, + { "edi",(unsigned int *)&ddb_regs.edi, db_i386_reg_value, 0, 0, 0, 0, TRUE, 0, 0, (int *)0, 0 }, + { "eip",(unsigned int *)&ddb_regs.eip, db_i386_reg_value, 0, 0, 0, 0, TRUE, 0, 0, (int *)0, 0 }, + { "efl",(unsigned int *)&ddb_regs.efl, db_i386_reg_value, 0, 0, 0, 0, TRUE, 0, 0, (int *)0, 0 } }; struct db_variable *db_eregs = db_regs + sizeof(db_regs)/sizeof(db_regs[0]); -int * +unsigned int * db_lookup_i386_kreg( char *name, int *kregp) @@ -187,7 +174,7 @@ db_lookup_i386_kreg( for (kp = i386_kregs; kp->name; kp++) { if (strcmp(name, kp->name) == 0) - return((int *)((int)kregp + kp->offset)); + return((unsigned int *)((int)kregp + kp->offset)); } return(0); } @@ -200,52 +187,48 @@ db_i386_reg_value( db_var_aux_param_t ap) { extern char etext; - int *dp = 0; + unsigned int *dp = 0; db_expr_t null_reg = 0; - register thread_act_t thr_act = ap->thr_act; - extern unsigned int_stack_high; - int cpu; + register thread_t thr_act = ap->thr_act; if (db_option(ap->modif, 'u')) { - if (thr_act == THR_ACT_NULL) { - if ((thr_act = current_act()) == THR_ACT_NULL) + if (thr_act == THREAD_NULL) { + if ((thr_act = current_thread()) == THREAD_NULL) db_error("no user registers\n"); } - if (thr_act == current_act()) { + if (thr_act == current_thread()) { if (IS_USER_TRAP(&ddb_regs, &etext)) dp = vp->valuep; - else if (ddb_regs.ebp < int_stack_high) - db_error("cannot get/set user registers in nested interrupt\n"); } } else { - if (thr_act == THR_ACT_NULL || thr_act == current_act()) { + if (thr_act == THREAD_NULL || thr_act == current_thread()) { dp = vp->valuep; } else { - if (thr_act->thread && - !(thr_act->thread->state & TH_STACK_HANDOFF) && - thr_act->thread->kernel_stack) { + if (thr_act && + (thr_act->continuation != THREAD_CONTINUE_NULL) && + thr_act->kernel_stack) { int cpu; - for (cpu = 0; cpu < NCPUS; cpu++) { - if (machine_slot[cpu].running == TRUE && - cpu_data[cpu].active_thread == thr_act->thread && saved_state[cpu]) { - dp = (int *) (((int)saved_state[cpu]) + - (((int) vp->valuep) - - (int) &ddb_regs)); + for (cpu = 0; cpu < real_ncpus; cpu++) { + if (cpu_datap(cpu)->cpu_running == TRUE && + cpu_datap(cpu)->cpu_active_thread == thr_act && cpu_datap(cpu)->cpu_kdb_saved_state) { + dp = (unsigned int *) (((unsigned int)cpu_datap(cpu)->cpu_kdb_saved_state) + + (((unsigned int) vp->valuep) - + (unsigned int) &ddb_regs)); break; } } - if (dp == 0 && thr_act && thr_act->thread) + if (dp == 0 && thr_act) dp = db_lookup_i386_kreg(vp->name, - (int *)(STACK_IKS(thr_act->thread->kernel_stack))); + (unsigned int *)(STACK_IKS(thr_act->kernel_stack))); if (dp == 0) dp = &null_reg; - } else if (thr_act->thread && - (thr_act->thread->state&TH_STACK_HANDOFF)){ - /* only EIP is valid */ - if (vp->valuep == (int *) &ddb_regs.eip) { - dp = (int *)(&thr_act->thread->continuation); - } else { + } else if (thr_act && + (thr_act->continuation != THREAD_CONTINUE_NULL)) { + /* only EIP is valid */ + if (vp->valuep == (unsigned int *) &ddb_regs.eip) { + dp = (unsigned int *)(&thr_act->continuation); + } else { dp = &null_reg; } } @@ -255,21 +238,21 @@ db_i386_reg_value( int cpu; if (!db_option(ap->modif, 'u')) { - for (cpu = 0; cpu < NCPUS; cpu++) { - if (machine_slot[cpu].running == TRUE && - cpu_data[cpu].active_thread == thr_act->thread && saved_state[cpu]) { - dp = (int *) (((int)saved_state[cpu]) + - (((int) vp->valuep) - - (int) &ddb_regs)); + for (cpu = 0; cpu < real_ncpus; cpu++) { + if (cpu_datap(cpu)->cpu_running == TRUE && + cpu_datap(cpu)->cpu_active_thread == thr_act && cpu_datap(cpu)->cpu_kdb_saved_state) { + dp = (unsigned int *) (((unsigned int)cpu_datap(cpu)->cpu_kdb_saved_state) + + (((unsigned int) vp->valuep) - + (unsigned int) &ddb_regs)); break; } } } if (dp == 0) { - if (!thr_act || thr_act->mact.pcb == 0) + if (!thr_act || thr_act->machine.pcb == 0) db_error("no pcb\n"); - dp = (int *)((int)(&thr_act->mact.pcb->iss) + - ((int)vp->valuep - (int)&ddb_regs)); + dp = (unsigned int *)((unsigned int)(thr_act->machine.pcb->iss) + + ((unsigned int)vp->valuep - (unsigned int)&ddb_regs)); } } if (flag == DB_VAR_SET) @@ -372,35 +355,35 @@ db_nextframe( struct i386_frame **fp, /* in/out */ db_addr_t *ip, /* out */ int frame_type, /* in */ - thread_act_t thr_act) /* in */ + thread_t thr_act) /* in */ { + x86_saved_state32_t *iss32; extern char * trap_type[]; extern int TRAP_TYPES; - struct i386_saved_state *saved_regs; struct interrupt_frame *ifp; - struct i386_interrupt_state *isp; - task_t task = (thr_act != THR_ACT_NULL)? thr_act->task: TASK_NULL; + task_t task = (thr_act != THREAD_NULL)? thr_act->task: TASK_NULL; switch(frame_type) { case TRAP: /* * We know that trap() has 1 argument and we know that - * it is an (strcut i386_saved_state *). + * it is an (x86_saved_state32_t *). */ - saved_regs = (struct i386_saved_state *) - db_get_task_value((int)&((*fp)->f_arg0),4,FALSE,task); - if (saved_regs->trapno >= 0 && saved_regs->trapno < TRAP_TYPES) { - db_printf(">>>>> %s trap at ", - trap_type[saved_regs->trapno]); + iss32 = (x86_saved_state32_t *) + db_get_task_value((int)&((*fp)->f_arg0),4,FALSE,task); + + if (iss32->trapno >= 0 && iss32->trapno < TRAP_TYPES) { + db_printf(">>>>> %s trap at ", + trap_type[iss32->trapno]); } else { - db_printf(">>>>> trap (number %d) at ", - saved_regs->trapno & 0xffff); + db_printf(">>>>> trap (number %d) at ", + iss32->trapno & 0xffff); } - db_task_printsym(saved_regs->eip, DB_STGY_PROC, task); + db_task_printsym(iss32->eip, DB_STGY_PROC, task); db_printf(" <<<<<\n"); - *fp = (struct i386_frame *)saved_regs->ebp; - *ip = (db_addr_t)saved_regs->eip; + *fp = (struct i386_frame *)iss32->ebp; + *ip = (db_addr_t)iss32->eip; break; case INTERRUPT: if (*lfp == 0) { @@ -410,19 +393,21 @@ db_nextframe( db_printf(">>>>> interrupt at "); ifp = (struct interrupt_frame *)(*lfp); *fp = ifp->if_frame; - if (ifp->if_iretaddr == db_return_to_iret_symbol_value) - *ip = ((struct i386_interrupt_state *) ifp->if_edx)->eip; - else - *ip = (db_addr_t) ifp->if_eip; + if (ifp->if_iretaddr == db_return_to_iret_symbol_value) { + *ip = ((x86_saved_state32_t *) ifp->if_edx)->eip; + } else + *ip = (db_addr_t) ifp->if_eip; db_task_printsym(*ip, DB_STGY_PROC, task); db_printf(" <<<<<\n"); break; case SYSCALL: - if (thr_act != THR_ACT_NULL && thr_act->mact.pcb) { - *ip = (db_addr_t) thr_act->mact.pcb->iss.eip; - *fp = (struct i386_frame *) thr_act->mact.pcb->iss.ebp; - break; + if (thr_act != THREAD_NULL && thr_act->machine.pcb) { + iss32 = (x86_saved_state32_t *)thr_act->machine.pcb->iss; + + *ip = (db_addr_t)(iss32->eip); + *fp = (struct i386_frame *)(iss32->ebp); } + break; /* falling down for unknown case */ default: miss_frame: @@ -443,6 +428,7 @@ db_stack_trace_cmd( char *modif) { struct i386_frame *frame, *lastframe; + x86_saved_state32_t *iss32; int *argp; db_addr_t callpc, lastcallpc; int frame_type; @@ -453,7 +439,7 @@ db_stack_trace_cmd( char *filename; int linenum; task_t task; - thread_act_t th, top_act; + thread_t th, top_act; int user_frame; int frame_count; jmp_buf_t *prev; @@ -483,30 +469,30 @@ db_stack_trace_cmd( if (!have_addr && !trace_thread) { have_addr = TRUE; trace_thread = TRUE; - act_list = &(current_task()->thr_acts); + act_list = &(current_task()->threads); addr = (db_expr_t) queue_first(act_list); } else if (trace_thread) { if (have_addr) { - if (!db_check_act_address_valid((thread_act_t)addr)) { + if (!db_check_act_address_valid((thread_t)addr)) { if (db_lookup_task((task_t)addr) == -1) return; - act_list = &(((task_t)addr)->thr_acts); + act_list = &(((task_t)addr)->threads); addr = (db_expr_t) queue_first(act_list); } else { - act_list = &(((thread_act_t)addr)->task->thr_acts); - thcount = db_lookup_task_act(((thread_act_t)addr)->task, - (thread_act_t)addr); + act_list = &(((thread_t)addr)->task->threads); + thcount = db_lookup_task_act(((thread_t)addr)->task, + (thread_t)addr); } } else { th = db_default_act; - if (th == THR_ACT_NULL) - th = current_act(); - if (th == THR_ACT_NULL) { + if (th == THREAD_NULL) + th = current_thread(); + if (th == THREAD_NULL) { db_printf("no active thr_act\n"); return; } have_addr = TRUE; - act_list = &th->task->thr_acts; + act_list = &th->task->threads; addr = (db_expr_t) queue_first(act_list); } } @@ -516,7 +502,7 @@ db_stack_trace_cmd( count = 65535; next_thread: - top_act = THR_ACT_NULL; + top_act = THREAD_NULL; user_frame = 0; frame_count = count; @@ -524,87 +510,84 @@ db_stack_trace_cmd( if (!have_addr && !trace_thread) { frame = (struct i386_frame *)ddb_regs.ebp; callpc = (db_addr_t)ddb_regs.eip; - th = current_act(); - task = (th != THR_ACT_NULL)? th->task: TASK_NULL; + th = current_thread(); + task = (th != THREAD_NULL)? th->task: TASK_NULL; + db_printf("thread 0x%x, current_thread() is 0x%x, ebp is 0x%x, eip is 0x%x\n", th, current_thread(), ddb_regs.ebp, ddb_regs.eip); } else if (trace_thread) { if (have_addr) { - th = (thread_act_t) addr; - if (!db_check_act_address_valid(th)) - return; + th = (thread_t) addr; + if (!db_check_act_address_valid(th)) { + return; + } } else { th = db_default_act; - if (th == THR_ACT_NULL) - th = current_act(); - if (th == THR_ACT_NULL) { + if (th == THREAD_NULL) + th = current_thread(); + if (th == THREAD_NULL) { db_printf("no active thread\n"); return; } } if (trace_all_threads) db_printf("---------- Thread 0x%x (#%d of %d) ----------\n", - addr, thcount, th->task->thr_act_count); + addr, thcount, th->task->thread_count); next_activation: user_frame = 0; - +// kprintf("th is %x, current_thread() is %x, ddb_regs.ebp is %x ddb_regs.eip is %x\n", th, current_thread(), ddb_regs.ebp, ddb_regs.eip); task = th->task; - if (th == current_act()) { + if (th == current_thread()) { frame = (struct i386_frame *)ddb_regs.ebp; callpc = (db_addr_t)ddb_regs.eip; } else { - if (th->mact.pcb == 0) { + if (th->machine.pcb == 0) { db_printf("thread has no pcb\n"); return; } - if (!th->thread) { - register struct i386_saved_state *iss = - &th->mact.pcb->iss; - + if (!th) { db_printf("thread has no shuttle\n"); -#if 0 - frame = (struct i386_frame *) (iss->ebp); - callpc = (db_addr_t) (iss->eip); -#else + goto thread_done; -#endif } - else if ((th->thread->state & TH_STACK_HANDOFF) || - th->thread->kernel_stack == 0) { - register struct i386_saved_state *iss = - &th->mact.pcb->iss; + else if ( (th->continuation != THREAD_CONTINUE_NULL) || + th->kernel_stack == 0) { db_printf("Continuation "); - db_task_printsym((db_expr_t)th->thread->continuation, + db_task_printsym((db_expr_t)th->continuation, DB_STGY_PROC, task); db_printf("\n"); - frame = (struct i386_frame *) (iss->ebp); - callpc = (db_addr_t) (iss->eip); + + iss32 = (x86_saved_state32_t *)th->machine.pcb->iss; + + frame = (struct i386_frame *) (iss32->ebp); + callpc = (db_addr_t) (iss32->eip); + } else { int cpu; - for (cpu = 0; cpu < NCPUS; cpu++) { - if (machine_slot[cpu].running == TRUE && - cpu_data[cpu].active_thread == th->thread && - saved_state[cpu]) { + for (cpu = 0; cpu < real_ncpus; cpu++) { + if (cpu_datap(cpu)->cpu_running == TRUE && + cpu_datap(cpu)->cpu_active_thread == th && + cpu_datap(cpu)->cpu_kdb_saved_state) { break; } } - if (top_act != THR_ACT_NULL) { + if (top_act != THREAD_NULL) { /* * Trying to get the backtrace of an activation * which is not the top_most one in the RPC chain: * use the activation's pcb. */ - register struct i386_saved_state *iss = - &th->mact.pcb->iss; - frame = (struct i386_frame *) (iss->ebp); - callpc = (db_addr_t) (iss->eip); + iss32 = (x86_saved_state32_t *)th->machine.pcb->iss; + + frame = (struct i386_frame *) (iss32->ebp); + callpc = (db_addr_t) (iss32->eip); } else { - if (cpu == NCPUS) { - register struct i386_kernel_state *iks; + if (cpu == real_ncpus) { + register struct x86_kernel_state32 *iks; int r; - iks = STACK_IKS(th->thread->kernel_stack); + iks = STACK_IKS(th->kernel_stack); prev = db_recover; if ((r = _setjmp(db_recover = &db_jmp_buf)) == 0) { frame = (struct i386_frame *) (iks->k_ebp); @@ -626,17 +609,19 @@ db_stack_trace_cmd( } else { db_printf(">>>>> active on cpu %d <<<<<\n", cpu); - frame = (struct i386_frame *) - saved_state[cpu]->ebp; - callpc = (db_addr_t) saved_state[cpu]->eip; + + iss32 = (x86_saved_state32_t *)cpu_datap(cpu)->cpu_kdb_saved_state; + + frame = (struct i386_frame *) (iss32->ebp); + callpc = (db_addr_t) (iss32->eip); } } } } } else { frame = (struct i386_frame *)addr; - th = (db_default_act)? db_default_act: current_act(); - task = (th != THR_ACT_NULL)? th->task: TASK_NULL; + th = (db_default_act)? db_default_act: current_thread(); + task = (th != THREAD_NULL)? th->task: TASK_NULL; callpc = (db_addr_t)db_get_task_value((int)&frame->f_retaddr, 4, FALSE, @@ -648,19 +633,18 @@ db_stack_trace_cmd( if (kernel_only) goto thread_done; user_frame++; - } else if (INKSERVER(callpc) && INKSERVER(frame)) { - db_printf(">>>>> INKserver space <<<<<\n"); } lastframe = 0; lastcallpc = (db_addr_t) 0; while (frame_count-- && frame != 0) { - int narg; + int narg = DB_NUMARGS_MAX; char * name; db_expr_t offset; db_addr_t call_func = 0; int r; - + db_addr_t off; + db_symbol_values(NULL, db_search_task_symbol_and_line( callpc, @@ -671,15 +655,22 @@ db_stack_trace_cmd( (user_frame) ? task : 0, &narg), &name, (db_expr_t *)&call_func); + if ( name == NULL) { + db_find_task_sym_and_offset(callpc, + &name, &off, (user_frame) ? task : 0); + offset = (db_expr_t) off; + } + if (user_frame == 0) { - if (call_func == db_user_trap_symbol_value || + if (call_func && call_func == db_user_trap_symbol_value || call_func == db_kernel_trap_symbol_value) { frame_type = TRAP; narg = 1; - } else if (call_func == db_interrupt_symbol_value) { + } else if (call_func && + call_func == db_interrupt_symbol_value) { frame_type = INTERRUPT; goto next_frame; - } else if (call_func == db_syscall_symbol_value) { + } else if (call_func && call_func == db_syscall_symbol_value) { frame_type = SYSCALL; goto next_frame; } else { @@ -764,13 +755,13 @@ db_stack_trace_cmd( next_frame: lastcallpc = callpc; db_nextframe(&lastframe, &frame, &callpc, frame_type, - (user_frame) ? th : THR_ACT_NULL); + (user_frame) ? th : THREAD_NULL); if (frame == 0) { - if (th->lower != THR_ACT_NULL) { - if (top_act == THR_ACT_NULL) + if (th->task_threads.prev != THREAD_NULL) { + if (top_act == THREAD_NULL) top_act = th; - th = th->lower; + th = th->task_threads.prev; db_printf(">>>>> next activation 0x%x ($task%d.%d) <<<<<\n", th, db_lookup_task(th->task), @@ -787,14 +778,10 @@ db_stack_trace_cmd( db_printf(">>>>> user space <<<<<\n"); if (kernel_only) break; - } else if ((!INKSERVER(lastframe) || !INKSERVER(lastcallpc)) && - (INKSERVER(callpc) && INKSERVER(frame))) { - db_printf(">>>>> inkserver space <<<<<\n"); } if (frame <= lastframe) { if ((INKERNELSTACK(lastframe, th) && - !INKERNELSTACK(frame, th)) || - (INKSERVER(lastframe) ^ INKSERVER(frame))) + !INKERNELSTACK(frame, th))) continue; db_printf("Bad frame pointer: 0x%x\n", frame); break; @@ -803,9 +790,9 @@ db_stack_trace_cmd( thread_done: if (trace_all_threads) { - if (top_act != THR_ACT_NULL) + if (top_act != THREAD_NULL) th = top_act; - th = (thread_act_t) queue_next(&th->thr_acts); + th = (thread_t) queue_next(&th->task_threads); if (! queue_end(act_list, (queue_entry_t) th)) { db_printf("\n"); addr = (db_expr_t) th; @@ -815,3 +802,63 @@ db_stack_trace_cmd( } } } + +extern int kdp_vm_read(caddr_t, caddr_t, unsigned int ); +extern boolean_t kdp_trans_off; +/* + * Print out 256 bytes of real storage + * + * dr [entaddr] + */ +void db_display_real(db_expr_t addr, __unused int have_addr, __unused db_expr_t count, __unused char * modif) { + + int i; + unsigned int xbuf[8]; + unsigned read_result = 0; +/* Print 256 bytes */ + for(i=0; i<8; i++) { + +/* Do a physical read using kdp_vm_read(), rather than replicating the same + * facility + */ + kdp_trans_off = 1; + read_result = kdp_vm_read(addr, &xbuf[0], 32); + kdp_trans_off = 0; + + if (read_result != 32) + db_printf("Unable to read address\n"); + else + db_printf("%016llX %08X %08X %08X %08X %08X %08X %08X %08X\n", addr, /* Print a line */ + xbuf[0], xbuf[1], xbuf[2], xbuf[3], + xbuf[4], xbuf[5], xbuf[6], xbuf[7]); + addr = addr + 0x00000020; /* Point to next address */ + } + db_next = addr; +} + +/* + * Displays all of the kmods in the system. + * + * dk + */ +void +db_display_kmod(__unused db_expr_t addr, __unused int have_addr, __unused db_expr_t count, __unused char *modif) +{ + + kmod_info_t *kmd; + unsigned int strt, end; + + kmd = kmod; /* Start at the start */ + + db_printf("info addr start - end name ver\n"); + + while (kmd) { /* Dump 'em all */ + strt = (unsigned int) kmd->address + kmd->hdr_size; + end = (unsigned int) kmd->address + kmd->size; + db_printf("%08X %08X %08X - %08X: %s, %s\n", + kmd, kmd->address, strt, end, kmd->name, kmd->version); + kmd = kmd->next; + } + + return; +}