1
0
Fork 0

Add gdb server to debugger

Here is a patch which allows using the GNU debugger as an alternative to
the DOSBox built-in debugger. The built-in debugger may be more
convenient to show x86 specific information about execution state,
whereas Gdb is useful for C and C++ source level debugging.

This patch applies against svn revision 3761. Once applied the configure
script can be used with a new option:

./autogen.sh
./configure --enable-debug=gdbserver

DOSBox then listen on TCP port 1234 and a Gdb client compiled for x86_64
or i686 targets can be connected:

$ gdb
(gdb) target remote localhost:1234

The gdb architecture must be set depending on the code your are trying
to disassemble (16 or 32 bits), for instance:

(gdb) set architecture i8086
(gdb) x/32i $eip

Breakpoints and watchpoints are supported and some DOSBox specific
features are available through the gdb "monitor" command.

This patch adds the following files:
- src/debug/gdb_server.cpp file
- src/debug/debug_log.cpp
- src/debug/debug_helpers.cpp

The debug.cpp file has been split in 3 files so that the original file
now contains built-in debugger stuff only and
debug_log.cpp/debug_helpers.cpp files contain common code used by both
built-in and Gdb debuggers. Some variables which were previously local
to debug.cpp have been prefixed by DEBUG_ and debug.h has been updated
accordingly.

Tested under GNU/Linux.

Co-authored-by: ykhwong
Imported-from: https://www.vogons.org/viewtopic.php?p=259378#p259378
This commit is contained in:
diaxen 2020-05-11 17:59:02 -04:00 committed by Alex Page
parent eb0a3dffc2
commit cf4685e7aa
31 changed files with 7979 additions and 1006 deletions

View file

@ -16,6 +16,19 @@
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*/
#ifndef DOSBOX_DEBUG_H
#define DOSBOX_DEBUG_H
#if C_DEBUG || C_GDBSERVER
#include <fstream>
extern Bit16u DEBUG_dataSeg;
extern Bit32u DEBUG_dataOfs;
extern bool DEBUG_showExtend;
extern char DEBUG_curSelectorName[3];
extern bool DEBUG_exitLoop;
void DEBUG_SetupConsole(void);
void DEBUG_DrawScreen(void);
bool DEBUG_Breakpoint(void);
@ -25,11 +38,72 @@ void DEBUG_CheckExecuteBreakpoint(Bit16u seg, Bit32u off);
bool DEBUG_ExitLoop(void);
void DEBUG_RefreshPage(char scroll);
Bitu DEBUG_EnableDebugger(void);
Bit32u DEBUG_GetHexValue(char* str, char*& hex);
Bit32u DEBUG_GetAddress(Bit16u seg, Bit32u offset);
char* DEBUG_AnalyzeInstruction(char* inst, bool saveSelector);
bool DEBUG_GetDescriptorInfo(char* selname, char* out1, char* out2);
extern Bitu cycle_count;
extern Bitu debugCallback;
void DEBUG_LogMCBChain(Bit16u mcb_segment);
void DEBUG_LogMCBS(void);
void DEBUG_LogGDT(void);
void DEBUG_LogLDT(void);
void DEBUG_LogIDT(void);
void DEBUG_LogPages(char* selname);
void DEBUG_LogCPUInfo(void);
void DEBUG_LogInstruction(Bit16u segValue, Bit32u eipValue, std::ofstream& out);
extern bool DEBUG_showExtend;
extern Bitu DEBUG_cycle_count;
extern Bitu DEBUG_debugCallback;
#if C_HEAVY_DEBUG || C_GDBSERVER
extern std::ofstream DEBUG_cpuLogFile;
extern bool DEBUG_cpuLog;
extern int DEBUG_cpuLogCounter;
extern int DEBUG_cpuLogType; // log detail
extern bool DEBUG_zeroProtect;
extern bool DEBUG_logHeavy;
#ifdef C_HEAVY_DEBUG
bool DEBUG_HeavyIsBreakpoint(void);
void DEBUG_HeavyLogInstruction(void);
void DEBUG_HeavyWriteLogInstruction(void);
#endif
#ifdef C_GDBSERVER
void DEBUG_GdbMemReadHook(Bit32u address, int width);
void DEBUG_GdbMemWriteHook(Bit32u address, int width, Bit32u value);
void DEBUG_IrqBreakpoint(Bit8u intNum);
#endif
/********************/
/* DebugVar stuff */
/********************/
#include <list>
#include "paging.h"
class CDebugVar
{
public:
CDebugVar(char* _name, PhysPt _adr);
char* GetName(void) { return name; };
PhysPt GetAdr (void) { return adr; };
private:
PhysPt adr;
char name[16];
public:
static void InsertVariable (char* name, PhysPt adr);
static CDebugVar* FindVar (PhysPt adr);
static void DeleteAll ();
static bool SaveVars (char* name);
static bool LoadVars (char* name);
static std::list<CDebugVar*> varList;
};
#endif
#endif

