FreeBSD/sys/i386/i386/db_trace.c
/*
 * Figure out the next frame up in the call stack.
 */
Figure out the next frame up in the call stack.
Figure out the next frame up in the call stack .
static void
db_nextframe(struct i386_frame **fp, db_addr_t *ip, struct thread *td)
{
	struct trapframe *tf;
	int frame_type;
	int eip, esp, ebp;
	db_expr_t offset;
	c_db_sym_t sym;
	const char *name;
	eip = db_get_value((int) &(*fp)->f_retaddr, 4, FALSE);
	ebp = db_get_value((int) &(*fp)->f_frame, 4, FALSE);
	frame_type = NORMAL;
	sym = db_search_symbol(eip - 1, DB_STGY_ANY, &offset);
	db_symbol_values(sym, &name, NULL);
	if (name != NULL) {
		if (strcmp(name, "calltrap") == 0 ||
		    strcmp(name, "fork_trampoline") == 0)
			frame_type = TRAP;
		else if (strncmp(name, "Xatpic_intr", 11) == 0 ||
		    strncmp(name, "Xapic_isr", 9) == 0)
			frame_type = INTERRUPT;
		else if (strcmp(name, "Xlcall_syscall") == 0 ||
		    strcmp(name, "Xint0x80_syscall") == 0)
			frame_type = SYSCALL;
		else if (strcmp(name, "dblfault_handler") == 0)
			frame_type = DOUBLE_FAULT;
		else if (strcmp(name, "Xtimerint") == 0)
			frame_type = TRAP_TIMERINT;
		else if (strcmp(name, "Xcpustop") == 0 ||
		    strcmp(name, "Xrendezvous") == 0 ||
		    strcmp(name, "Xipi_intr_bitmap_handler") == 0)
			frame_type = TRAP_INTERRUPT;
	}
	if (frame_type == NORMAL) {
		*ip = (db_addr_t) eip;
		*fp = (struct i386_frame *) ebp;
		return;
	}
	db_print_stack_entry(name, 0, 0, 0, eip, &(*fp)->f_frame);
	if (frame_type == DOUBLE_FAULT) {
		esp = PCPU_GET(common_tss.tss_esp);
		eip = PCPU_GET(common_tss.tss_eip);
		ebp = PCPU_GET(common_tss.tss_ebp);
		db_printf(
		    "--- trap 0x17, eip = %#r, esp = %#r, ebp = %#r ---\n",
		    eip, esp, ebp);
		*ip = (db_addr_t) eip;
		*fp = (struct i386_frame *) ebp;
		return;
	}
	if (frame_type == INTERRUPT)
		tf = (struct trapframe *)((int)*fp + 16);
	else if (frame_type == TRAP_INTERRUPT)
		tf = (struct trapframe *)((int)*fp + 8);
	else
		tf = (struct trapframe *)((int)*fp + 12);
	if (INKERNEL((int) tf)) {
		esp = get_esp(tf);
		eip = tf->tf_eip;
		ebp = tf->tf_ebp;
		switch (frame_type) {
		case TRAP:
			db_printf("--- trap %#r", tf->tf_trapno);
			break;
		case SYSCALL:
			db_printf("--- syscall");
			decode_syscall(tf->tf_eax, td);
			break;
		case TRAP_TIMERINT:
		case TRAP_INTERRUPT:
		case INTERRUPT:
			db_printf("--- interrupt");
			break;
		default:
			panic("The moon has moved again.");
		}
		db_printf(", eip = %#r, esp = %#r, ebp = %#r ---\n", eip,
		    esp, ebp);
	}
	*ip = (db_addr_t) eip;
	*fp = (struct i386_frame *) ebp;
}
static void db_nextframe ( struct i386_frame * * fp , db_addr_t * ip , struct thread * td ) { struct trapframe * tf ; int frame_type ; int eip , esp , ebp ; db_expr_t offset ; c_db_sym_t sym ; const char * name ; eip = db_get_value ( ( int ) & ( * fp ) -> f_retaddr , 4 , FALSE ) ; ebp = db_get_value ( ( int ) & ( * fp ) -> f_frame , 4 , FALSE ) ; frame_type = NORMAL ; sym = db_search_symbol ( eip - 1 , DB_STGY_ANY , & offset ) ; db_symbol_values ( sym , & name , NULL ) ; if ( name != NULL ) { if ( strcmp ( name , " " ) == 0 || strcmp ( name , " " ) == 0 ) frame_type = TRAP ; else if ( strncmp ( name , " " , 11 ) == 0 || strncmp ( name , " " , 9 ) == 0 ) frame_type = INTERRUPT ; else if ( strcmp ( name , " " ) == 0 || strcmp ( name , " " ) == 0 ) frame_type = SYSCALL ; else if ( strcmp ( name , " " ) == 0 ) frame_type = DOUBLE_FAULT ; else if ( strcmp ( name , " " ) == 0 ) frame_type = TRAP_TIMERINT ; else if ( strcmp ( name , " " ) == 0 || strcmp ( name , " " ) == 0 || strcmp ( name , " " ) == 0 ) frame_type = TRAP_INTERRUPT ; } if ( frame_type == NORMAL ) { * ip = ( db_addr_t ) eip ; * fp = ( struct i386_frame * ) ebp ; return ; } db_print_stack_entry ( name , 0 , 0 , 0 , eip , & ( * fp ) -> f_frame ) ; if ( frame_type == DOUBLE_FAULT ) { esp = PCPU_GET ( common_tss . tss_esp ) ; eip = PCPU_GET ( common_tss . tss_eip ) ; ebp = PCPU_GET ( common_tss . tss_ebp ) ; db_printf ( " \n " , eip , esp , ebp ) ; * ip = ( db_addr_t ) eip ; * fp = ( struct i386_frame * ) ebp ; return ; } if ( frame_type == INTERRUPT ) tf = ( struct trapframe * ) ( ( int ) * fp + 16 ) ; else if ( frame_type == TRAP_INTERRUPT ) tf = ( struct trapframe * ) ( ( int ) * fp + 8 ) ; else tf = ( struct trapframe * ) ( ( int ) * fp + 12 ) ; if ( INKERNEL ( ( int ) tf ) ) { esp = get_esp ( tf ) ; eip = tf -> tf_eip ; ebp = tf -> tf_ebp ; switch ( frame_type ) { case TRAP : db_printf ( " " , tf -> tf_trapno ) ; break ; case SYSCALL : db_printf ( " " ) ; decode_syscall ( tf -> tf_eax , td ) ; break ; case TRAP_TIMERINT : case TRAP_INTERRUPT : case INTERRUPT : db_printf ( " " ) ; break ; default : panic ( " " ) ; } db_printf ( " \n " , eip , esp , ebp ) ; } * ip = ( db_addr_t ) eip ; * fp = ( struct i386_frame * ) ebp ; }
Figure out the next frame up in the call stack.
Figure out the next frame up in the call stack .
/*
	 * Figure out frame type.  We look at the address just before
	 * the saved instruction pointer as the saved EIP is after the
	 * call function, and if the function being called is marked as
	 * dead (such as panic() at the end of dblfault_handler()), then
	 * the instruction at the saved EIP will be part of a different
	 * function (syscall() in this example) rather than the one that
	 * actually made the call.
	 */ /* XXX: These are interrupts with trap frames. */ /*
	 * Normal frames need no special processing.
	 */ /*
	 * For a double fault, we have to snag the values from the
	 * previous TSS since a double fault uses a task gate to
	 * switch to a known good state.
	 */ /*
	 * Point to base of trapframe which is just above the
	 * current frame.
	 */