Break to debugger on triple fault or panic (this time do it correctly)
Indent changes
This commit is contained in:
parent
49d7b4614f
commit
8ed8916ea9
@ -1,5 +1,5 @@
|
||||
/////////////////////////////////////////////////////////////////////////
|
||||
// $Id: dbg_main.cc,v 1.70 2006-06-12 16:58:26 sshwarts Exp $
|
||||
// $Id: dbg_main.cc,v 1.71 2006-06-12 19:51:31 sshwarts Exp $
|
||||
/////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Copyright (C) 2001 MandrakeSoft S.A.
|
||||
@ -1192,7 +1192,6 @@ one_more:
|
||||
SIM->set_display_mode(DISP_MODE_SIM);
|
||||
|
||||
bx_guard.interrupt_requested = 0;
|
||||
bx_guard.special_unwind_stack = 0;
|
||||
int stop = 0;
|
||||
int which = -1;
|
||||
while (!stop && !bx_guard.interrupt_requested) {
|
||||
|
@ -1,5 +1,5 @@
|
||||
/////////////////////////////////////////////////////////////////////////
|
||||
// $Id: debug.h,v 1.26 2006-06-11 16:40:37 sshwarts Exp $
|
||||
// $Id: debug.h,v 1.27 2006-06-12 19:51:31 sshwarts Exp $
|
||||
/////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Copyright (C) 2001 MandrakeSoft S.A.
|
||||
@ -225,7 +225,7 @@ void bx_dbg_set_reg32_value(unsigned reg, Bit32u value);
|
||||
void bx_dbg_set_reg64_value(unsigned reg, Bit64u value);
|
||||
Bit32u bx_dbg_get_laddr(Bit16u sel, Bit32u ofs);
|
||||
void bx_dbg_step_over_command(void);
|
||||
bx_num_range make_num_range (Bit64s from, Bit64s to);
|
||||
bx_num_range make_num_range(Bit64s from, Bit64s to);
|
||||
void bx_dbg_trace_command(bx_bool enable);
|
||||
void bx_dbg_trace_reg_command(bx_bool enable);
|
||||
void bx_dbg_ptime_command(void);
|
||||
@ -251,12 +251,12 @@ void bx_dbg_disassemble_switch_mode(void);
|
||||
void bx_dbg_set_disassemble_size(unsigned size);
|
||||
void bx_dbg_del_breakpoint_command(unsigned handle);
|
||||
void bx_dbg_en_dis_breakpoint_command(unsigned handle, bx_bool enable);
|
||||
bx_bool bx_dbg_en_dis_pbreak (unsigned handle, bx_bool enable);
|
||||
bx_bool bx_dbg_en_dis_lbreak (unsigned handle, bx_bool enable);
|
||||
bx_bool bx_dbg_en_dis_vbreak (unsigned handle, bx_bool enable);
|
||||
bx_bool bx_dbg_en_dis_pbreak(unsigned handle, bx_bool enable);
|
||||
bx_bool bx_dbg_en_dis_lbreak(unsigned handle, bx_bool enable);
|
||||
bx_bool bx_dbg_en_dis_vbreak(unsigned handle, bx_bool enable);
|
||||
bx_bool bx_dbg_del_pbreak(unsigned handle);
|
||||
bx_bool bx_dbg_del_lbreak (unsigned handle);
|
||||
bx_bool bx_dbg_del_vbreak (unsigned handle);
|
||||
bx_bool bx_dbg_del_lbreak(unsigned handle);
|
||||
bx_bool bx_dbg_del_vbreak(unsigned handle);
|
||||
int bx_dbg_vbreakpoint_command(BreakpointKind bk, Bit32u cs, bx_address eip);
|
||||
int bx_dbg_lbreakpoint_command(BreakpointKind bk, bx_address laddress);
|
||||
int bx_dbg_pbreakpoint_command(BreakpointKind bk, Bit32u paddress);
|
||||
@ -349,7 +349,7 @@ typedef enum {
|
||||
#define BX_DBG_PENDING_DMA 1
|
||||
#define BX_DBG_PENDING_IRQ 2
|
||||
|
||||
void bx_debug_break ();
|
||||
void bx_debug_break(void);
|
||||
|
||||
void bx_dbg_exit(int code);
|
||||
#if BX_DBG_EXTENSIONS
|
||||
@ -408,18 +408,6 @@ typedef struct {
|
||||
// user typed Ctrl-C, requesting simulator stop at next convient spot
|
||||
volatile bx_bool 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.)
|
||||
bx_bool special_unwind_stack;
|
||||
|
||||
// booleans to control whether simulator should report events
|
||||
// to debug controller
|
||||
struct {
|
||||
@ -472,7 +460,7 @@ extern bx_guard_t bx_guard;
|
||||
|
||||
int bx_dbg_main(int argc, char *argv[]);
|
||||
void bx_dbg_user_input_loop(void);
|
||||
void bx_dbg_interpret_line (char *cmd);
|
||||
void bx_dbg_interpret_line(char *cmd);
|
||||
|
||||
typedef struct {
|
||||
Bit16u sel;
|
||||
|
@ -1,5 +1,5 @@
|
||||
/////////////////////////////////////////////////////////////////////////
|
||||
// $Id: cpu.cc,v 1.160 2006-06-11 21:37:22 sshwarts Exp $
|
||||
// $Id: cpu.cc,v 1.161 2006-06-12 19:51:31 sshwarts Exp $
|
||||
/////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Copyright (C) 2001 MandrakeSoft S.A.
|
||||
@ -223,8 +223,8 @@ void BX_CPU_C::cpu_loop(Bit32u max_instr_count)
|
||||
// If the exception() routine has encountered a nasty fault scenario,
|
||||
// the debugger may request that control is returned to it so that
|
||||
// the situation may be examined.
|
||||
if (bx_guard.special_unwind_stack) {
|
||||
BX_ERROR(("CPU_LOOP bx_guard.special_unwind_stack=%d", bx_guard.special_unwind_stack));
|
||||
if (bx_guard.interrupt_requested) {
|
||||
BX_ERROR(("CPU_LOOP bx_guard.interrupt_requested=%d", bx_guard.interrupt_requested));
|
||||
return;
|
||||
}
|
||||
#endif
|
||||
|
@ -1,5 +1,5 @@
|
||||
/////////////////////////////////////////////////////////////////////////
|
||||
// $Id: exception.cc,v 1.80 2006-06-12 16:58:27 sshwarts Exp $
|
||||
// $Id: exception.cc,v 1.81 2006-06-12 19:51:31 sshwarts Exp $
|
||||
/////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Copyright (C) 2001 MandrakeSoft S.A.
|
||||
@ -763,10 +763,6 @@ void BX_CPU_C::real_mode_int(Bit8u vector, bx_bool is_INT, bx_bool is_error_code
|
||||
void BX_CPU_C::interrupt(Bit8u vector, bx_bool is_INT, bx_bool is_error_code, Bit16u error_code)
|
||||
{
|
||||
#if BX_DEBUGGER
|
||||
if (bx_guard.special_unwind_stack) {
|
||||
BX_INFO(("interrupt() returning early because special_unwind_stack is set"));
|
||||
return;
|
||||
}
|
||||
BX_CPU_THIS_PTR show_flag |= Flag_intsig;
|
||||
#if BX_DEBUG_LINUX
|
||||
if (bx_dbg.linux_syscall) {
|
||||
@ -816,17 +812,6 @@ void BX_CPU_C::exception(unsigned vector, Bit16u error_code, bx_bool is_INT)
|
||||
invalidate_prefetch_q();
|
||||
UNUSED(is_INT);
|
||||
|
||||
#if BX_DEBUGGER
|
||||
if (bx_guard.special_unwind_stack) {
|
||||
BX_INFO(("exception(): returning early because special_unwind_stack is set"));
|
||||
longjmp(BX_CPU_THIS_PTR jmp_buf_env, 1); // go back to main decode loop
|
||||
}
|
||||
#endif
|
||||
|
||||
//#if BX_EXTERNAL_DEBUGGER
|
||||
//trap_debugger(1);
|
||||
//#endif
|
||||
|
||||
BX_INSTR_EXCEPTION(BX_CPU_ID, vector);
|
||||
|
||||
BX_DEBUG(("exception(0x%02X)", (unsigned) vector));
|
||||
@ -846,9 +831,13 @@ void BX_CPU_C::exception(unsigned vector, Bit16u error_code, bx_bool is_INT)
|
||||
// if 1st was a double fault (software INT?), then shutdown
|
||||
(BX_CPU_THIS_PTR errorno == 2 && BX_CPU_THIS_PTR curr_exception[0]==BX_ET_DOUBLE_FAULT))
|
||||
{
|
||||
debug(BX_CPU_THIS_PTR prev_eip); // print debug information to the log
|
||||
#if BX_DEBUGGER
|
||||
// trap into debugger (similar as done when PANIC occured)
|
||||
bx_debug_break();
|
||||
#endif
|
||||
if (SIM->get_param_bool(BXPN_RESET_ON_TRIPLE_FAULT)->get()) {
|
||||
BX_ERROR(("exception(): 3rd (%d) exception with no resolution, shutdown status is %02xh, resetting", vector, DEV_cmos_get_reg(0x0f)));
|
||||
debug(BX_CPU_THIS_PTR prev_eip);
|
||||
bx_pc_system.Reset(BX_RESET_SOFTWARE);
|
||||
}
|
||||
else {
|
||||
@ -856,9 +845,6 @@ void BX_CPU_C::exception(unsigned vector, Bit16u error_code, bx_bool is_INT)
|
||||
BX_ERROR(("WARNING: Any simulation after this point is completely bogus !"));
|
||||
shutdown();
|
||||
}
|
||||
#if BX_DEBUGGER
|
||||
bx_guard.special_unwind_stack = 1;
|
||||
#endif
|
||||
longjmp(BX_CPU_THIS_PTR jmp_buf_env, 1); // go back to main decode loop
|
||||
}
|
||||
|
||||
|
@ -1,5 +1,5 @@
|
||||
/////////////////////////////////////////////////////////////////////////
|
||||
// $Id: segment_ctrl_pro.cc,v 1.64 2006-06-12 16:58:27 sshwarts Exp $
|
||||
// $Id: segment_ctrl_pro.cc,v 1.65 2006-06-12 19:51:31 sshwarts Exp $
|
||||
/////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Copyright (C) 2001 MandrakeSoft S.A.
|
||||
@ -511,7 +511,7 @@ bx_bool BX_CPU_C::set_segment_ar_data(bx_segment_reg_t *seg,
|
||||
d->u.segment.limit_scaled = (d->u.segment.limit << 12);
|
||||
else
|
||||
d->u.segment.limit_scaled = (d->u.segment.limit << 12) | 0x0fff;
|
||||
}
|
||||
}
|
||||
else
|
||||
d->u.segment.limit_scaled = d->u.segment.limit;
|
||||
|
||||
|
551
bochs/logio.cc
551
bochs/logio.cc
@ -1,5 +1,5 @@
|
||||
/////////////////////////////////////////////////////////////////////////
|
||||
// $Id: logio.cc,v 1.54 2006-05-30 17:01:27 sshwarts Exp $
|
||||
// $Id: logio.cc,v 1.55 2006-06-12 19:51:31 sshwarts Exp $
|
||||
/////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Copyright (C) 2001 MandrakeSoft S.A.
|
||||
@ -44,85 +44,85 @@ static int Allocio=0;
|
||||
|
||||
void iofunctions::flush(void)
|
||||
{
|
||||
if(logfd && magic == MAGIC_LOGNUM) {
|
||||
fflush(logfd);
|
||||
}
|
||||
if(logfd && magic == MAGIC_LOGNUM) {
|
||||
fflush(logfd);
|
||||
}
|
||||
}
|
||||
|
||||
void iofunctions::init(void)
|
||||
{
|
||||
// iofunctions methods must not be called before this magic
|
||||
// number is set.
|
||||
magic=MAGIC_LOGNUM;
|
||||
// iofunctions methods must not be called before this magic
|
||||
// number is set.
|
||||
magic=MAGIC_LOGNUM;
|
||||
|
||||
// sets the default logprefix
|
||||
strcpy(logprefix,"%t%e%d");
|
||||
n_logfn = 0;
|
||||
init_log(stderr);
|
||||
log = new logfunc_t(this);
|
||||
log->put("IO");
|
||||
log->settype(IOLOG);
|
||||
log->ldebug ("Init(log file: '%s').",logfn);
|
||||
// sets the default logprefix
|
||||
strcpy(logprefix,"%t%e%d");
|
||||
n_logfn = 0;
|
||||
init_log(stderr);
|
||||
log = new logfunc_t(this);
|
||||
log->put("IO");
|
||||
log->settype(IOLOG);
|
||||
log->ldebug("Init(log file: '%s').",logfn);
|
||||
}
|
||||
|
||||
void iofunctions::add_logfn (logfunc_t *fn)
|
||||
void iofunctions::add_logfn(logfunc_t *fn)
|
||||
{
|
||||
assert (n_logfn < MAX_LOGFNS);
|
||||
assert(n_logfn < MAX_LOGFNS);
|
||||
logfn_list[n_logfn++] = fn;
|
||||
}
|
||||
|
||||
void iofunctions::set_log_action (int loglevel, int action)
|
||||
void iofunctions::set_log_action(int loglevel, int action)
|
||||
{
|
||||
for (int i=0; i<n_logfn; i++)
|
||||
for(int i=0; i<n_logfn; i++)
|
||||
logfn_list[i]->setonoff(loglevel, action);
|
||||
}
|
||||
|
||||
void iofunctions::init_log(const char *fn)
|
||||
{
|
||||
assert (magic==MAGIC_LOGNUM);
|
||||
// use newfd/newfn so that we can log the message to the OLD log
|
||||
// file descriptor.
|
||||
FILE *newfd = stderr;
|
||||
char *newfn = "/dev/stderr";
|
||||
if( strcmp( fn, "-" ) != 0 ) {
|
||||
newfd = fopen(fn, "w");
|
||||
if(newfd != NULL) {
|
||||
newfn = strdup(fn);
|
||||
log->ldebug ("Opened log file '%s'.", fn );
|
||||
} else {
|
||||
// in constructor, genlog might not exist yet, so do it the safe way.
|
||||
log->error("Couldn't open log file: %s, using stderr instead", fn);
|
||||
newfd = stderr;
|
||||
}
|
||||
}
|
||||
logfd = newfd;
|
||||
logfn = newfn;
|
||||
assert(magic==MAGIC_LOGNUM);
|
||||
// use newfd/newfn so that we can log the message to the OLD log
|
||||
// file descriptor.
|
||||
FILE *newfd = stderr;
|
||||
char *newfn = "/dev/stderr";
|
||||
if(strcmp(fn, "-") != 0) {
|
||||
newfd = fopen(fn, "w");
|
||||
if(newfd != NULL) {
|
||||
newfn = strdup(fn);
|
||||
log->ldebug("Opened log file '%s'.", fn );
|
||||
} else {
|
||||
// in constructor, genlog might not exist yet, so do it the safe way.
|
||||
log->error("Couldn't open log file: %s, using stderr instead", fn);
|
||||
newfd = stderr;
|
||||
}
|
||||
}
|
||||
logfd = newfd;
|
||||
logfn = newfn;
|
||||
}
|
||||
|
||||
void iofunctions::init_log(FILE *fs)
|
||||
{
|
||||
assert (magic==MAGIC_LOGNUM);
|
||||
logfd = fs;
|
||||
assert(magic==MAGIC_LOGNUM);
|
||||
logfd = fs;
|
||||
|
||||
if(fs == stderr) {
|
||||
logfn = "/dev/stderr";
|
||||
} else if(fs == stdout) {
|
||||
logfn = "/dev/stdout";
|
||||
} else {
|
||||
logfn = "(unknown)";
|
||||
}
|
||||
if(fs == stderr) {
|
||||
logfn = "/dev/stderr";
|
||||
} else if(fs == stdout) {
|
||||
logfn = "/dev/stdout";
|
||||
} else {
|
||||
logfn = "(unknown)";
|
||||
}
|
||||
}
|
||||
|
||||
void iofunctions::init_log(int fd)
|
||||
{
|
||||
assert (magic==MAGIC_LOGNUM);
|
||||
FILE *tmpfd;
|
||||
if( (tmpfd = fdopen(fd,"w")) == NULL ) {
|
||||
log->panic("Couldn't open fd %d as a stream for writing", fd);
|
||||
return;
|
||||
}
|
||||
assert(magic==MAGIC_LOGNUM);
|
||||
FILE *tmpfd;
|
||||
if((tmpfd = fdopen(fd,"w")) == NULL) {
|
||||
log->panic("Couldn't open fd %d as a stream for writing", fd);
|
||||
return;
|
||||
}
|
||||
|
||||
init_log(tmpfd);
|
||||
init_log(tmpfd);
|
||||
};
|
||||
|
||||
// all other functions may use genlog safely.
|
||||
@ -130,10 +130,9 @@ void iofunctions::init_log(int fd)
|
||||
|
||||
// This converts the option string to a printf style string with the following args:
|
||||
// 1. timer, 2. event, 3. cpu0 eip, 4. device
|
||||
void
|
||||
iofunctions::set_log_prefix(const char* prefix) {
|
||||
|
||||
strcpy(logprefix,prefix);
|
||||
void iofunctions::set_log_prefix(const char* prefix)
|
||||
{
|
||||
strcpy(logprefix, prefix);
|
||||
}
|
||||
|
||||
// iofunctions::out( class, level, prefix, fmt, ap)
|
||||
@ -142,98 +141,99 @@ iofunctions::set_log_prefix(const char* prefix) {
|
||||
|
||||
void iofunctions::out(int f, int l, const char *prefix, const char *fmt, va_list ap)
|
||||
{
|
||||
char c=' ', *s;
|
||||
assert (magic==MAGIC_LOGNUM);
|
||||
assert (this != NULL);
|
||||
assert (logfd != NULL);
|
||||
char c=' ', *s;
|
||||
assert(magic==MAGIC_LOGNUM);
|
||||
assert(this != NULL);
|
||||
assert(logfd != NULL);
|
||||
|
||||
switch(l) {
|
||||
case LOGLEV_INFO: c='i'; break;
|
||||
case LOGLEV_PANIC: c='p'; break;
|
||||
case LOGLEV_PASS: c='s'; break;
|
||||
case LOGLEV_ERROR: c='e'; break;
|
||||
case LOGLEV_DEBUG: c='d'; break;
|
||||
default: break;
|
||||
}
|
||||
//fprintf(logfd, "-%c",c);
|
||||
switch(l) {
|
||||
case LOGLEV_INFO: c='i'; break;
|
||||
case LOGLEV_PANIC: c='p'; break;
|
||||
case LOGLEV_PASS: c='s'; break;
|
||||
case LOGLEV_ERROR: c='e'; break;
|
||||
case LOGLEV_DEBUG: c='d'; break;
|
||||
default: break;
|
||||
}
|
||||
|
||||
//if(prefix != NULL)
|
||||
// fprintf(logfd, "%s ", prefix);
|
||||
//fprintf(logfd, "-%c",c);
|
||||
|
||||
s=logprefix;
|
||||
while(*s) {
|
||||
switch(*s) {
|
||||
case '%':
|
||||
if(*(s+1)) s++;
|
||||
else break;
|
||||
switch(*s) {
|
||||
case 'd':
|
||||
fprintf(logfd, "%s", prefix==NULL?"":prefix);
|
||||
break;
|
||||
case 't':
|
||||
fprintf(logfd, FMT_TICK, bx_pc_system.time_ticks());
|
||||
break;
|
||||
case 'i':
|
||||
//if(prefix != NULL)
|
||||
// fprintf(logfd, "%s ", prefix);
|
||||
|
||||
s=logprefix;
|
||||
while(*s) {
|
||||
switch(*s) {
|
||||
case '%':
|
||||
if(*(s+1)) s++;
|
||||
else break;
|
||||
switch(*s) {
|
||||
case 'd':
|
||||
fprintf(logfd, "%s", prefix==NULL?"":prefix);
|
||||
break;
|
||||
case 't':
|
||||
fprintf(logfd, FMT_TICK, bx_pc_system.time_ticks());
|
||||
break;
|
||||
case 'i':
|
||||
#if BX_SUPPORT_SMP == 0
|
||||
fprintf(logfd, "%08x", BX_CPU(0)->dword.eip);
|
||||
fprintf(logfd, "%08x", BX_CPU(0)->dword.eip);
|
||||
#endif
|
||||
break;
|
||||
case 'e':
|
||||
fprintf(logfd, "%c", c);
|
||||
break;
|
||||
case '%':
|
||||
fprintf(logfd,"%%");
|
||||
break;
|
||||
default:
|
||||
fprintf(logfd,"%%%c",*s);
|
||||
}
|
||||
break;
|
||||
default :
|
||||
fprintf(logfd,"%c",*s);
|
||||
}
|
||||
s++;
|
||||
break;
|
||||
case 'e':
|
||||
fprintf(logfd, "%c", c);
|
||||
break;
|
||||
case '%':
|
||||
fprintf(logfd,"%%");
|
||||
break;
|
||||
default:
|
||||
fprintf(logfd,"%%%c",*s);
|
||||
}
|
||||
break;
|
||||
default :
|
||||
fprintf(logfd,"%c",*s);
|
||||
}
|
||||
s++;
|
||||
}
|
||||
|
||||
fprintf(logfd," ");
|
||||
fprintf(logfd," ");
|
||||
|
||||
if(l==LOGLEV_PANIC)
|
||||
fprintf(logfd, ">>PANIC<< ");
|
||||
if(l==LOGLEV_PASS)
|
||||
fprintf(logfd, ">>PASS<< ");
|
||||
if(l==LOGLEV_PANIC)
|
||||
fprintf(logfd, ">>PANIC<< ");
|
||||
if(l==LOGLEV_PASS)
|
||||
fprintf(logfd, ">>PASS<< ");
|
||||
|
||||
vfprintf(logfd, fmt, ap);
|
||||
fprintf(logfd, "\n");
|
||||
fflush(logfd);
|
||||
vfprintf(logfd, fmt, ap);
|
||||
fprintf(logfd, "\n");
|
||||
fflush(logfd);
|
||||
}
|
||||
|
||||
iofunctions::iofunctions(FILE *fs)
|
||||
{
|
||||
init();
|
||||
init_log(fs);
|
||||
init();
|
||||
init_log(fs);
|
||||
}
|
||||
|
||||
iofunctions::iofunctions(const char *fn)
|
||||
{
|
||||
init();
|
||||
init_log(fn);
|
||||
init();
|
||||
init_log(fn);
|
||||
}
|
||||
|
||||
iofunctions::iofunctions(int fd)
|
||||
{
|
||||
init();
|
||||
init_log(fd);
|
||||
init();
|
||||
init_log(fd);
|
||||
}
|
||||
|
||||
iofunctions::iofunctions(void)
|
||||
iofunctions::iofunctions()
|
||||
{
|
||||
this->init();
|
||||
init();
|
||||
}
|
||||
|
||||
iofunctions::~iofunctions(void)
|
||||
{
|
||||
// flush before erasing magic number, or flush does nothing.
|
||||
this->flush();
|
||||
this->magic=0;
|
||||
// flush before erasing magic number, or flush does nothing.
|
||||
flush();
|
||||
magic=0;
|
||||
}
|
||||
|
||||
#define LOG_THIS genlog->
|
||||
@ -253,186 +253,187 @@ int logfunctions::default_onoff[N_LOGLEV] =
|
||||
|
||||
logfunctions::logfunctions(void)
|
||||
{
|
||||
prefix = NULL;
|
||||
put(" ");
|
||||
settype(GENLOG);
|
||||
if (io == NULL && Allocio == 0) {
|
||||
Allocio = 1;
|
||||
io = new iofunc_t(stderr);
|
||||
}
|
||||
setio(io);
|
||||
// BUG: unfortunately this can be called before the bochsrc is read,
|
||||
// which means that the bochsrc has no effect on the actions.
|
||||
for (int i=0; i<N_LOGLEV; i++)
|
||||
onoff[i] = get_default_action(i);
|
||||
prefix = NULL;
|
||||
put(" ");
|
||||
settype(GENLOG);
|
||||
if (io == NULL && Allocio == 0) {
|
||||
Allocio = 1;
|
||||
io = new iofunc_t(stderr);
|
||||
}
|
||||
setio(io);
|
||||
// BUG: unfortunately this can be called before the bochsrc is read,
|
||||
// which means that the bochsrc has no effect on the actions.
|
||||
for (int i=0; i<N_LOGLEV; i++)
|
||||
onoff[i] = get_default_action(i);
|
||||
}
|
||||
|
||||
logfunctions::logfunctions(iofunc_t *iofunc)
|
||||
{
|
||||
prefix = NULL;
|
||||
put(" ");
|
||||
settype(GENLOG);
|
||||
setio(iofunc);
|
||||
// BUG: unfortunately this can be called before the bochsrc is read,
|
||||
// which means that the bochsrc has no effect on the actions.
|
||||
for (int i=0; i<N_LOGLEV; i++)
|
||||
onoff[i] = get_default_action(i);
|
||||
prefix = NULL;
|
||||
put(" ");
|
||||
settype(GENLOG);
|
||||
setio(iofunc);
|
||||
// BUG: unfortunately this can be called before the bochsrc is read,
|
||||
// which means that the bochsrc has no effect on the actions.
|
||||
for (int i=0; i<N_LOGLEV; i++)
|
||||
onoff[i] = get_default_action(i);
|
||||
}
|
||||
|
||||
logfunctions::~logfunctions(void)
|
||||
logfunctions::~logfunctions()
|
||||
{
|
||||
if (this->prefix) free(this->prefix);
|
||||
if (prefix) free(prefix);
|
||||
}
|
||||
|
||||
void logfunctions::setio(iofunc_t *i)
|
||||
{
|
||||
// add pointer to iofunction object to use
|
||||
this->logio = i;
|
||||
// give iofunction a pointer to me
|
||||
i->add_logfn (this);
|
||||
// add pointer to iofunction object to use
|
||||
this->logio = i;
|
||||
// give iofunction a pointer to me
|
||||
i->add_logfn(this);
|
||||
}
|
||||
|
||||
void logfunctions::put(char *p)
|
||||
{
|
||||
char * tmpbuf=strdup("[ ]"); // if we ever have more than 32 chars,
|
||||
// we need to rethink this
|
||||
char * tmpbuf=strdup("[ ]"); // if we ever have more than 32 chars,
|
||||
// we need to rethink this
|
||||
|
||||
if (tmpbuf == NULL)
|
||||
{
|
||||
return; /* allocation not successful */
|
||||
}
|
||||
if (this->prefix != NULL)
|
||||
{
|
||||
free(this->prefix); /* free previously allocated memory */
|
||||
this->prefix = NULL;
|
||||
}
|
||||
int len=strlen(p);
|
||||
for(int i=1;i<len+1;i++) {
|
||||
tmpbuf[i]=p[i-1];
|
||||
}
|
||||
|
||||
switch(len) {
|
||||
case 1: tmpbuf[2]=' ';
|
||||
case 2: tmpbuf[3]=' ';
|
||||
case 3: tmpbuf[4]=' ';
|
||||
case 4: tmpbuf[5]=' ';
|
||||
default: tmpbuf[6]=']'; tmpbuf[7]='\0'; break;
|
||||
}
|
||||
|
||||
this->prefix=tmpbuf;
|
||||
if (tmpbuf == NULL)
|
||||
{
|
||||
return; // allocation not successful
|
||||
}
|
||||
|
||||
if (this->prefix != NULL)
|
||||
{
|
||||
free(this->prefix); // free previously allocated memory
|
||||
prefix = NULL;
|
||||
}
|
||||
|
||||
int len=strlen(p);
|
||||
for(int i=1;i<len+1;i++) {
|
||||
tmpbuf[i]=p[i-1];
|
||||
}
|
||||
|
||||
switch(len) {
|
||||
case 1: tmpbuf[2]=' ';
|
||||
case 2: tmpbuf[3]=' ';
|
||||
case 3: tmpbuf[4]=' ';
|
||||
case 4: tmpbuf[5]=' ';
|
||||
default: tmpbuf[6]=']'; tmpbuf[7]='\0'; break;
|
||||
}
|
||||
|
||||
prefix=tmpbuf;
|
||||
}
|
||||
|
||||
void logfunctions::settype(int t)
|
||||
{
|
||||
type=t;
|
||||
type=t;
|
||||
}
|
||||
|
||||
void logfunctions::info(const char *fmt, ...)
|
||||
{
|
||||
va_list ap;
|
||||
va_list ap;
|
||||
|
||||
assert (this != NULL);
|
||||
assert (this->logio != NULL);
|
||||
assert(this != NULL);
|
||||
assert(this->logio != NULL);
|
||||
|
||||
if(!onoff[LOGLEV_INFO]) return;
|
||||
|
||||
va_start(ap, fmt);
|
||||
this->logio->out(this->type,LOGLEV_INFO,this->prefix, fmt, ap);
|
||||
if (onoff[LOGLEV_INFO] == ACT_ASK)
|
||||
ask (LOGLEV_INFO, this->prefix, fmt, ap);
|
||||
if (onoff[LOGLEV_INFO] == ACT_FATAL)
|
||||
fatal (this->prefix, fmt, ap, 1);
|
||||
va_end(ap);
|
||||
if(!onoff[LOGLEV_INFO]) return;
|
||||
|
||||
va_start(ap, fmt);
|
||||
this->logio->out(this->type,LOGLEV_INFO,this->prefix, fmt, ap);
|
||||
if (onoff[LOGLEV_INFO] == ACT_ASK)
|
||||
ask(LOGLEV_INFO, this->prefix, fmt, ap);
|
||||
if (onoff[LOGLEV_INFO] == ACT_FATAL)
|
||||
fatal(this->prefix, fmt, ap, 1);
|
||||
va_end(ap);
|
||||
}
|
||||
|
||||
void logfunctions::error(const char *fmt, ...)
|
||||
{
|
||||
va_list ap;
|
||||
va_list ap;
|
||||
|
||||
assert (this != NULL);
|
||||
assert (this->logio != NULL);
|
||||
assert(this != NULL);
|
||||
assert(this->logio != NULL);
|
||||
|
||||
if(!onoff[LOGLEV_ERROR]) return;
|
||||
if(!onoff[LOGLEV_ERROR]) return;
|
||||
|
||||
va_start(ap, fmt);
|
||||
this->logio->out(this->type,LOGLEV_ERROR,this->prefix, fmt, ap);
|
||||
if (onoff[LOGLEV_ERROR] == ACT_ASK)
|
||||
ask (LOGLEV_ERROR, this->prefix, fmt, ap);
|
||||
if (onoff[LOGLEV_ERROR] == ACT_FATAL)
|
||||
fatal (this->prefix, fmt, ap, 1);
|
||||
va_end(ap);
|
||||
va_start(ap, fmt);
|
||||
this->logio->out(this->type,LOGLEV_ERROR,this->prefix, fmt, ap);
|
||||
if (onoff[LOGLEV_ERROR] == ACT_ASK)
|
||||
ask(LOGLEV_ERROR, this->prefix, fmt, ap);
|
||||
if (onoff[LOGLEV_ERROR] == ACT_FATAL)
|
||||
fatal(this->prefix, fmt, ap, 1);
|
||||
va_end(ap);
|
||||
}
|
||||
|
||||
void logfunctions::panic(const char *fmt, ...)
|
||||
{
|
||||
va_list ap;
|
||||
va_list ap;
|
||||
|
||||
assert (this != NULL);
|
||||
assert (this->logio != NULL);
|
||||
assert(this != NULL);
|
||||
assert(this->logio != NULL);
|
||||
|
||||
// Special case for panics since they are so important. Always print
|
||||
// the panic to the log, no matter what the log action says.
|
||||
//if(!onoff[LOGLEV_PANIC]) return;
|
||||
// Special case for panics since they are so important. Always print
|
||||
// the panic to the log, no matter what the log action says.
|
||||
//if(!onoff[LOGLEV_PANIC]) return;
|
||||
|
||||
va_start(ap, fmt);
|
||||
this->logio->out(this->type,LOGLEV_PANIC,this->prefix, fmt, ap);
|
||||
va_start(ap, fmt);
|
||||
this->logio->out(this->type,LOGLEV_PANIC,this->prefix, fmt, ap);
|
||||
|
||||
// This fixes a funny bug on linuxppc where va_list is no pointer but a struct
|
||||
va_end(ap);
|
||||
va_start(ap, fmt);
|
||||
// This fixes a funny bug on linuxppc where va_list is no pointer but a struct
|
||||
va_end(ap);
|
||||
va_start(ap, fmt);
|
||||
|
||||
if (onoff[LOGLEV_PANIC] == ACT_ASK)
|
||||
ask (LOGLEV_PANIC, this->prefix, fmt, ap);
|
||||
if (onoff[LOGLEV_PANIC] == ACT_FATAL)
|
||||
fatal (this->prefix, fmt, ap, 1);
|
||||
va_end(ap);
|
||||
if (onoff[LOGLEV_PANIC] == ACT_ASK)
|
||||
ask(LOGLEV_PANIC, this->prefix, fmt, ap);
|
||||
if (onoff[LOGLEV_PANIC] == ACT_FATAL)
|
||||
fatal(this->prefix, fmt, ap, 1);
|
||||
va_end(ap);
|
||||
}
|
||||
|
||||
void logfunctions::pass(const char *fmt, ...)
|
||||
{
|
||||
va_list ap;
|
||||
va_list ap;
|
||||
|
||||
assert (this != NULL);
|
||||
assert (this->logio != NULL);
|
||||
assert(this != NULL);
|
||||
assert(this->logio != NULL);
|
||||
|
||||
// Special case for panics since they are so important. Always print
|
||||
// the panic to the log, no matter what the log action says.
|
||||
//if(!onoff[LOGLEV_PASS]) return;
|
||||
// Special case for panics since they are so important. Always print
|
||||
// the panic to the log, no matter what the log action says.
|
||||
//if(!onoff[LOGLEV_PASS]) return;
|
||||
|
||||
va_start(ap, fmt);
|
||||
this->logio->out(this->type,LOGLEV_PASS,this->prefix, fmt, ap);
|
||||
va_start(ap, fmt);
|
||||
this->logio->out(this->type,LOGLEV_PASS,this->prefix, fmt, ap);
|
||||
|
||||
// This fixes a funny bug on linuxppc where va_list is no pointer but a struct
|
||||
va_end(ap);
|
||||
va_start(ap, fmt);
|
||||
// This fixes a funny bug on linuxppc where va_list is no pointer but a struct
|
||||
va_end(ap);
|
||||
va_start(ap, fmt);
|
||||
|
||||
if (onoff[LOGLEV_PASS] == ACT_ASK)
|
||||
ask (LOGLEV_PASS, this->prefix, fmt, ap);
|
||||
if (onoff[LOGLEV_PASS] == ACT_FATAL)
|
||||
fatal (this->prefix, fmt, ap, 101);
|
||||
va_end(ap);
|
||||
if (onoff[LOGLEV_PASS] == ACT_ASK)
|
||||
ask(LOGLEV_PASS, this->prefix, fmt, ap);
|
||||
if (onoff[LOGLEV_PASS] == ACT_FATAL)
|
||||
fatal(this->prefix, fmt, ap, 101);
|
||||
va_end(ap);
|
||||
}
|
||||
|
||||
void logfunctions::ldebug(const char *fmt, ...)
|
||||
{
|
||||
va_list ap;
|
||||
va_list ap;
|
||||
|
||||
assert (this != NULL);
|
||||
assert (this->logio != NULL);
|
||||
assert(this != NULL);
|
||||
assert(this->logio != NULL);
|
||||
|
||||
if(!onoff[LOGLEV_DEBUG]) return;
|
||||
if(!onoff[LOGLEV_DEBUG]) return;
|
||||
|
||||
va_start(ap, fmt);
|
||||
this->logio->out(this->type,LOGLEV_DEBUG,this->prefix, fmt, ap);
|
||||
if (onoff[LOGLEV_DEBUG] == ACT_ASK)
|
||||
ask (LOGLEV_DEBUG, this->prefix, fmt, ap);
|
||||
if (onoff[LOGLEV_DEBUG] == ACT_FATAL)
|
||||
fatal (this->prefix, fmt, ap, 1);
|
||||
va_end(ap);
|
||||
va_start(ap, fmt);
|
||||
this->logio->out(this->type,LOGLEV_DEBUG,this->prefix, fmt, ap);
|
||||
if (onoff[LOGLEV_DEBUG] == ACT_ASK)
|
||||
ask(LOGLEV_DEBUG, this->prefix, fmt, ap);
|
||||
if (onoff[LOGLEV_DEBUG] == ACT_FATAL)
|
||||
fatal(this->prefix, fmt, ap, 1);
|
||||
va_end(ap);
|
||||
}
|
||||
|
||||
void logfunctions::ask (int level, const char *prefix, const char *fmt, va_list ap)
|
||||
void logfunctions::ask(int level, const char *prefix, const char *fmt, va_list ap)
|
||||
{
|
||||
// Guard against reentry on ask() function. The danger is that some
|
||||
// function that's called within ask() could trigger another
|
||||
@ -441,11 +442,11 @@ void logfunctions::ask (int level, const char *prefix, const char *fmt, va_list
|
||||
static char in_ask_already = 0;
|
||||
char buf1[1024];
|
||||
if (in_ask_already) {
|
||||
fprintf (stderr, "logfunctions::ask() should not reenter!!\n");
|
||||
fprintf(stderr, "logfunctions::ask() should not reenter!!\n");
|
||||
return;
|
||||
}
|
||||
in_ask_already = 1;
|
||||
vsnprintf (buf1, sizeof(buf1), fmt, ap);
|
||||
vsnprintf(buf1, sizeof(buf1), fmt, ap);
|
||||
// FIXME: facility set to 0 because it's unknown.
|
||||
|
||||
// update vga screen. This is useful because sometimes useful messages
|
||||
@ -456,36 +457,36 @@ void logfunctions::ask (int level, const char *prefix, const char *fmt, va_list
|
||||
|
||||
#if !BX_EXTERNAL_DEBUGGER
|
||||
// ensure the text screen is showing
|
||||
SIM->set_display_mode (DISP_MODE_CONFIG);
|
||||
int val = SIM->log_msg (prefix, level, buf1);
|
||||
switch (val)
|
||||
SIM->set_display_mode(DISP_MODE_CONFIG);
|
||||
int val = SIM->log_msg(prefix, level, buf1);
|
||||
switch(val)
|
||||
{
|
||||
case BX_LOG_ASK_CHOICE_CONTINUE:
|
||||
break;
|
||||
case BX_LOG_ASK_CHOICE_CONTINUE_ALWAYS:
|
||||
// user said continue, and don't "ask" for this facility again.
|
||||
setonoff (level, ACT_REPORT);
|
||||
setonoff(level, ACT_REPORT);
|
||||
break;
|
||||
case BX_LOG_ASK_CHOICE_DIE:
|
||||
case BX_LOG_NOTIFY_FAILED:
|
||||
bx_user_quit = (val==BX_LOG_ASK_CHOICE_DIE)?1:0;
|
||||
in_ask_already = 0; // because fatal will longjmp out
|
||||
fatal (prefix, fmt, ap, 1);
|
||||
fatal(prefix, fmt, ap, 1);
|
||||
// should never get here
|
||||
BX_PANIC (("in ask(), fatal() should never return!"));
|
||||
BX_PANIC(("in ask(), fatal() should never return!"));
|
||||
break;
|
||||
case BX_LOG_ASK_CHOICE_DUMP_CORE:
|
||||
fprintf (stderr, "User chose to dump core...\n");
|
||||
fprintf(stderr, "User chose to dump core...\n");
|
||||
#if BX_HAVE_ABORT
|
||||
abort ();
|
||||
abort();
|
||||
#else
|
||||
// do something highly illegal that should kill the process.
|
||||
// Hey, this is fun!
|
||||
{
|
||||
char *crashptr = (char *)0; char c = *crashptr;
|
||||
}
|
||||
fprintf (stderr, "Sorry, I couldn't find your abort() function. Exiting.");
|
||||
exit (0);
|
||||
fprintf(stderr, "Sorry, I couldn't find your abort() function. Exiting.");
|
||||
exit(0);
|
||||
#endif
|
||||
#if BX_DEBUGGER
|
||||
case BX_LOG_ASK_CHOICE_ENTER_DEBUG:
|
||||
@ -493,19 +494,19 @@ void logfunctions::ask (int level, const char *prefix, const char *fmt, va_list
|
||||
// interrupt_requested bit and continue execution. Before the next
|
||||
// instruction, it should notice the user interrupt and return to
|
||||
// the debugger.
|
||||
bx_guard.interrupt_requested = 1;
|
||||
bx_debug_break();
|
||||
break;
|
||||
#endif
|
||||
default:
|
||||
// this happens if panics happen before the callback is initialized
|
||||
// in gui/control.cc.
|
||||
fprintf (stderr, "WARNING: log_msg returned unexpected value %d\n", val);
|
||||
fprintf(stderr, "WARNING: log_msg returned unexpected value %d\n", val);
|
||||
}
|
||||
#else
|
||||
// external debugger ask code goes here
|
||||
#endif
|
||||
// return to simulation mode
|
||||
SIM->set_display_mode (DISP_MODE_SIM);
|
||||
SIM->set_display_mode(DISP_MODE_SIM);
|
||||
in_ask_already = 0;
|
||||
}
|
||||
|
||||
@ -528,7 +529,9 @@ static void carbonFatalDialog(const char *error, const char *exposition)
|
||||
{
|
||||
cfExposition = CFStringCreateWithCString(NULL, exposition, kCFStringEncodingASCII);
|
||||
}
|
||||
else { cfExposition = NULL; }
|
||||
else {
|
||||
cfExposition = NULL;
|
||||
}
|
||||
alertParam.version = kStdCFStringAlertVersionOne;
|
||||
alertParam.defaultText = CFSTR("Quit");
|
||||
alertParam.position = kWindowDefaultPosition;
|
||||
@ -540,14 +543,14 @@ static void carbonFatalDialog(const char *error, const char *exposition)
|
||||
cfExposition, /* can be NULL */
|
||||
&alertParam, /* can be NULL */
|
||||
&alertDialog);
|
||||
RunStandardAlert( alertDialog, NULL, &index);
|
||||
RunStandardAlert(alertDialog, NULL, &index);
|
||||
// Cleanup
|
||||
CFRelease( cfError );
|
||||
if( cfExposition != NULL ) { CFRelease( cfExposition ); }
|
||||
CFRelease(cfError);
|
||||
if(cfExposition != NULL) { CFRelease(cfExposition); }
|
||||
}
|
||||
#endif
|
||||
|
||||
void logfunctions::fatal (const char *prefix, const char *fmt, va_list ap, int exit_status)
|
||||
void logfunctions::fatal(const char *prefix, const char *fmt, va_list ap, int exit_status)
|
||||
{
|
||||
bx_atexit();
|
||||
#if BX_WITH_CARBON
|
||||
@ -555,28 +558,28 @@ void logfunctions::fatal (const char *prefix, const char *fmt, va_list ap, int e
|
||||
{
|
||||
char buf1[1024];
|
||||
char buf2[1024];
|
||||
vsnprintf (buf1, sizeof(buf1), fmt, ap);
|
||||
snprintf (buf2, sizeof(buf2), "Bochs startup error\n%s", buf1);
|
||||
vsnprintf(buf1, sizeof(buf1), fmt, ap);
|
||||
snprintf(buf2, sizeof(buf2), "Bochs startup error\n%s", buf1);
|
||||
carbonFatalDialog(buf2,
|
||||
"For more information, try running Bochs within Terminal by clicking on \"bochs.scpt\".");
|
||||
}
|
||||
#endif
|
||||
#if !BX_WITH_WX
|
||||
static char *divider = "========================================================================";
|
||||
fprintf (stderr, "%s\n", divider);
|
||||
fprintf (stderr, "Bochs is exiting with the following message:\n");
|
||||
fprintf (stderr, "%s ", prefix);
|
||||
vfprintf (stderr, fmt, ap);
|
||||
fprintf (stderr, "\n%s\n", divider);
|
||||
fprintf(stderr, "%s\n", divider);
|
||||
fprintf(stderr, "Bochs is exiting with the following message:\n");
|
||||
fprintf(stderr, "%s ", prefix);
|
||||
vfprintf(stderr, fmt, ap);
|
||||
fprintf(stderr, "\n%s\n", divider);
|
||||
#endif
|
||||
#if 0 && defined(WIN32)
|
||||
#error disabled because it is not working yet!
|
||||
// wait for a keypress before quitting. Depending on how bochs is
|
||||
// installed, the console window can disappear before the user has
|
||||
// a chance to read the final message.
|
||||
fprintf (stderr, "\n\nPress Enter to exit...\n");
|
||||
fprintf(stderr, "\n\nPress Enter to exit...\n");
|
||||
char buf[8];
|
||||
fgets (buf, 8, stdin);
|
||||
fgets(buf, 8, stdin);
|
||||
#endif
|
||||
#if !BX_DEBUGGER
|
||||
BX_EXIT(exit_status);
|
||||
@ -588,18 +591,18 @@ void logfunctions::fatal (const char *prefix, const char *fmt, va_list ap, int e
|
||||
}
|
||||
#endif
|
||||
// not safe to use BX_* log functions in here.
|
||||
fprintf (stderr, "fatal() should never return, but it just did\n");
|
||||
fprintf(stderr, "fatal() should never return, but it just did\n");
|
||||
}
|
||||
|
||||
iofunc_t *io = NULL;
|
||||
logfunc_t *genlog = NULL;
|
||||
|
||||
void bx_center_print (FILE *file, char *line, int maxwidth)
|
||||
void bx_center_print(FILE *file, char *line, int maxwidth)
|
||||
{
|
||||
int len = strlen(line);
|
||||
if (len > maxwidth)
|
||||
BX_PANIC (("bx_center_print: line is too long: '%s'", line));
|
||||
BX_PANIC(("bx_center_print: line is too long: '%s'", line));
|
||||
int imax = (maxwidth - len) >> 1;
|
||||
for (int i=0; i<imax; i++) fputc (' ', file);
|
||||
fputs (line, file);
|
||||
for (int i=0; i<imax; i++) fputc(' ', file);
|
||||
fputs(line, file);
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user