Skip to content

Commit

Permalink
Debugger always enabled (#197)
Browse files Browse the repository at this point in the history
Please re-generate configure script before use :)

Allow to have debugger and non-debugger version in same binary.

Just compile Bochs with --enable-debugger and specify -debugger option
in command line - and it run Bochs internal debugger. If -debugger not
supplied it will run normal optimized build.

This is first draft of the idea provided for initial testing.

When -debugger is not supplied emulation speed is affected ~1% which I
think if very reasonable taking into account extra capability.

When -debugger is supplied the emulation speed is affected severely as
before.

There are potential ways how to make debugger cost cheaper (not
addressed here yet):
- data watchpoints could be implemented in cheap way so they won't cost
any emulation performance if not used (meaning there are no active
watchpoints set).
- similarly code breakpoints could be optimized using the same
mechanisms

Also:
- it would be nice to have GUI debugger button which will switch into
debugger even if started as 'optimized'
and if already done it would be nice to do 'optimized continue' which
will switch to fast mode until some even drops you into the debugger
back.

Also code is just hacky for now, will be improving the logic while doing
more testing.
Especially need to test without handlers chaining compiled and when SMP
is enabled.

For now I need as much feedback as possible.
What to improve ?
Bugs ?
How to make it more user friendly ?

---------

Co-authored-by: Stanislav Shwartsman <[email protected]>
Co-authored-by: Stanislav Shwartsman <[email protected]>
  • Loading branch information
3 people authored Nov 28, 2024
1 parent 05954ee commit 119af93
Show file tree
Hide file tree
Showing 32 changed files with 364 additions and 324 deletions.
6 changes: 6 additions & 0 deletions bochs/.conf.gh-build-test
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,8 @@ case $which_config in
--enable-e1000 \
--enable-plugins \
--enable-show-ips \
--enable-debugger \
--enable-debugger-gui \
--with-all-libs
;;
nothing)
Expand Down Expand Up @@ -118,6 +120,8 @@ case $which_config in
--enable-es1370 \
--enable-ne2000 \
--enable-e1000 \
--enable-debugger \
--enable-debugger-gui \
--enable-show-ips
;;
x86-64)
Expand All @@ -137,6 +141,8 @@ case $which_config in
--enable-es1370 \
--enable-ne2000 \
--enable-e1000 \
--enable-debugger \
--enable-debugger-gui \
--enable-show-ips
;;
*) echo "Unknown config \"$1\" selected!" ;;
Expand Down
4 changes: 4 additions & 0 deletions bochs/.conf.linux
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,8 @@ case $which_config in
--enable-es1370 \
--enable-e1000 \
--enable-show-ips \
--enable-debugger \
--enable-debugger-gui \
${CONFIGURE_ARGS}
;;

Expand Down Expand Up @@ -84,6 +86,8 @@ case $which_config in
--enable-e1000 \
--enable-plugins \
--enable-show-ips \
--enable-debugger \
--enable-debugger-gui \
--with-all-libs \
${CONFIGURE_ARGS}
;;
Expand Down
2 changes: 2 additions & 0 deletions bochs/.conf.win32-cygwin
Original file line number Diff line number Diff line change
Expand Up @@ -38,4 +38,6 @@ export CXXFLAGS
--enable-e1000 \
--enable-show-ips \
--with-win32 --with-rfb --with-nogui \
--enable-debugger \
--enable-debugger-gui \
${CONFIGURE_ARGS}
43 changes: 0 additions & 43 deletions bochs/.conf.win32-cygwin-debugger

This file was deleted.

