diff --git a/bochs/cpu/exception.cc b/bochs/cpu/exception.cc index acec46f5c..f86545bed 100644 --- a/bochs/cpu/exception.cc +++ b/bochs/cpu/exception.cc @@ -1,5 +1,5 @@ ///////////////////////////////////////////////////////////////////////// -// $Id: exception.cc,v 1.9 2001-10-03 13:10:37 bdenney Exp $ +// $Id: exception.cc,v 1.10 2002-03-12 09:16:41 bdenney Exp $ ///////////////////////////////////////////////////////////////////////// // // Copyright (C) 2001 MandrakeSoft S.A. @@ -63,6 +63,10 @@ BX_CPU_C::interrupt(Bit8u vector, Boolean is_INT, Boolean is_error_code, #endif #endif + if (bx_guard.special_unwind_stack) { + BX_INFO (("interrupt() returning early because special_unwind_stack is set")); + return; + } //BX_DEBUG(( "::interrupt(%u)", vector )); BX_INSTR_INTERRUPT(vector); @@ -572,6 +576,11 @@ BX_CPU_C::exception(unsigned vector, Bit16u error_code, Boolean is_INT) Bit8u exception_type; unsigned prev_errno; + if (bx_guard.special_unwind_stack) { + BX_INFO (("exception() returning early because special_unwind_stack is set")); + return; + } + //BX_DEBUG(( "::exception(%u)", vector )); BX_INSTR_EXCEPTION(vector); @@ -593,6 +602,9 @@ BX_CPU_C::exception(unsigned vector, Bit16u error_code, Boolean is_INT) BX_CPU_THIS_PTR errorno++; if (BX_CPU_THIS_PTR errorno >= 3) { BX_PANIC(("exception(): 3rd exception with no resolution")); + BX_ERROR(("WARNING: Any simulation after this point is completely bogus.")); + bx_guard.special_unwind_stack = true; + return; } /* careful not to get here with curr_exception[1]==DOUBLE_FAULT */ @@ -600,7 +612,10 @@ BX_CPU_C::exception(unsigned vector, Bit16u error_code, Boolean is_INT) /* if 1st was a double fault (software INT?), then shutdown */ if ( (BX_CPU_THIS_PTR errorno==2) && (BX_CPU_THIS_PTR curr_exception[0]==BX_ET_DOUBLE_FAULT) ) { - BX_PANIC(("exception(): tripple fault encountered")); + BX_PANIC(("exception(): triple fault encountered")); + BX_ERROR(("WARNING: Any simulation after this point is completely bogus.")); + bx_guard.special_unwind_stack = true; + return; } /* ??? this is not totally correct, should be done depending on diff --git a/bochs/debug/dbg_main.cc b/bochs/debug/dbg_main.cc index 33f3e370b..71ec1a05b 100644 --- a/bochs/debug/dbg_main.cc +++ b/bochs/debug/dbg_main.cc @@ -1,5 +1,5 @@ ///////////////////////////////////////////////////////////////////////// -// $Id: dbg_main.cc,v 1.37 2002-02-15 22:58:06 yakovlev Exp $ +// $Id: dbg_main.cc,v 1.38 2002-03-12 09:16:40 bdenney Exp $ ///////////////////////////////////////////////////////////////////////// // // Copyright (C) 2001 MandrakeSoft S.A. @@ -1520,6 +1520,7 @@ bx_dbg_continue_command(void) #if BX_NUM_SIMULATORS >= 2 bx_guard.interrupt_requested = 0; + bx_guard.special_unwind_stack = 0; while (1) { if ( !bx_dbg_cosimulateN(bx_debugger.icount_quantum) ) break; @@ -1533,6 +1534,7 @@ bx_dbg_continue_command(void) bx_guard.interrupt_requested = 0; + bx_guard.special_unwind_stack = 0; int stop = 0; int which = -1; while (!stop) { @@ -1608,6 +1610,7 @@ bx_dbg_stepN_command(bx_dbg_icount_t count) #if BX_NUM_SIMULATORS >= 2 bx_guard.interrupt_requested = 0; + bx_guard.special_unwind_stack = 0; bx_dbg_cosimulateN(count); #else // single CPU diff --git a/bochs/debug/debug.h b/bochs/debug/debug.h index 69e2f58ab..d23e5bfd8 100644 --- a/bochs/debug/debug.h +++ b/bochs/debug/debug.h @@ -1,5 +1,5 @@ ///////////////////////////////////////////////////////////////////////// -// $Id: debug.h,v 1.10 2001-11-28 18:37:12 instinc Exp $ +// $Id: debug.h,v 1.11 2002-03-12 09:16:41 bdenney Exp $ ///////////////////////////////////////////////////////////////////////// // // Copyright (C) 2001 MandrakeSoft S.A. @@ -257,6 +257,18 @@ typedef struct { // user typed Ctrl-C, requesting simulator stop at next convient spot volatile Boolean interrupt_requested; + // when a triple fault occurs, Bochs panics. If you continue through + // the panic, it will generally produce another exception and panic + // again at an even deeper stack level. To recover from this potentially + // infinite recursion, I set special_unwind_stack to true. This causes + // the interrupt() and exception() functions to return immediately instead + // of creating more exception conditions, and allows the user to reenter the + // debugger after the triple fault. Note that special_unwind_stack causes + // bochs to NOT emulate the hardware behavior correctly. The correct + // behavior would be to reboot. (Rebooting, if it is ever implemented, + // will need some kind of unwinding too.) + Boolean special_unwind_stack; + // booleans to control whether simulator should report events // to debug controller struct {