Prepared siminterface and logio code for the implementation of a log viewer

for watching the log output at simulation time. This feature has been prepared
and described in the code (BX_ASYNC_EVT_LOG_MSG), but it was never implemented.
A viewer window could be implemented easily in wx. The gui debugger could also
have an option to view the log output while debugging.
This commit is contained in:
Volker Ruppert 2014-01-12 08:26:04 +00:00
parent af29c8bd60
commit bace4d0c6b
3 changed files with 52 additions and 22 deletions

View File

@ -2,7 +2,7 @@
// $Id$
/////////////////////////////////////////////////////////////////////////
//
// Copyright (C) 2002-2013 The Bochs Project
// Copyright (C) 2002-2014 The Bochs Project
//
// This library is free software; you can redistribute it and/or
// modify it under the terms of the GNU Lesser General Public
@ -74,6 +74,7 @@ class bx_real_sim_c : public bx_simulator_interface_c {
int exit_code;
unsigned param_id;
bx_bool bx_debug_gui;
bx_bool bx_log_viewer;
bx_bool wxsel;
public:
bx_real_sim_c();
@ -119,7 +120,10 @@ public:
virtual void set_notify_callback(bxevent_handler func, void *arg);
virtual void get_notify_callback(bxevent_handler *func, void **arg);
virtual BxEvent* sim_to_ci_event(BxEvent *event);
virtual int log_msg(const char *prefix, int level, const char *msg);
virtual int log_ask(const char *prefix, int level, const char *msg);
virtual void log_msg(const char *prefix, int level, const char *msg);
virtual void set_log_viewer(bx_bool val) { bx_log_viewer = val; }
virtual bx_bool has_log_viewer() const { return bx_log_viewer; }
virtual int ask_param(bx_param_c *param);
virtual int ask_param(const char *pname);
// ask the user for a pathname
@ -331,6 +335,7 @@ bx_real_sim_c::bx_real_sim_c()
ci_callback_data = NULL;
is_sim_thread_func = NULL;
bx_debug_gui = 0;
bx_log_viewer = 0;
wxsel = 0;
enabled = 1;
@ -538,7 +543,7 @@ BxEvent *bx_real_sim_c::sim_to_ci_event(BxEvent *event)
}
// returns 0 for continue, 1 for alwayscontinue, 2 for die.
int bx_real_sim_c::log_msg(const char *prefix, int level, const char *msg)
int bx_real_sim_c::log_ask(const char *prefix, int level, const char *msg)
{
BxEvent be;
be.type = BX_SYNC_EVT_LOG_ASK;
@ -552,6 +557,19 @@ int bx_real_sim_c::log_msg(const char *prefix, int level, const char *msg)
return be.retcode;
}
void bx_real_sim_c::log_msg(const char *prefix, int level, const char *msg)
{
if (SIM->has_log_viewer()) {
// send message to the log viewer
BxEvent *event = new BxEvent();
event->type = BX_ASYNC_EVT_LOG_MSG;
event->u.logmsg.prefix = strdup(prefix);
event->u.logmsg.level = level;
event->u.logmsg.msg = strdup(msg);
sim_to_ci_event(event);
}
}
// Called by simulator whenever it needs the user to choose a new value
// for a registered parameter. Create a synchronous ASK_PARAM event,
// send it to the CI, and wait for the response. The CI will call the

View File