View file

@ -37,7 +37,12 @@ enum LOG_SEVERITIES {
LOG_ERROR
};
#if C_DEBUG
#if C_DEBUG || C_GDBSERVER
struct _LogGroup {
char const* front;
bool enabled;
};
class LOG
{
LOG_TYPES d_type;
@ -48,14 +53,14 @@ public:
d_type(type),
d_severity(severity)
{}
void operator() (char const* buf, ...) GCC_ATTRIBUTE(__format__(__printf__, 2, 3)); //../src/debug/debug_gui.cpp
void operator() (char const* buf, ...) GCC_ATTRIBUTE(__format__(__printf__, 2, 3)); //../src/debug/debug_log.cpp
};
void DEBUG_ShowMsg(char const* format,...) GCC_ATTRIBUTE(__format__(__printf__, 1, 2));
#define LOG_MSG DEBUG_ShowMsg
#else //C_DEBUG
#else //C_DEBUG || C_GDBSERVER
struct LOG
{
@ -84,7 +89,7 @@ struct LOG
void GFX_ShowMsg(char const* format,...) GCC_ATTRIBUTE(__format__(__printf__, 1, 2));
#define LOG_MSG GFX_ShowMsg
#endif //C_DEBUG
#endif //C_DEBUG || C_GDBSERVER
#endif //DOSBOX_LOGGING_H

View file

@ -27,6 +27,8 @@
#include "mem.h"
#endif
#include "debug.h"
// disable this to reduce the size of the TLB
// NOTE: does not work with the dynamic core (dynrec is fine)
#define USE_FULL_TLB
@ -261,12 +263,18 @@ static INLINE PhysPt PAGING_GetPhysicalAddress(PhysPt linAddr) {
/* Special inlined memory reading/writing */
static INLINE Bit8u mem_readb_inline(PhysPt address) {
#ifdef C_GDBSERVER
DEBUG_GdbMemReadHook(address, 1);
#endif
HostPt tlb_addr=get_tlb_read(address);
if (tlb_addr) return host_readb(tlb_addr+address);
else return (Bit8u)(get_tlb_readhandler(address))->readb(address);
}
static INLINE Bit16u mem_readw_inline(PhysPt address) {
#ifdef C_GDBSERVER
DEBUG_GdbMemReadHook(address, 1);
#endif
if ((address & 0xfff)<0xfff) {
HostPt tlb_addr=get_tlb_read(address);
if (tlb_addr) return host_readw(tlb_addr+address);
@ -275,6 +283,9 @@ static INLINE Bit16u mem_readw_inline(PhysPt address) {
}
static INLINE Bit32u mem_readd_inline(PhysPt address) {
#ifdef C_GDBSERVER
DEBUG_GdbMemReadHook(address, 1);
#endif
if ((address & 0xfff)<0xffd) {
HostPt tlb_addr=get_tlb_read(address);
if (tlb_addr) return host_readd(tlb_addr+address);
@ -283,12 +294,18 @@ static INLINE Bit32u mem_readd_inline(PhysPt address) {
}
static INLINE void mem_writeb_inline(PhysPt address,Bit8u val) {
#ifdef C_GDBSERVER
DEBUG_GdbMemWriteHook(address, 1, val);
#endif
HostPt tlb_addr=get_tlb_write(address);
if (tlb_addr) host_writeb(tlb_addr+address,val);
else (get_tlb_writehandler(address))->writeb(address,val);
}
static INLINE void mem_writew_inline(PhysPt address,Bit16u val) {
#ifdef C_GDBSERVER
DEBUG_GdbMemWriteHook(address, 2, val);
#endif
if ((address & 0xfff)<0xfff) {
HostPt tlb_addr=get_tlb_write(address);
if (tlb_addr) host_writew(tlb_addr+address,val);
@ -297,6 +314,9 @@ static INLINE void mem_writew_inline(PhysPt address,Bit16u val) {
}
static INLINE void mem_writed_inline(PhysPt address,Bit32u val) {
#ifdef C_GDBSERVER
DEBUG_GdbMemWriteHook(address, 4, val);
#endif
if ((address & 0xfff)<0xffd) {
HostPt tlb_addr=get_tlb_write(address);
if (tlb_addr) host_writed(tlb_addr+address,val);