2 changes: 2 additions & 0 deletions bochs/.conf.win32-vcpp
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,8 @@ set echo
--enable-es1370 \
--enable-e1000 \
--enable-show-ips \
--enable-debugger \
--enable-debugger-gui \
--disable-readline \
--without-x \
--with-win32 --with-rfb --with-nogui
Expand Down
2 changes: 2 additions & 0 deletions bochs/.conf.win64-cross-mingw32
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,8 @@ export DLLTOOL
--enable-es1370 \
--enable-e1000 \
--enable-show-ips \
--enable-debugger \
--enable-debugger-gui \
--disable-readline \
--with-win32 --with-rfb --with-nogui \
${CONFIGURE_ARGS}
2 changes: 2 additions & 0 deletions bochs/.conf.win64-vcpp
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,8 @@ set echo
--enable-es1370 \
--enable-e1000 \
--enable-show-ips \
--enable-debugger \
--enable-debugger-gui \
--disable-readline \
--without-x \
--with-win32 --with-rfb --with-nogui
Expand Down
14 changes: 12 additions & 2 deletions bochs/CHANGES
Original file line number Diff line number Diff line change
@@ -1,16 +1,18 @@
Changes after 2.8:

Brief summary :
- Include Bochs debugger support in all release binaries.
Bochs internal debugger and Bochs GUI debugger are compiled by in by default and there are no special Bochs binaries with internal debugger support anymore.
- Integrated softfloat3e library replacing older softfloat2a fpu-emulation code
- Bugfixes for CPU emulation correctness (critical bugfixes for WAITPKG, LASS, XSAVEC/XSAVES, CPUID and SHA1 ISA implementation)
- Implemented AVX512_FP16 Intel instruction set based on softfloat3e library (enabled in Xeon Sapphire Rapids CPU definition)
- Implemented MONITORLESS MWAIT instructions support
- Implemented initial support for AVX10_1 + AVX10_2 ISA extensions and AVX10 CPUID leaf 0x24 (AVX10_1 first to be enabled in Xeon Granite Rapids)
- Implemented AMX-TF32 and AMX-AVX512 ISA extensions
- Implemented RAO-INT ISA extension
- CPUID: Added new CPU definitions: for i386 CPU, i486DX4 CPU and Intel Core i5 Arrow Lake CPU
- CPUID: Support for enabling/disabling of one of more CPU features from CPUID configuration (see "add_features" and "exclude_features" in bochsrc sample and documentation)
- CPUID: Old bx_generic CPUID model is deprecated with all associated .bochsrc CPUID configuration options, use pre-defined CPU models instead
- Bugfixes for CPU emulation correctness (critical bugfixes for WAITPKG, LASS, XSAVEC/XSAVES, CPUID and SHA1 ISA implementation)
! CPUID: Old bx_generic CPUID model is deprecated with all associated .bochsrc CPUID configuration options, use pre-defined CPU models instead
- Several fixes and improvements for the Cirrus and Voodoo emulation
- USB: Added the USB Debugger support for xHCI and UHCI
- Added USB boot option (requires BIOS from https://github.com/fysnet/i440fx)
Expand Down Expand Up @@ -40,6 +42,14 @@ Detailed change log :
- Support for enabling/disabling of one of more CPU features from CPUID configuration (see "add_features" and "exclude_features" in bochsrc sample and documentation)
- Old bx_generic CPUID model is deprecated with all associated .bochsrc CPUID configuration options, use pre-defined CPU models instead

- Bochs Debugger
- Include Bochs debugger support in all release binaries.
Bochs internal debugger and Bochs GUI debugger are compiled by in by default and there are no special Bochs binaries with internal debugger support anymore.
The debugger could be enabled if -dbg or -debugger option is included in the Bochs command line.
Without these options, normal high performance execution invoked and impact on emulation performance is minimal.
Note that simulation performance in debugger mode is still substantially lower.
- Implemented 64-bit paging support in GUI debugger page table dump

- Configure and compile
- Fixed compilation of plugin version with debugger enabled on Windows
- Removed legacy libltdl code and force using library installed on host system
Expand Down
18 changes: 13 additions & 5 deletions bochs/bochs.h
Original file line number Diff line number Diff line change
Expand Up @@ -229,10 +229,6 @@ void print_statistics_tree(bx_param_c *node, int level = 0);
if (bx_guard.report.a20) bx_dbg_a20_report(val)
# define BX_DBG_IO_REPORT(port, size, op, val) \
if (bx_guard.report.io) bx_dbg_io_report(port, size, op, val)
# define BX_DBG_LIN_MEMORY_ACCESS(cpu, lin, phy, len, memtype, rw, data) \
bx_dbg_lin_memory_access(cpu, lin, phy, len, memtype, rw, data)
# define BX_DBG_PHY_MEMORY_ACCESS(cpu, phy, len, memtype, rw, why, data) \
bx_dbg_phy_memory_access(cpu, phy, len, memtype, rw, why, data)
#else // #if BX_DEBUGGER
// debugger not compiled in, use empty stubs
# define BX_DBG_ASYNC_INTR 1
Expand All @@ -241,9 +237,19 @@ void print_statistics_tree(bx_param_c *node, int level = 0);
# define BX_DBG_IAC_REPORT(vector, irq) /* empty */
# define BX_DBG_A20_REPORT(val) /* empty */
# define BX_DBG_IO_REPORT(port, size, op, val) /* empty */
#endif // #if BX_DEBUGGER

#if BX_DEBUGGER
# define BX_DBG_LIN_MEMORY_ACCESS(cpu, lin, phy, len, memtype, rw, data) \
if (bx_dbg.debugger_active) \
bx_dbg_lin_memory_access(cpu, lin, phy, len, memtype, rw, data);
# define BX_DBG_PHY_MEMORY_ACCESS(cpu, phy, len, memtype, rw, why, data) \
if (bx_dbg.debugger_active) \
bx_dbg_phy_memory_access(cpu, phy, len, memtype, rw, why, data);
#else
# define BX_DBG_LIN_MEMORY_ACCESS(cpu, lin, phy, len, memtype, rw, data) /* empty */
# define BX_DBG_PHY_MEMORY_ACCESS(cpu, phy, len, memtype, rw, attr, data) /* empty */
#endif // #if BX_DEBUGGER
#endif

#include "logio.h"

Expand Down Expand Up @@ -288,6 +294,7 @@ typedef struct {
bool interrupts;
bool exceptions;
bool print_timestamps;
bool debugger_active;
#if BX_DEBUGGER
Bit8u magic_break;
#endif
Expand All @@ -308,6 +315,7 @@ BOCHSAPI_MSVCONLY void bx_show_ips_handler(void);
void CDECL bx_signal_handler(int signum);
BOCHSAPI_MSVCONLY int bx_atexit(void);
BOCHSAPI extern bx_debug_t bx_dbg;
BOCHSAPI_MSVCONLY void bx_exit(int errcode);

#if BX_SUPPORT_SMP
#define BX_SMP_PROCESSORS (bx_cpu_count)
Expand Down
33 changes: 17 additions & 16 deletions bochs/bx_debug/dbg_main.cc
Original file line number Diff line number Diff line change
Expand Up @@ -147,13 +147,6 @@ void dbg_printf(const char *fmt, ...)
SIM->debug_puts(buf); // send to debugger, which will free buf when done.
}

void bx_dbg_init_infile(void)
{
bx_infile_stack_index = 0;
bx_infile_stack[0].fp = stdin;
bx_infile_stack[0].lineno = 0;
}

int bx_dbg_set_rcfile(const char *rcfile)
{
strncpy(bx_infile_stack[0].fname, rcfile, BX_MAX_PATH);
Expand Down Expand Up @@ -216,12 +209,8 @@ void switch_dbg_cpu(unsigned cpu)
dbg_cpu = cpu;
}

int bx_dbg_main(void)
void bx_dbg_init(void)
{
setbuf(stdout, NULL);
setbuf(stderr, NULL);

bx_dbg_exit_called = 0;
bx_dbg_batch_dma.this_many = 1;
bx_dbg_batch_dma.Qsize = 0;

Expand All @@ -236,6 +225,18 @@ int bx_dbg_main(void)
bx_debugger.default_unit_size = 'w';
bx_debugger.default_addr = 0;

bx_infile_stack_index = 0;
bx_infile_stack[0].fp = stdin;
bx_infile_stack[0].lineno = 0;
}

int bx_dbg_main(void)
{
setbuf(stdout, NULL);
setbuf(stderr, NULL);

bx_dbg_exit_called = 0;

const char *debugger_log_filename = SIM->get_param_string(BXPN_DEBUGGER_LOG_FILENAME)->getptr();

// Open debugger log file if needed
Expand Down Expand Up @@ -2158,7 +2159,7 @@ void bx_dbg_continue_command(bool expression)

if (BX_SMP_PROCESSORS == 1) {
bx_dbg_set_icount_guard(0, 0); // run to next breakpoint
BX_CPU(0)->cpu_loop();
BX_CPU(0)->cpu_loop_debugger();
// set stop flag if a guard found other than icount or halted
unsigned found = BX_CPU(0)->guard_found.guard_found;
stop_reason_t reason = (stop_reason_t) BX_CPU(0)->stop_reason;
Expand All @@ -2173,7 +2174,7 @@ void bx_dbg_continue_command(bool expression)
for (int cpu=0; cpu < BX_SMP_PROCESSORS; cpu++) {
Bit64u cpu_icount = BX_CPU(cpu)->get_icount();
bx_dbg_set_icount_guard(cpu, BX_DBG_DEFAULT_ICOUNT_QUANTUM);
BX_CPU(cpu)->cpu_loop();
BX_CPU(cpu)->cpu_loop_debugger();
Bit32u executed = BX_CPU(cpu)->get_icount() - cpu_icount;
if (executed > max_executed) max_executed = executed;
// set stop flag if a guard found other than icount or halted
Expand Down Expand Up @@ -2237,7 +2238,7 @@ void bx_dbg_stepN_command(int cpu, Bit32u count)
if (cpu >= 0 || BX_SMP_PROCESSORS == 1) {
bx_guard.interrupt_requested = false;
bx_dbg_set_icount_guard(cpu, count);
BX_CPU(cpu)->cpu_loop();
BX_CPU(cpu)->cpu_loop_debugger();
}
#if BX_SUPPORT_SMP
else {
Expand All @@ -2247,7 +2248,7 @@ void bx_dbg_stepN_command(int cpu, Bit32u count)
for (unsigned ncpu=0; ncpu < BX_SMP_PROCESSORS; ncpu++) {
bx_guard.interrupt_requested = false;
bx_dbg_set_icount_guard(ncpu, 1);
BX_CPU(ncpu)->cpu_loop();
BX_CPU(ncpu)->cpu_loop_debugger();
// set stop flag if a guard found other than icount or halted
unsigned found = BX_CPU(ncpu)->guard_found.guard_found;
stop_reason_t reason = (stop_reason_t) BX_CPU(ncpu)->stop_reason;
Expand Down
2 changes: 1 addition & 1 deletion bochs/bx_debug/debug.h
Original file line number Diff line number Diff line change
Expand Up @@ -349,7 +349,7 @@ BOCHSAPI_MSVCONLY extern bx_guard_t bx_guard;
#define IS_CODE_32(code_32_64) ((code_32_64 & 1) != 0)
#define IS_CODE_64(code_32_64) ((code_32_64 & 2) != 0)

void bx_dbg_init_infile(void);
void bx_dbg_init(void);
int bx_dbg_set_rcfile(const char *rcfile);
int bx_dbg_main(void);
void bx_dbg_user_input_loop(void);
Expand Down
4 changes: 2 additions & 2 deletions bochs/config.h.in
Original file line number Diff line number Diff line change
Expand Up @@ -661,8 +661,8 @@ typedef Bit32u bx_phy_address;
#define BX_SUPPORT_HANDLERS_CHAINING_SPEEDUPS 0
#define BX_ENABLE_TRACE_LINKING 0

#if (BX_DEBUGGER || BX_GDBSTUB) && BX_SUPPORT_HANDLERS_CHAINING_SPEEDUPS
#error "Handler-chaining-speedups are not supported together with internal debugger or gdb-stub!"
#if BX_GDBSTUB && BX_SUPPORT_HANDLERS_CHAINING_SPEEDUPS
#error "Handler-chaining-speedups are not supported together with gdb-stub!"
#endif

#if BX_SUPPORT_3DNOW
Expand Down
Loading

0 comments on commit 119af93

Please sign in to comment.