use enhanced gui debugger instead of classic wx debugger if BX_DEBUGGER_GUI == 1

The Windows version looks almost stable, but the GTK version fails in some cases.
That's why the classic wx debugger is still available if BX_DEBUGGER_GUI is set to 0.
- added function close_debug_dialog() to handle the simulation stop case in wx
- disable all the wx debugger related code if BX_DEBUGGER_GUI is set to 1
- added enhanced debugger specific init code similar to the code in sdl.cc
- include debugger related resources on Windows
- TODO: make the GTK / wxGTK case stable and remove the wx debugger
This commit is contained in:
Volker Ruppert 2013-02-12 21:08:35 +00:00
parent 9c8c25b7ef
commit 97de484efb
14 changed files with 150 additions and 13 deletions

View File

@ -1423,7 +1423,7 @@ public: // for now...
void initialize(void);
void after_restore_state(void);
void register_state(void);
#if BX_WITH_WX
#if BX_WITH_WX && !BX_DEBUGGER_GUI
void register_wx_state(void);
#endif
static Bit64s param_save_handler(void *devptr, bx_param_c *param);

View File

@ -57,7 +57,7 @@ BX_CPU_C::BX_CPU_C(unsigned id): bx_cpuid(id)
srand(time(NULL)); // initialize random generator for RDRAND/RDSEED
}
#if BX_WITH_WX
#if BX_WITH_WX && !BX_DEBUGGER_GUI
#define IF_SEG_REG_GET(x) \
if (!strcmp(param->get_name(), #x)) { \
@ -227,12 +227,12 @@ void BX_CPU_C::initialize(void)
init_VMCS();
#endif
#if BX_WITH_WX
#if BX_WITH_WX && !BX_DEBUGGER_GUI
register_wx_state();
#endif
}
#if BX_WITH_WX
#if BX_WITH_WX && !BX_DEBUGGER_GUI
void BX_CPU_C::register_wx_state(void)
{
if (SIM->get_param(BXPN_WX_CPU_STATE) != NULL) {

View File

@ -3380,8 +3380,13 @@ void ActivateMenuItem (int cmd)
void InitDebugDialog()
{
DoAllInit(); // non-os-specific init stuff
OSInit();
DoAllInit(); // non-os-specific init stuff
OSInit();
}
void CloseDebugDialog()
{
CloseDialog();
}
#endif

View File

@ -66,6 +66,7 @@ int GetNextSelectedLI(int listnum, int StartPt);
bx_bool OSInit();
void SpecialInit();
void CloseDialog();
void HitBreak();
void ParseIDText(const char *x);

View File

@ -2334,6 +2334,11 @@ bx_bool OSInit()
return TRUE;
}
void CloseDialog()
{
gtk_widget_destroy(window);
}
// recurse displaying each leaf/branch of param_tree -- with values for each leaf
void MakeBL(TreeParent *h_P, bx_param_c *p)
{

View File

@ -1015,4 +1015,10 @@ void bx_gui_c::init_debug_dialog()
extern void InitDebugDialog();
InitDebugDialog();
}
void bx_gui_c::close_debug_dialog()
{
extern void CloseDebugDialog();
CloseDebugDialog();
}
#endif

View File

@ -158,6 +158,7 @@ public:
const char* get_toggle_info(void);
#if BX_DEBUGGER && BX_DEBUGGER_GUI
void init_debug_dialog(void);
void close_debug_dialog(void);
#endif
protected:

View File

@ -1821,6 +1821,11 @@ bx_bool OSInit()
return TRUE;
}
void CloseDialog()
{
SendMessage(hY, WM_CLOSE, 0, 0);
}
// recurse displaying each leaf/branch of param_tree -- with values for each leaf
void MakeBL(HTREEITEM *h_P, bx_param_c *p)
{

View File

@ -121,6 +121,11 @@ static bx_bool wx_hide_ips = 0;
#if defined (wxHAS_RAW_KEY_CODES) && defined(__WXGTK__)
static Bit32u convertStringToGDKKey (const char *string);
#endif
#if BX_DEBUGGER && BX_DEBUGGER_GUI
BxEvent *wx_notify_callback (void *unused, BxEvent *event);
static bxevent_handler old_callback = NULL;
static void *old_callback_arg = NULL;
#endif
//////////////////////////////////////////////////////////////
@ -922,6 +927,20 @@ bx_bool MyPanel::fillBxKeyEvent(wxKeyEvent& wxev, BxKeyEvent& bxev, bx_bool rele
// fill in methods of bx_gui
//////////////////////////////////////////////////////////////
#if defined(WIN32) && BX_DEBUGGER && BX_DEBUGGER_GUI
DWORD WINAPI DebugGuiThread(LPVOID)
{
MSG msg;
bx_gui->init_debug_dialog();
while (GetMessage(&msg, NULL, 0, 0)) {
TranslateMessage(&msg);
DispatchMessage(&msg);
}
return 0;
}
#endif
void bx_wx_gui_c::specific_init(int argc, char **argv, unsigned headerbar_y)
{
int b,i,j;
@ -989,6 +1008,22 @@ void bx_wx_gui_c::specific_init(int argc, char **argv, unsigned headerbar_y)
}
}
#if BX_DEBUGGER && BX_DEBUGGER_GUI
// redirect notify callback to wx specific code
SIM->get_notify_callback(&old_callback, &old_callback_arg);
assert(old_callback != NULL);
SIM->set_notify_callback(wx_notify_callback, NULL);
#ifdef WIN32
// on Windows the debugger gui must run in a separate thread
DWORD threadID;
CreateThread(NULL, 0, DebugGuiThread, NULL, 0, &threadID);
#else
wxMutexGuiEnter();
init_debug_dialog();
wxMutexGuiLeave();
#endif
#endif
new_gfx_api = 1;
dialog_caps = BX_GUI_DLG_USER | BX_GUI_DLG_SNAPSHOT | BX_GUI_DLG_SAVE_RESTORE;
}
@ -1640,6 +1675,10 @@ bx_wx_gui_c::replace_bitmap(unsigned hbar_id, unsigned bmap_id)
void bx_wx_gui_c::exit(void)
{
clear_screen();
#if BX_DEBUGGER && BX_DEBUGGER_GUI
SIM->set_notify_callback(old_callback, old_callback_arg);
close_debug_dialog();
#endif
}
void bx_wx_gui_c::mouse_enabled_changed_specific(bx_bool val)
@ -1728,4 +1767,47 @@ static Bit32u convertStringToGDKKey (const char *string)
}
#endif
#if BX_DEBUGGER && BX_DEBUGGER_GUI
#include "enh_dbg.h"
BxEvent *wx_notify_callback(void *unused, BxEvent *event)
{
switch (event->type)
{
case BX_SYNC_EVT_GET_DBG_COMMAND:
{
debug_cmd = new char[512];
debug_cmd_ready = 0;
HitBreak();
while (debug_cmd_ready == 0 && bx_user_quit == 0)
{
if (vgaw_refresh != 0) // is the GUI frontend requesting a VGAW refresh?
SIM->refresh_vga();
vgaw_refresh = 0;
#ifdef WIN32
Sleep(10);
#elif BX_HAVE_USLEEP
usleep(10000);
#else
sleep(1);
#endif
}
if (bx_user_quit != 0) {
bx_dbg_exit(0);
}
event->u.debugcmd.command = debug_cmd;
event->retcode = 1;
return event;
}
case BX_ASYNC_EVT_DBG_MSG:
{
ParseIDText(event->u.logmsg.msg);
return event;
}
default:
return (*old_callback)(old_callback_arg, event);
}
}
#endif /* if BX_DEBUGGER && BX_DEBUGGER_GUI */
#endif /* if BX_WITH_WX */

View File

@ -400,7 +400,7 @@ void AdvancedLogOptionsDialog::ShowHelp()
wxMessageBox(MSG_NO_HELP, MSG_NO_HELP_CAPTION, wxOK | wxICON_ERROR, this);
}
#if BX_DEBUGGER
#if BX_DEBUGGER && !BX_DEBUGGER_GUI
//////////////////////////////////////////////////////////////////////
// DebugLogDialog implementation
//////////////////////////////////////////////////////////////////////
@ -1310,6 +1310,7 @@ void ParamDialog::ShowHelp()
// - col2: flexgrid
// - CR* params
#if !BX_DEBUGGER_GUI
// all events go to OnEvent method
BEGIN_EVENT_TABLE(CpuRegistersDialog, wxDialog)
EVT_BUTTON(-1, CpuRegistersDialog::OnEvent)
@ -1512,6 +1513,7 @@ void CpuRegistersDialog::OnEvent(wxCommandEvent& event)
ParamDialog::OnEvent(event);
}
}
#endif
//////////////////////////////////////////////////////////////////////
// FloppyConfigDialog implementation

View File

@ -168,7 +168,7 @@ DECLARE_EVENT_TABLE()
};
#if BX_DEBUGGER
#if BX_DEBUGGER && !BX_DEBUGGER_GUI
////////////////////////////////////////////////////////////////////////////
// DebugLogDialog
////////////////////////////////////////////////////////////////////////////
@ -430,6 +430,7 @@ public:
// | [Go] [Stop] [Step] [Step N] N=[____] |
// +---------------------------------------------------------+
//
#if !BX_DEBUGGER_GUI
class CpuRegistersDialog : public ParamDialog
{
@ -482,6 +483,7 @@ public:
virtual void CopyParamToGui();
DECLARE_EVENT_TABLE()
};
#endif
/**************************************************************************

View File

@ -202,6 +202,7 @@ extern "C" int libwx_LTX_plugin_init(plugin_t *plugin, plugintype_t type,
wxLogDebug(wxT("installing %s as the Bochs GUI"), wxT("wxWidgets"));
SIM->get_param_enum(BXPN_SEL_DISPLAY_LIBRARY)->set_enabled(0);
MyPanel::OnPluginInit();
#if !BX_DEBUGGER_GUI
bx_list_c *list = new bx_list_c(SIM->get_param("."),
"wxdebug",
"subtree for the wx debugger"
@ -211,6 +212,7 @@ extern "C" int libwx_LTX_plugin_init(plugin_t *plugin, plugintype_t type,
"CPU State"
);
cpu->set_options(bx_list_c::USE_TAB_WINDOW);
#endif
return 0; // success
}
@ -344,9 +346,11 @@ BEGIN_EVENT_TABLE(MyFrame, wxFrame)
EVT_MENU(ID_Edit_Other, MyFrame::OnEditOther)
EVT_MENU(ID_Log_Prefs, MyFrame::OnLogPrefs)
EVT_MENU(ID_Log_PrefsDevice, MyFrame::OnLogPrefsDevice)
#if !BX_DEBUGGER_GUI
EVT_MENU(ID_Debug_ShowCpu, MyFrame::OnShowCpu)
#if BX_DEBUGGER
EVT_MENU(ID_Debug_Console, MyFrame::OnDebugLog)
#endif
#endif
// toolbar events
EVT_TOOL(ID_Edit_FD_0, MyFrame::OnToolbarClick)
@ -423,9 +427,11 @@ MyFrame::MyFrame(const wxString& title, const wxPoint& pos, const wxSize& size,
// init variables
sim_thread = NULL;
start_bochs_times = 0;
#if !BX_DEBUGGER_GUI
showCpu = NULL;
debugCommand = NULL;
debugCommandEvent = NULL;
#endif
// set up the gui
menuConfiguration = new wxMenu;
@ -466,10 +472,12 @@ MyFrame::MyFrame(const wxString& title, const wxPoint& pos, const wxSize& size,
menuSimulate->Enable(ID_Simulate_PauseResume, FALSE);
menuSimulate->Enable(ID_Simulate_Stop, FALSE);
#if !BX_DEBUGGER_GUI
menuDebug = new wxMenu;
menuDebug->Append(ID_Debug_ShowCpu, wxT("Show &CPU"));
#if BX_DEBUGGER
menuDebug->Append(ID_Debug_Console, wxT("Debug Console"));
#endif
#endif
menuLog = new wxMenu;
@ -484,7 +492,9 @@ MyFrame::MyFrame(const wxString& title, const wxPoint& pos, const wxSize& size,
menuBar->Append(menuConfiguration, wxT("&File"));
menuBar->Append(menuEdit, wxT("&Edit"));
menuBar->Append(menuSimulate, wxT("&Simulate"));
#if !BX_DEBUGGER_GUI
menuBar->Append(menuDebug, wxT("&Debug"));
#endif
menuBar->Append(menuLog, wxT("&Log"));
menuBar->Append(menuHelp, wxT("&Help"));
SetMenuBar(menuBar);
@ -539,7 +549,7 @@ MyFrame::MyFrame(const wxString& title, const wxPoint& pos, const wxSize& size,
SetAutoLayout(TRUE);
SetSizer(sz);
#if BX_DEBUGGER
#if BX_DEBUGGER && !BX_DEBUGGER_GUI
// create the debug log dialog box immediately so that we can write output
// to it.
showDebugLog = new DebugLogDialog(this, -1);
@ -810,6 +820,7 @@ void MyFrame::OnLogPrefsDevice(wxCommandEvent& WXUNUSED(event))
// interrupt the simulation, you want to force an update. If you manually
// change a parameter, you would force an update.
// When simulation is free running, #1 or #2 might make sense. Try #2.
#if !BX_DEBUGGER_GUI
void MyFrame::OnShowCpu(wxCommandEvent& WXUNUSED(event))
{
if (SIM->get_param(BXPN_WX_CPU0_STATE) == NULL) {
@ -888,6 +899,7 @@ void MyFrame::DebugCommand(const char *cmd)
}
}
#endif
#endif
void MyFrame::OnQuit(wxCommandEvent& event)
{
@ -931,7 +943,7 @@ void MyFrame::simStatusChanged(StatusChange change, bx_bool popupNotify) {
menuSimulate->Enable(ID_Simulate_PauseResume, FALSE);
menuSimulate->Enable(ID_Simulate_Stop, FALSE);
menuSimulate->SetLabel(ID_Simulate_PauseResume, wxT("&Pause"));
#if BX_DEBUGGER
#if BX_DEBUGGER && !BX_DEBUGGER_GUI
showDebugLog->Show(FALSE);
#endif
// This should only be used if the simulation stops due to error.
@ -1055,7 +1067,7 @@ void MyFrame::OnKillSim(wxCommandEvent& WXUNUSED(event))
// OnSimThreadExit, which also tries to lock sim_thread_lock.
// If we grab the lock at this level, deadlock results.
wxLogDebug(wxT("OnKillSim()"));
#if BX_DEBUGGER
#if BX_DEBUGGER && !BX_DEBUGGER_GUI
// the sim_thread may be waiting for a debugger command. If so, send
// it a "quit"
DebugCommand("quit");
@ -1180,9 +1192,11 @@ void MyFrame::OnSim2CIEvent(wxCommandEvent& event)
// all cases should return. sync event handlers MUST send back a
// response. async event handlers MUST delete the event.
switch (be->type) {
#if !BX_DEBUGGER_GUI
case BX_ASYNC_EVT_REFRESH:
RefreshDialogs();
break;
#endif
case BX_SYNC_EVT_ASK_PARAM:
wxLogDebug(wxT("before HandleAskParam"));
be->retcode = HandleAskParam(be);
@ -1191,7 +1205,7 @@ void MyFrame::OnSim2CIEvent(wxCommandEvent& event)
sim_thread->SendSyncResponse(be);
wxLogDebug(wxT("after SendSyncResponse"));
break;
#if BX_DEBUGGER
#if BX_DEBUGGER && !BX_DEBUGGER_GUI
case BX_ASYNC_EVT_DBG_MSG:
showDebugLog->AppendText(wxString(be->u.logmsg.msg, wxConvUTF8));
break;
@ -1200,6 +1214,7 @@ void MyFrame::OnSim2CIEvent(wxCommandEvent& event)
case BX_ASYNC_EVT_LOG_MSG:
OnLogMsg(be);
break;
#if !BX_DEBUGGER_GUI
case BX_SYNC_EVT_GET_DBG_COMMAND:
wxLogDebug(wxT("BX_SYNC_EVT_GET_DBG_COMMAND received"));
if (debugCommand == NULL) {
@ -1223,6 +1238,7 @@ void MyFrame::OnSim2CIEvent(wxCommandEvent& event)
sim_thread->SendSyncResponse(be);
}
break;
#endif
case BX_ASYNC_EVT_QUIT_SIM:
wxMessageBox(wxT("Bochs simulation has stopped."), wxT("Bochs Stopped"),
wxOK | wxICON_INFORMATION, this);
@ -1352,6 +1368,7 @@ void MyFrame::OnToolbarClick(wxCommandEvent& event)
}
// warning: This can be called from the simulator thread!!!
#if !BX_DEBUGGER_GUI
bool MyFrame::WantRefresh()
{
bool anyShowing = false;
@ -1363,6 +1380,7 @@ void MyFrame::RefreshDialogs()
{
if (showCpu!=NULL && showCpu->IsShowing()) showCpu->CopyParamToGui();
}
#endif
//////////////////////////////////////////////////////////////////////
// Simulation Thread
@ -1466,11 +1484,13 @@ BxEvent *SimThread::SiminterfaceCallback2(BxEvent *event)
return event;
}
#if !BX_DEBUGGER_GUI
// prune refresh events if the frame is going to ignore them anyway
if (event->type == BX_ASYNC_EVT_REFRESH && !theFrame->WantRefresh()) {
delete event;
return NULL;
}
#endif
//encapsulate the bxevent in a wxwidgets event
wxCommandEvent wxevent(wxEVT_COMMAND_MENU_SELECTED, ID_Sim2CI_Event);

View File

@ -58,8 +58,10 @@ enum
ID_Simulate_Start,
ID_Simulate_PauseResume,
ID_Simulate_Stop,
#if !BX_DEBUGGER_GUI
ID_Debug_ShowCpu,
ID_Debug_Console,
#endif
ID_Log_View,
ID_Log_Prefs,
ID_Log_PrefsDevice,
@ -189,12 +191,14 @@ public:
void OnLogPrefs(wxCommandEvent& event);
void OnLogPrefsDevice(wxCommandEvent& event);
void OnEditATA(wxCommandEvent& event);
#if !BX_DEBUGGER_GUI
void OnShowCpu(wxCommandEvent& event);
#if BX_DEBUGGER
void OnDebugLog(wxCommandEvent& event);
void DebugBreak();
void DebugCommand(wxString string);
void DebugCommand(const char *cmd);
#endif
#endif
void editFloppyConfig(int drive);
void editFirstCdrom();
@ -217,6 +221,7 @@ private:
wxMenu *menuLog;
wxMenu *menuHelp;
wxToolBar *bxToolBar;
#if !BX_DEBUGGER_GUI
ParamDialog *showCpu;
#if BX_DEBUGGER
DebugLogDialog *showDebugLog;
@ -224,8 +229,11 @@ private:
void RefreshDialogs();
char *debugCommand; // maybe need lock on this
BxEvent *debugCommandEvent; // maybe need lock on this
#endif
public:
#if !BX_DEBUGGER_GUI
bool WantRefresh();
#endif
DECLARE_EVENT_TABLE()
};

View File

@ -1,7 +1,7 @@
#include "config.h"
icon_bochs ICON build\win32\nsis\bochs.ico
#include "wx/msw/wx.rc"
#if BX_WITH_WIN32
#if BX_WITH_WIN32 || BX_DEBUGGER_GUI
#include "win32res.rc"
#else
#include "bxversion.rc"