Pass the trap type and code down from db_trap() to db_stop_at_pc() so

that the latter can easily determine what the trap type actually is
after callers are fixed to encode the type unambigously.

ddb currently barely understands breakpoints, and it treats all
non-breakpoints as single-step traps.  This works OK for stopping
after every instruction when single-stepping, but is broken for
single-stepping with a count > 1 (especially with a large count).
ddb needs to stop on the first non-single-step trap while single-
stepping.  Otherwise, ddb doesn't even stop the first time for
fatal traps and external breakpoints like the one in kdb_enter().
This commit is contained in:
Bruce Evans 2016-09-09 15:53:42 +00:00
parent 930b6b4dce
commit 5c48342f16
3 changed files with 6 additions and 7 deletions

View File

@ -226,10 +226,7 @@ db_trap(int type, int code)
if (cnunavailable())
return (0);
bkpt = IS_BREAKPOINT_TRAP(type, code);
watchpt = IS_WATCHPOINT_TRAP(type, code);
if (db_stop_at_pc(&bkpt)) {
if (db_stop_at_pc(type, code, &bkpt, &watchpt)) {
if (db_inst_count) {
db_printf("After %d instructions (%d loads, %d stores),\n",
db_inst_count, db_load_count, db_store_count);

View File

@ -90,13 +90,14 @@ db_pc_is_singlestep(db_addr_t pc)
#endif
bool
db_stop_at_pc(bool *is_breakpoint)
db_stop_at_pc(int type, int code, bool *is_breakpoint, bool *is_watchpoint)
{
db_addr_t pc;
db_breakpoint_t bkpt;
*is_breakpoint = IS_BREAKPOINT_TRAP(type, code);
*is_watchpoint = IS_WATCHPOINT_TRAP(type, code);
pc = PC_REGS();
if (db_pc_is_singlestep(pc))
*is_breakpoint = false;

View File

@ -215,7 +215,8 @@ void db_restart_at_pc(bool watchpt);
int db_set_variable(db_expr_t value);
void db_set_watchpoints(void);
void db_skip_to_eol(void);
bool db_stop_at_pc(bool *is_breakpoint);
bool db_stop_at_pc(int type, int code, bool *is_breakpoint,
bool *is_watchpoint);
#define db_strcpy strcpy
void db_trace_self(void);
int db_trace_thread(struct thread *, int);