@ -2,7 +2,7 @@
// $Id$
/////////////////////////////////////////////////////////////////////////
//
// Copyright (C) 2001-2013 The Bochs Project
// Copyright (C) 2001-2014 The Bochs Project
//
// This library is free software; you can redistribute it and/or
// modify it under the terms of the GNU Lesser General Public
@ -371,7 +371,7 @@ typedef struct {
// some kind of "flow control" since the simulator will be able to produce
// new events much faster than the gui can accept them.
// Event type: BX_ASYNC_EVT_LOG_MSG (unused)
// Event type: BX_ASYNC_EVT_LOG_MSG
//
// Asynchronous event from the simulator to the CI. When a BX_PANIC,
// BX_ERROR, BX_INFO, or BX_DEBUG is found in the simulator code, this
@ -694,7 +694,12 @@ public:
// called from simulator when it hits serious errors, to ask if the user
// wants to continue or not
virtual int log_msg(const char *prefix, int level, const char *msg) {return -1;}
virtual int log_ask(const char *prefix, int level, const char *msg) {return -1;}
// called from simulator when writing a message to log file
virtual void log_msg(const char *prefix, int level, const char *msg) {}
// set this to 1 if the gui has a log viewer
virtual void set_log_viewer(bx_bool val) {}
virtual bx_bool has_log_viewer() const {return 0;}
// tell the CI to ask the user for the value of a parameter.
virtual int ask_param(bx_param_c *param) {return -1;}

View File

@ -2,7 +2,7 @@
// $Id$
/////////////////////////////////////////////////////////////////////////
//
// Copyright (C) 2001-2013 The Bochs Project
// Copyright (C) 2001-2014 The Bochs Project
//
// This library is free software; you can redistribute it and/or
// modify it under the terms of the GNU Lesser General Public
@ -177,6 +177,8 @@ void iofunctions::set_log_prefix(const char* prefix)
void iofunctions::out(int level, const char *prefix, const char *fmt, va_list ap)
{
char c = ' ', *s;
char tmpstr[80], msgpfx[80], msg[1024];
assert(magic==MAGIC_LOGNUM);
assert(this != NULL);
assert(logfd != NULL);
@ -190,6 +192,7 @@ void iofunctions::out(int level, const char *prefix, const char *fmt, va_list ap
}
s = logprefix;
msgpfx[0] = 0;
while (*s) {
switch (*s) {
case '%':
@ -197,40 +200,44 @@ void iofunctions::out(int level, const char *prefix, const char *fmt, va_list ap
else break;
switch(*s) {
case 'd':
fprintf(logfd, "%s", prefix==NULL?"":prefix);
sprintf(tmpstr, "%s", prefix==NULL?"":prefix);
break;
case 't':
fprintf(logfd, FMT_TICK, bx_pc_system.time_ticks());
sprintf(tmpstr, FMT_TICK, bx_pc_system.time_ticks());
break;
case 'i':
#if BX_SUPPORT_SMP == 0
fprintf(logfd, "%08x", BX_CPU(0)->get_eip());
sprintf(tmpstr, "%08x", BX_CPU(0)->get_eip());
#endif
break;
case 'e':
fprintf(logfd, "%c", c);
sprintf(tmpstr, "%c", c);
break;
case '%':
fprintf(logfd,"%%");
sprintf(tmpstr,"%%");
break;
default:
fprintf(logfd,"%%%c",*s);
sprintf(tmpstr,"%%%c",*s);
}
break;
default:
fprintf(logfd,"%c",*s);
sprintf(tmpstr,"%c",*s);
}
strcat(msgpfx, tmpstr);
s++;
}
fprintf(logfd," ");
fprintf(logfd,"%s ", msgpfx);
if(level==LOGLEV_PANIC)
fprintf(logfd, ">>PANIC<< ");
vfprintf(logfd, fmt, ap);
fprintf(logfd, "\n");
vsnprintf(msg, sizeof(msg), fmt, ap);
fprintf(logfd, "%s\n", msg);
fflush(logfd);
if (SIM->has_log_viewer()) {
SIM->log_msg(msgpfx, level, msg);
}
}
iofunctions::iofunctions(FILE *fs)
@ -458,7 +465,7 @@ void logfunctions::ask(int level, const char *prefix, const char *fmt, va_list a
// ensure the text screen is showing
SIM->set_display_mode(DISP_MODE_CONFIG);
int val = SIM->log_msg(prefix, level, buf1);
int val = SIM->log_ask(prefix, level, buf1);
switch(val)
{
case BX_LOG_ASK_CHOICE_CONTINUE: