Esempio n. 1
0
void
db_task_trap(
	int		type,
	int		code,
	boolean_t	user_space)
{
	jmp_buf_t db_jmpbuf;
	jmp_buf_t *prev;
	boolean_t	bkpt;
	boolean_t	watchpt;
	task_t		task;
	task_t		task_space;

	task = db_current_task();
	task_space = db_target_space(current_act(), user_space);
	bkpt = IS_BREAKPOINT_TRAP(type, code);
	watchpt = IS_WATCHPOINT_TRAP(type, code);

	/*
	 * Note:  we look up PC values in an address space (task_space),
	 * but print symbols using a (task-specific) symbol table, found
	 * using task.
	 */
	db_init_default_act();
	db_check_breakpoint_valid();
	if (db_stop_at_pc(&bkpt, task, task_space)) {
	    if (db_inst_count) {
		db_printf("After %d instructions (%d loads, %d stores),\n",
			  db_inst_count, db_load_count, db_store_count);
	    }
	    if (bkpt)
		db_printf("Breakpoint at  ");
	    else if (watchpt)
		db_printf("Watchpoint at  ");
	    else
		db_printf("Stopped at  ");
	    db_dot = PC_REGS(DDB_REGS);

	    prev = db_recover;
	    if (_setjmp(db_recover = &db_jmpbuf) == 0) {
#if defined(__alpha)
		db_print_loc(db_dot, task_space);
		db_printf("\n\t");
		db_print_inst(db_dot, task_space);
#else /* !defined(__alpha) */
#if defined(__powerpc__)
		db_print_loc_and_inst(db_dot, task_space);
#else	/* __powerpc__ */
		db_print_loc_and_inst(db_dot, task);
#endif	/* __powerpc__ */
#endif /* defined(__alpha) */
	    } else
		db_printf("Trouble printing location %#X.\n", db_dot);
	    db_recover = prev;

	    db_command_loop();
	}

	db_restart_at_pc(watchpt, task_space);
}
Esempio n. 2
0
void
db_trap(int type, int code)
{
	boolean_t	bkpt;
	boolean_t	watchpt;

	bkpt = IS_BREAKPOINT_TRAP(type, code);
	watchpt = IS_WATCHPOINT_TRAP(type, code);

	if (db_stop_at_pc(&bkpt)) {
	    if (db_inst_count) {
		db_printf("After %d instructions (%d loads, %d stores),\n",
			  db_inst_count, db_load_count, db_store_count);
	    }
	    if (bkpt)
		db_printf("Breakpoint at\t");
	    else if (watchpt)
		db_printf("Watchpoint at\t");
	    else
		db_printf("Stopped at\t");
	    db_dot = PC_REGS(DDB_REGS);
	    if (setjmp(db_jmpbuf) == 0)
		db_print_loc_and_inst(db_dot, DDB_REGS);

	    db_command_loop();
	}

	db_restart_at_pc(watchpt);
}
Esempio n. 3
0
void
db_show_regs(db_expr_t dummy1, int dummy2, db_expr_t dummy3, char *dummy4)
{
	register struct db_variable *regp;
	db_expr_t	value, offset;
	char *		name;

	for (regp = db_regs; regp < db_eregs; regp++) {
	    db_read_variable(regp, &value);
	    db_printf("%-12s%#10n", regp->name, value);
	    db_find_xtrn_sym_and_offset((db_addr_t)value, &name, &offset);
	    if (name != 0 && offset <= db_maxoff && offset != value) {
		db_printf("\t%s", name);
		if (offset != 0)
		    db_printf("+%#r", offset);
	    }
	    db_printf("\n");
	}
	db_print_loc_and_inst(PC_REGS(DDB_REGS));
}
Esempio n. 4
0
void
db_show_regs(db_expr_t _1, boolean_t _2, db_expr_t _3, char *_4)
{
	struct db_variable *regp;
	db_expr_t value, offset;
	const char *name;

	for (regp = db_regs; regp < db_eregs; regp++) {
		if (!db_read_variable(regp, &value))
			continue;
		db_printf("%-12s%#10lr", regp->name, (unsigned long)value);
		db_find_xtrn_sym_and_offset((db_addr_t)value, &name, &offset);
		if (name != NULL && offset <= (unsigned long)db_maxoff &&
		    offset != value) {
			db_printf("\t%s", name);
			if (offset != 0)
				db_printf("+%+#lr", (long)offset);
		}
		db_printf("\n");
	}
	db_print_loc_and_inst(PC_REGS());
}
Esempio n. 5
0
/*ARGSUSED*/
void
db_show_regs(db_expr_t addr, int have_addr, db_expr_t count, char *modif)
{
	struct db_variable *regp;
	db_expr_t	value, offset;
	char *		name;
	char		tmpfmt[28];

	for (regp = db_regs; regp < db_eregs; regp++) {
	    db_read_variable(regp, &value);
	    db_printf("%-12s%s", regp->name, db_format(tmpfmt, sizeof tmpfmt,
	      (long)value, DB_FORMAT_N, 1, sizeof(long) * 3));
	    db_find_xtrn_sym_and_offset((db_addr_t)value, &name, &offset);
	    if (name != 0 && offset <= db_maxoff && offset != value) {
		db_printf("\t%s", name);
		if (offset != 0)
		    db_printf("+%s", db_format(tmpfmt, sizeof tmpfmt,
		      (long)offset, DB_FORMAT_R, 1, 0));
	    }
	    db_printf("\n");
	}
	db_print_loc_and_inst(PC_REGS(DDB_REGS));
}
Esempio n. 6
0
boolean_t
db_stop_at_pc(boolean_t *is_breakpoint)
{
	db_addr_t	pc;
	db_breakpoint_t bkpt;

	db_clear_single_step(DDB_REGS);
	db_clear_breakpoints();
	db_clear_watchpoints();
	pc = PC_REGS(DDB_REGS);

#ifdef	FIXUP_PC_AFTER_BREAK
	if (*is_breakpoint) {
	    /*
	     * Breakpoint trap.  Fix up the PC if the
	     * machine requires it.
	     */
	    FIXUP_PC_AFTER_BREAK
	    pc = PC_REGS(DDB_REGS);
	}
#endif

	/*
	 * Now check for a breakpoint at this address.
	 */
	bkpt = db_find_breakpoint_here(pc);
	if (bkpt) {
	    if (--bkpt->count == 0) {
		bkpt->count = bkpt->init_count;
		*is_breakpoint = TRUE;
		return (TRUE);	/* stop here */
	    }
	} else if (*is_breakpoint) {
#ifdef __x86_64__
		ddb_regs.tf_rip += 1;
#endif
	}

	*is_breakpoint = FALSE;

	if (db_run_mode == STEP_INVISIBLE) {
	    db_run_mode = STEP_CONTINUE;
	    return (FALSE);	/* continue */
	}
	if (db_run_mode == STEP_COUNT) {
	    return (FALSE); /* continue */
	}
	if (db_run_mode == STEP_ONCE) {
	    if (--db_loop_count > 0) {
		if (db_sstep_print) {
		    db_printf("\t\t");
		    db_print_loc_and_inst(pc, DDB_REGS);
		    db_printf("\n");
		}
		return (FALSE);	/* continue */
	    }
	}
	if (db_run_mode == STEP_RETURN) {
	    db_expr_t ins = db_get_value(pc, sizeof(int), FALSE);

	    /* continue until matching return */

	    if (!inst_trap_return(ins) &&
		(!inst_return(ins) || --db_call_depth != 0)) {
		if (db_sstep_print) {
		    if (inst_call(ins) || inst_return(ins)) {
			int i;

			db_printf("[after %6d]     ", db_inst_count);
			for (i = db_call_depth; --i > 0; )
			    db_printf("  ");
			db_print_loc_and_inst(pc, DDB_REGS);
			db_printf("\n");
		    }
		}
		if (inst_call(ins))
		    db_call_depth++;
		return (FALSE);	/* continue */
	    }
	}
	if (db_run_mode == STEP_CALLT) {
	    db_expr_t ins = db_get_value(pc, sizeof(int), FALSE);

	    /* continue until call or return */

	    if (!inst_call(ins) &&
		!inst_return(ins) &&
		!inst_trap_return(ins)) {
		return (FALSE);	/* continue */
	    }
	}
	db_run_mode = STEP_NONE;
	return (TRUE);
}
Esempio n. 7
0
boolean_t
db_stop_at_pc(
	boolean_t	*is_breakpoint,
	task_t		task,
	task_t		space)
{
	register  db_thread_breakpoint_t bkpt;

	db_clear_task_single_step(DDB_REGS, space);
	db_clear_breakpoints();
	db_clear_watchpoints();
	db_stop_pc = PC_REGS(DDB_REGS);

#ifdef	FIXUP_PC_AFTER_BREAK
	if (*is_breakpoint) {
	    /*
	     * Breakpoint trap.  Fix up the PC if the
	     * machine requires it.
	     */
	    FIXUP_PC_AFTER_BREAK
	    db_stop_pc = PC_REGS(DDB_REGS);
	}
#endif

	/*
	 * Now check for a breakpoint at this address.
	 */
	bkpt = db_find_thread_breakpoint_here(space, db_stop_pc);
	if (bkpt) {
	    if (db_cond_check(bkpt)) {
		*is_breakpoint = TRUE;
		return (TRUE);	/* stop here */
	    }
	}
	*is_breakpoint = FALSE;

	if (db_run_mode == STEP_INVISIBLE) {
	    db_run_mode = STEP_CONTINUE;
	    return (FALSE);	/* continue */
	}
	if (db_run_mode == STEP_COUNT) {
	    return (FALSE); /* continue */
	}
	if (db_run_mode == STEP_ONCE) {
	    if (--db_loop_count > 0) {
		if (db_sstep_print) {
		    db_print_loc_and_inst(db_stop_pc, task);
		}
		return (FALSE);	/* continue */
	    }
	}
	if (db_run_mode == STEP_RETURN) {
	    jmp_buf_t *prev;
	    jmp_buf_t db_jmpbuf;
	    /* WARNING: the following assumes an instruction fits an int */
		db_expr_t ins;
	   
		ins = db_get_task_value(db_stop_pc, sizeof(int), FALSE, space);

	    /* continue until matching return */

	    prev = db_recover;
	    if (_setjmp(db_recover = &db_jmpbuf) == 0) {
	    	if (!inst_trap_return(ins) &&
		    (!inst_return(ins) || --db_call_depth != 0)) {
			if (db_sstep_print) {
		    	    if (inst_call(ins) || inst_return(ins)) {
				register int i;

				db_printf("[after %6d /%4d] ",
					  db_inst_count,
					  db_inst_count - db_last_inst_count);
				db_last_inst_count = db_inst_count;
				for (i = db_call_depth; --i > 0; )
				    db_printf("  ");
				db_print_loc_and_inst(db_stop_pc, task);
				db_printf("\n");
		    	    }
		        }
			if (inst_call(ins))
			    db_call_depth++;
			db_recover = prev;
			if (db_step_again())
				return (FALSE);	/* continue */
	        }
	    }
	    db_recover = prev;
	}
	if (db_run_mode == STEP_CALLT) {
	    /* WARNING: the following assumes an instruction fits an int */
		db_expr_t ins;
		ins = db_get_task_value(db_stop_pc, sizeof(int), FALSE, space);

	    /* continue until call or return */

	    if (!inst_call(ins) &&
		!inst_return(ins) &&
		!inst_trap_return(ins)) {
			if (db_step_again())
				return (FALSE);	/* continue */
	    }
	}
	if (db_find_breakpoint_here(space, db_stop_pc))
		return(FALSE);
	db_run_mode = STEP_NONE;
	return (TRUE);
}
Esempio n. 8
0
bool
db_stop_at_pc(db_regs_t *regs, bool *is_breakpoint)
{
	db_addr_t	pc;
	db_breakpoint_t bkpt;

	pc = PC_REGS(regs);

#ifdef	FIXUP_PC_AFTER_BREAK
	if (*is_breakpoint) {
		/*
		 * Breakpoint trap.  Regardless if we treat this as a
		 * real breakpoint (e.g. software single-step), fix up the PC.
		 */
		FIXUP_PC_AFTER_BREAK(regs);
		pc = PC_REGS(regs);
	}
#endif

#ifdef	SOFTWARE_SSTEP
	/*
	 * If we stopped at one of the single-step breakpoints, say it's not
	 * really a breakpoint so that we don't skip over the real instruction.
	 */
	if (db_taken_bkpt.address == pc || db_not_taken_bkpt.address == pc)
		*is_breakpoint = false;
#endif	/* SOFTWARE_SSTEP */

	db_clear_single_step(regs);
	db_clear_breakpoints();
	db_clear_watchpoints();

	/*
	 * Now check for a breakpoint at this address.
	 */
	bkpt = db_find_breakpoint_here(pc);
	if (bkpt) {
		if (--bkpt->count == 0) {
			bkpt->count = bkpt->init_count;
			*is_breakpoint = true;
			return (true);	/* stop here */
		}
	} else if (*is_breakpoint) {
#ifdef PC_ADVANCE
		PC_ADVANCE(regs);
#else
		PC_REGS(regs) += BKPT_SIZE;
#endif
	}

	*is_breakpoint = false;

	if (db_run_mode == STEP_INVISIBLE) {
		db_run_mode = STEP_CONTINUE;
		return (false);	/* continue */
	}
	if (db_run_mode == STEP_COUNT) {
		return (false); /* continue */
	}
	if (db_run_mode == STEP_ONCE) {
		if (--db_loop_count > 0) {
			if (db_sstep_print) {
				db_printf("\t\t");
				db_print_loc_and_inst(pc);
				db_printf("\n");
			}
			return (false);	/* continue */
		}
	}
	if (db_run_mode == STEP_RETURN) {
		db_expr_t ins = db_get_value(pc, sizeof(int), false);

		/* continue until matching return */

		if (!inst_trap_return(ins) &&
		    (!inst_return(ins) || --db_call_depth != 0)) {
			if (db_sstep_print) {
				if (inst_call(ins) || inst_return(ins)) {
					int i;

					db_printf("[after %6d]     ",
					    db_inst_count);
					for (i = db_call_depth; --i > 0; )
						db_printf("  ");
					db_print_loc_and_inst(pc);
					db_printf("\n");
				}
			}
			if (inst_call(ins))
				db_call_depth++;
			return (false);	/* continue */
		}
	}
	if (db_run_mode == STEP_CALLT) {
		db_expr_t ins = db_get_value(pc, sizeof(int), false);

		/* continue until call or return */

		if (!inst_call(ins) &&
		    !inst_return(ins) &&
		    !inst_trap_return(ins)) {
			return (false);	/* continue */
		}
	}
	db_run_mode = STEP_NONE;
	return (true);
}
Esempio n. 9
0
boolean_t
db_stop_at_pc(db_regs_t *regs, boolean_t *is_breakpoint)
{
	db_addr_t	pc, old_pc;
	db_breakpoint_t	bkpt;

	db_clear_breakpoints();
	db_clear_watchpoints();
	old_pc = pc = PC_REGS(regs);

#ifdef	FIXUP_PC_AFTER_BREAK
	if (*is_breakpoint) {
		/*
		 * Breakpoint trap.  Fix up the PC if the
		 * machine requires it.
		 */
		FIXUP_PC_AFTER_BREAK(regs);
		pc = PC_REGS(regs);
	}
#endif

	/*
	 * Now check for a breakpoint at this address.
	 */
	bkpt = db_find_breakpoint_here(pc);
	if (bkpt) {
		if (--bkpt->count == 0) {
			db_clear_single_step(regs);
			bkpt->count = bkpt->init_count;
			*is_breakpoint = TRUE;
			return (TRUE);	/* stop here */
		}
	} else if (*is_breakpoint
#ifdef SOFTWARE_SSTEP
	    && !((db_taken_bkpt && db_taken_bkpt->address == pc) ||
	    (db_not_taken_bkpt && db_not_taken_bkpt->address == pc))
#endif
	    ) {
#ifdef PC_ADVANCE
		PC_ADVANCE(regs);
#else
# ifdef SET_PC_REGS
		SET_PC_REGS(regs, old_pc);
# else
		PC_REGS(regs) = old_pc;
# endif
#endif
	}
	db_clear_single_step(regs);
		
	*is_breakpoint = FALSE;

	if (db_run_mode == STEP_INVISIBLE) {
		db_run_mode = STEP_CONTINUE;
		return (FALSE);	/* continue */
	}
	if (db_run_mode == STEP_COUNT) {
		return (FALSE); /* continue */
	}
	if (db_run_mode == STEP_ONCE) {
		if (--db_loop_count > 0) {
			if (db_sstep_print) {
				db_printf("\t\t");
				db_print_loc_and_inst(pc);
				db_printf("\n");
			}
			return (FALSE);	/* continue */
		}
	}
	if (db_run_mode == STEP_RETURN) {
	    db_expr_t ins = db_get_value(pc, sizeof(int), FALSE);

	    /* continue until matching return */

	    if (!inst_trap_return(ins) &&
		(!inst_return(ins) || --db_call_depth != 0)) {
		if (db_sstep_print) {
		    if (inst_call(ins) || inst_return(ins)) {
			int i;

			db_printf("[after %6d]     ", db_inst_count);
			for (i = db_call_depth; --i > 0; )
			    db_printf("  ");
			db_print_loc_and_inst(pc);
			db_printf("\n");
		    }
		}
		if (inst_call(ins))
		    db_call_depth++;
		return (FALSE);	/* continue */
	    }
	}
	if (db_run_mode == STEP_CALLT) {
	    db_expr_t ins = db_get_value(pc, sizeof(int), FALSE);

	    /* continue until call or return */

	    if (!inst_call(ins) && !inst_return(ins) &&
		!inst_trap_return(ins)) {
		return (FALSE);	/* continue */
	    }
	}
	db_run_mode = STEP_NONE;
	return (TRUE);
}