- apply patches/patch.consistent2b. Description:

> This patch fixes a number of debugger problems.
>   - with trace-on, simulation time would pass 5x faster than usual, so
>     interrupts and other timed events would happen at different times
>   - with trace-on, breakpoints were ignored
>   - with trace-on, control-C would not stop the processor and return to the
>     debugger.
>
> This patch changes the execution quantum for the debugger to 1, which means
> that cpu_loop is asked to do one instruction at a time.  This may cause
> bochs with the debugger to be slower than before.
>
> I haven't tested without the debugger yet, so I don't know if the timing
> of events matches or not.
This commit is contained in:
Bryce Denney 2001-09-27 14:19:38 +00:00
parent bf983610b9
commit 9a1364b1f9
3 changed files with 88 additions and 55 deletions

View File

@ -308,6 +308,14 @@ debugger_check:
#endif
#if BX_DEBUGGER
if (BX_CPU_THIS_PTR trace) {
// print the instruction that was just executed. This used to
// return with a certain stop reason, but as a result the tracing
// affected simulation, which is obviously bad when you're trying
// to debug a problem.
bx_dbg_disassemble_current (-1);
}
// BW vm mode switch support is in dbg_is_begin_instr_bpoint
// note instr generating exceptions never reach this point.
@ -344,14 +352,9 @@ debugger_check:
}
}
#endif
if (BX_CPU_THIS_PTR trace) {
BX_CPU_THIS_PTR stop_reason = STOP_TRACE;
return;
}
#endif
#if BX_DEBUGGER
{
// check for icount or control-C. If found, set guard reg and return.
Bit32u debug_eip = BX_CPU_THIS_PTR prev_eip;
if ( dbg_is_end_instr_bpoint(
BX_CPU_THIS_PTR sregs[BX_SEG_REG_CS].selector.value,
@ -361,6 +364,7 @@ debugger_check:
return;
}
}
#endif // #if BX_DEBUGGER
goto main_cpu_loop;
}
@ -660,6 +664,7 @@ extern unsigned int dbg_show_mask;
BX_CPU_C::dbg_is_begin_instr_bpoint(Bit32u cs, Bit32u eip, Bit32u laddr,
Bit32u is_32)
{
//fprintf (stderr, "begin_instr_bp: checking cs:eip %04x:%08x\n", cs, eip);
BX_CPU_THIS_PTR guard_found.cs = cs;
BX_CPU_THIS_PTR guard_found.eip = eip;
BX_CPU_THIS_PTR guard_found.laddr = laddr;
@ -719,7 +724,14 @@ BX_CPU_C::dbg_is_begin_instr_bpoint(Bit32u cs, Bit32u eip, Bit32u laddr,
Boolean valid;
dbg_xlate_linear2phy(BX_CPU_THIS_PTR guard_found.laddr,
&phy, &valid);
if ( (BX_CPU_THIS_PTR guard_found.icount!=0) && valid ) {
// why the condition "guard_found.icount!=0"? That means that
// breakpoints only occur when you're using "continue" but never
// when you're using "step". I'm going to try disabling taht
// condition and see what happens. This caused it to stop at
// a breakpoint even while trace-on is on.
if ( valid
//&& (BX_CPU_THIS_PTR guard_found.icount!=0)
) {
for (unsigned i=0; i<bx_guard.iaddr.num_physical; i++) {
if ( bx_guard.iaddr.phy[i].addr == phy ) {
BX_CPU_THIS_PTR guard_found.guard_found = BX_DBG_GUARD_IADDR_PHY;
@ -739,8 +751,16 @@ BX_CPU_C::dbg_is_begin_instr_bpoint(Bit32u cs, Bit32u eip, Bit32u laddr,
BX_CPU_C::dbg_is_end_instr_bpoint(Bit32u cs, Bit32u eip, Bit32u laddr,
Bit32u is_32)
{
//fprintf (stderr, "end_instr_bp: checking for icount or ^C\n");
BX_CPU_THIS_PTR guard_found.icount++;
// convenient point to see if user typed Ctrl-C
if (bx_guard.interrupt_requested &&
(bx_guard.guard_for & BX_DBG_GUARD_CTRL_C)) {
BX_CPU_THIS_PTR guard_found.guard_found = BX_DBG_GUARD_CTRL_C;
return(1);
}
// see if debugger requesting icount guard
if (bx_guard.guard_for & BX_DBG_GUARD_ICOUNT) {
if (BX_CPU_THIS_PTR guard_found.icount >= bx_guard.icount) {
@ -753,13 +773,6 @@ BX_CPU_C::dbg_is_end_instr_bpoint(Bit32u cs, Bit32u eip, Bit32u laddr,
}
}
// convenient point to see if user typed Ctrl-C
if (bx_guard.interrupt_requested &&
(bx_guard.guard_for & BX_DBG_GUARD_CTRL_C)) {
BX_CPU_THIS_PTR guard_found.guard_found = BX_DBG_GUARD_CTRL_C;
return(1);
}
#if (BX_NUM_SIMULATORS >= 2)
// if async event pending, acknowlege them
if (bx_guard.async_changes_pending.which) {

View File

@ -1500,13 +1500,18 @@ bx_dbg_continue_command(void)
bx_guard.interrupt_requested = 0;
int stop = 0;
int which = -1;
int max_instr_executed = 0;
while (!stop) {
int quantum = 5; // arbitrary number of cycles to run in each
int quantum = 1; // arbitrary number of cycles to run in each
for (int cpu=0; cpu < BX_SMP_PROCESSORS; cpu++) {
BX_CPU(cpu)->guard_found.guard_found = 0;
BX_CPU(cpu)->guard_found.icount = 0;
bx_guard.icount = quantum;
BX_CPU(cpu)->cpu_loop (-1);
/// check out BX_CPU(cpu)->guard_found.icount
//fprintf (stderr, "dbg_cont: after cpu_loop guard_found.icount=%d\n", BX_CPU(cpu)->guard_found.icount);
if (BX_CPU(cpu)->guard_found.icount > max_instr_executed)
max_instr_executed = BX_CPU(cpu)->guard_found.icount;
// set stop flag if a guard found other than icount or halted
unsigned long found = BX_CPU(cpu)->guard_found.guard_found;
stop_reason_t reason = (stop_reason_t) BX_CPU(cpu)->stop_reason;
@ -1525,7 +1530,13 @@ bx_dbg_continue_command(void)
// cpus set stop, too bad.
}
// increment time tick only after all processors have had their chance.
BX_TICKN(quantum);
// MAJOR PROBLEM: we should tick by the number of instructions
// that were ACTUALLY executed, not the number that we asked it
// to execute. When tracing is on, only one instruction is
// executed, not quantum. As a result, when you trace you get
// ticks speeding ahead at 5x normal speed.
BX_TICKN(max_instr_executed);
//BX_TICKN(quantum);
}
#endif
@ -1535,10 +1546,6 @@ bx_dbg_continue_command(void)
BX_INSTR_DEBUG_PROMPT();
bx_dbg_print_guard_results();
if (BX_CPU(which)->stop_reason == STOP_TRACE
|| BX_CPU(which)->stop_reason == STOP_CPU_HALTED)
goto one_more;
if (watchpoint_continue && (BX_CPU(which)->stop_reason == STOP_READ_WATCH_POINT ||
BX_CPU(which)->stop_reason == STOP_WRITE_WATCH_POINT))
goto one_more;
@ -1990,6 +1997,46 @@ bx_dbg_compare_sim_memory(void)
#endif
void bx_dbg_disassemble_current (int which_cpu)
{
Bit32u phy;
Boolean valid;
if (which_cpu < 0) {
// iterate over all of them.
for (int i=0; i<BX_NUM_SIMULATORS; i++)
bx_dbg_disassemble_current (i);
return;
}
BX_CPU(which_cpu)->dbg_xlate_linear2phy(BX_CPU(which_cpu)->guard_found.laddr, &phy, &valid);
if (valid) {
unsigned ilen;
BX_CPU(which_cpu)->mem->dbg_fetch_mem(phy, 16, bx_disasm_ibuf);
ilen = bx_disassemble.disasm(BX_CPU(which_cpu)->guard_found.is_32bit_code,
bx_disasm_ibuf, bx_disasm_tbuf);
if (BX_CPU(which_cpu)->guard_found.is_32bit_code) {
fprintf(stderr, "(%u) %04x:%08x (%s): ", which_cpu,
(unsigned) BX_CPU(which_cpu)->guard_found.cs,
(unsigned) BX_CPU(which_cpu)->guard_found.eip,
bx_dbg_symbolic_address((BX_CPU(which_cpu)->cr3) >> 12, BX_CPU(which_cpu)->guard_found.eip, BX_CPU(which_cpu)->sregs[BX_SREG_CS].cache.u.segment.base));
}
else {
fprintf(stderr, "(%u) %04x:%04x: ", which_cpu,
(unsigned) BX_CPU(which_cpu)->guard_found.cs,
(unsigned) BX_CPU(which_cpu)->guard_found.eip);
}
for (unsigned j=0; j<ilen; j++)
fprintf(stderr, "%02x", (unsigned) bx_disasm_ibuf[j]);
fprintf(stderr, ": %s\n", bx_disasm_tbuf);
}
else {
fprintf(stderr, "(%u) ??? (physical address not available)\n", which_cpu);
}
}
void
bx_dbg_print_guard_results(void)
@ -2037,8 +2084,6 @@ for (sim=0; sim<BX_SMP_PROCESSORS; sim++) {
}
else if (BX_CPU(sim)->stop_reason == STOP_MAGIC_BREAK_POINT) {
fprintf(stderr, "(%u) Magic breakpoint\n", sim);
} else if (BX_CPU(sim)->stop_reason == STOP_TRACE) {
/* Nothing */
} else if (BX_CPU(sim)->stop_reason == STOP_TIME_BREAK_POINT) {
fprintf(stderr, "(%u) Caught time breakpoint\n", sim);
} else if (BX_CPU(sim)->stop_reason == STOP_MODE_BREAK_POINT) {
@ -2054,40 +2099,14 @@ for (sim=0; sim<BX_SMP_PROCESSORS; sim++) {
sim, BX_CPU(sim)->stop_reason);
}
#if BX_DISASM
if (bx_debugger.auto_disassemble) {
Bit32u phy;
Boolean valid;
BX_CPU(sim)->dbg_xlate_linear2phy(BX_CPU(sim)->guard_found.laddr, &phy, &valid);
if (valid) {
unsigned ilen;
BX_CPU(sim)->mem->dbg_fetch_mem(phy, 16, bx_disasm_ibuf);
ilen = bx_disassemble.disasm(BX_CPU(sim)->guard_found.is_32bit_code,
bx_disasm_ibuf, bx_disasm_tbuf);
if (BX_CPU(sim)->guard_found.is_32bit_code) {
fprintf(stderr, "(%u) %04x:%08x (%s): ", sim,
(unsigned) BX_CPU(sim)->guard_found.cs,
(unsigned) BX_CPU(sim)->guard_found.eip,
bx_dbg_symbolic_address((BX_CPU(sim)->cr3) >> 12, BX_CPU(sim)->guard_found.eip, BX_CPU(sim)->sregs[BX_SREG_CS].cache.u.segment.base));
}
else {
fprintf(stderr, "(%u) %04x:%04x: ", sim,
(unsigned) BX_CPU(sim)->guard_found.cs,
(unsigned) BX_CPU(sim)->guard_found.eip);
}
for (unsigned j=0; j<ilen; j++)
fprintf(stderr, "%02x", (unsigned) bx_disasm_ibuf[j]);
fprintf(stderr, ": %s\n", bx_disasm_tbuf);
}
else {
fprintf(stderr, "(%u) ??? (physical address not available)\n", sim);
}
}
// if tracing is on for this cpu, we've already printed the disassembly
// for the instruction that's about to be executed. So omit the
// disassembly here. (experiment)
if (! BX_CPU(sim)->trace)
bx_dbg_disassemble_current (sim);
}
#endif // #if BX_DISASM
}
}

View File

@ -150,7 +150,7 @@ extern int num_read_watchpoints;
extern Bit32u read_watchpoint[MAX_READ_WATCHPOINTS];
typedef enum {
STOP_NO_REASON = 0, STOP_TIME_BREAK_POINT, STOP_READ_WATCH_POINT, STOP_WRITE_WATCH_POINT, STOP_MAGIC_BREAK_POINT, STOP_TRACE, STOP_MODE_BREAK_POINT, STOP_CPU_HALTED
STOP_NO_REASON = 0, STOP_TIME_BREAK_POINT, STOP_READ_WATCH_POINT, STOP_WRITE_WATCH_POINT, STOP_MAGIC_BREAK_POINT, UNUSED_STOP_TRACE, STOP_MODE_BREAK_POINT, STOP_CPU_HALTED
} stop_reason_t;
typedef enum {
@ -405,6 +405,7 @@ void bx_dbg_outp(Bit16u addr, Bit32u value, unsigned len);
void bx_dbg_raise_HLDA(void);
Bit8u bx_dbg_IAC(void);
void bx_dbg_set_INTR(Boolean b);
void bx_dbg_disassemble_current (int which_cpu);
int bx_dbg_symbolic_output(void); /* BW */
#endif // #ifdef __cplusplus