1
0
Fork 0

Add history to debugger and cleanup. Patch 2991413 from etillite

Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@3613
This commit is contained in:
Peter Veenstra 2010-06-05 10:35:20 +00:00
parent 6976225474
commit b441536ff4
2 changed files with 151 additions and 72 deletions

View file

@ -76,6 +76,7 @@ static void DrawVariables(void);
char* AnalyzeInstruction(char* inst, bool saveSelector);
Bit32u GetHexValue(char* str, char*& hex);
#if 0
class DebugPageHandler : public PageHandler {
public:
Bitu readb(PhysPt /*addr*/) {
@ -90,10 +91,8 @@ public:
}
void writed(PhysPt /*addr*/,Bitu /*val*/) {
}
};
#endif
class DEBUG;
@ -123,7 +122,6 @@ static char curSelectorName[3] = { 0,0,0 };
static Segment oldsegs[6];
static Bitu oldflags,oldcpucpl;
DBGBlock dbg;
static Bitu input_count;
Bitu cycle_count;
static bool debugging;
@ -136,23 +134,34 @@ static void SetColor(Bitu test) {
}
}
#define MAXCMDLEN 254
struct SCodeViewData {
int cursorPos;
int cursorPos;
Bit16u firstInstSize;
Bit16u useCS;
Bit32u useEIPlast, useEIPmid;
Bit32u useEIP;
Bit16u useCS;
Bit32u useEIPlast, useEIPmid;
Bit32u useEIP;
Bit16u cursorSeg;
Bit32u cursorOfs;
bool inputMode;
char inputStr[255];
char prevInputStr[255];
Bit32u cursorOfs;
bool ovrMode;
char inputStr[MAXCMDLEN+1];
char suspInputStr[MAXCMDLEN+1];
int inputPos;
} codeViewData;
static Bit16u dataSeg;
static Bit32u dataOfs;
static bool showExtend = true;
static Bit16u dataSeg;
static Bit32u dataOfs;
static bool showExtend = true;
static void ClearInputLine(void) {
codeViewData.inputStr[0] = 0;
codeViewData.inputPos = 0;
}
// History stuff
#define MAX_HIST_BUFFER 50
static list<string> histBuff;
static list<string>::iterator histBuffPos = histBuff.end();
/***********/
/* Helpers */
@ -775,6 +784,8 @@ static void DrawCode(void) {
wattrset(dbg.win_code,COLOR_PAIR(PAIR_GREEN_BLACK));
if (codeViewData.cursorPos==-1) {
codeViewData.cursorPos = i; // Set Cursor
}
if (i == codeViewData.cursorPos) {
codeViewData.cursorSeg = SegValue(cs);
codeViewData.cursorOfs = disEIP;
}
@ -837,12 +848,18 @@ static void DrawCode(void) {
wattrset(dbg.win_code,0);
if (!debugging) {
mvwprintw(dbg.win_code,10,0,"(Running)",codeViewData.inputStr);
} else {
if(!*codeViewData.inputStr) { //Clear old commands
mvwprintw(dbg.win_code,10,0," ");
}
mvwprintw(dbg.win_code,10,0,"-> %s_ ",codeViewData.inputStr);
mvwprintw(dbg.win_code,10,0,"%s","(Running)");
wclrtoeol(dbg.win_code);
} else {
//TODO long lines
char* dispPtr = codeViewData.inputStr;
char* curPtr = &codeViewData.inputStr[codeViewData.inputPos];
mvwprintw(dbg.win_code,10,0,"%c-> %s%c",
(codeViewData.ovrMode?'O':'I'),dispPtr,(*curPtr?' ':'_'));
wclrtoeol(dbg.win_code); // not correct in pdcurses if full line
if (*curPtr) {
mvwchgat(dbg.win_code,10,(curPtr-dispPtr+4),1,0,(PAIR_BLACK_GREY),NULL);
}
}
wrefresh(dbg.win_code);
@ -1121,6 +1138,7 @@ bool ParseCommand(char* str) {
DEBUG_ShowMsg("DEBUG: Set code overview to %04X:%04X\n",codeSeg,codeOfs);
codeViewData.useCS = codeSeg;
codeViewData.useEIP = codeOfs;
codeViewData.cursorPos = 0;
return true;
};
@ -1226,6 +1244,7 @@ bool ParseCommand(char* str) {
DEBUG_ShowMsg("DEBUG: Set code overview to interrupt handler %X\n",intNr);
codeViewData.useCS = mem_readw(intNr*4+2);
codeViewData.useEIP = mem_readw(intNr*4);
codeViewData.cursorPos = 0;
return true;
}
};
@ -1259,7 +1278,8 @@ bool ParseCommand(char* str) {
if (command == "HELP" || command == "?") {
DEBUG_ShowMsg("Debugger commands (enter all values in hex or as register):\n");
DEBUG_ShowMsg("--------------------------------------------------------------------------\n");
DEBUG_ShowMsg("F3/F6 - Re-enter previous command.\n");
DEBUG_ShowMsg("F3/F6 - Previous command in history.\n");
DEBUG_ShowMsg("F4/F7 - Next command in history.\n");
DEBUG_ShowMsg("F5 - Run.\n");
DEBUG_ShowMsg("F9 - Set/Remove breakpoint.\n");
DEBUG_ShowMsg("F10/F11 - Step over / trace into instruction.\n");
@ -1476,12 +1496,12 @@ char* AnalyzeInstruction(char* inst, bool saveSelector) {
if (jmp) {
pos = strchr(instu,'$');
if (pos) {
pos = strchr(instu,'+');
if (pos) {
strcpy(result,"(down)");
} else {
strcpy(result,"(up)");
}
pos = strchr(instu,'+');
if (pos) {
strcpy(result,"(down)");
} else {
strcpy(result,"(up)");
}
}
} else {
sprintf(result,"(no jmp)");
@ -1497,6 +1517,11 @@ Bit32u DEBUG_CheckKeys(void) {
if (key>0) {
#if defined(WIN32) && defined(__PDCURSES__)
switch (key) {
case PADENTER: key=0x0A; break;
case PADSLASH: key='/'; break;
case PADSTAR: key='*'; break;
case PADMINUS: key='-'; break;
case PADPLUS: key='+'; break;
case ALT_D:
if (ungetch('D') != ERR) key=27;
break;
@ -1518,7 +1543,7 @@ Bit32u DEBUG_CheckKeys(void) {
case 27: // escape (a bit slow): Clears line. and processes alt commands.
key=getch();
if(key < 0) { //Purely escape Clear line
codeViewData.inputStr[0] = 0;
ClearInputLine();
break;
}
@ -1584,23 +1609,54 @@ Bit32u DEBUG_CheckKeys(void) {
case KEY_END: // End: scroll log page down
DEBUG_RefreshPage(1);
break;
case KEY_F(6): // Re-enter previous command (f1-f4 generate rubbish at my place)
case KEY_F(3): // Re-enter previous command
// copy prevInputStr back into inputStr
safe_strncpy(codeViewData.inputStr, codeViewData.prevInputStr, sizeof(codeViewData.inputStr));
case KEY_IC: // Insert: toggle insert/overwrite
codeViewData.ovrMode = !codeViewData.ovrMode;
break;
case KEY_LEFT: // move to the left in command line
if (codeViewData.inputPos > 0) codeViewData.inputPos--;
break;
case KEY_RIGHT: // move to the right in command line
if (codeViewData.inputStr[codeViewData.inputPos]) codeViewData.inputPos++;
break;
case KEY_F(6): // previous command (f1-f4 generate rubbish at my place)
case KEY_F(3): // previous command
if (histBuffPos == histBuff.begin()) break;
if (histBuffPos == histBuff.end()) {
// copy inputStr to suspInputStr so we can restore it
safe_strncpy(codeViewData.suspInputStr, codeViewData.inputStr, sizeof(codeViewData.suspInputStr));
}
safe_strncpy(codeViewData.inputStr,(*--histBuffPos).c_str(),sizeof(codeViewData.inputStr));
codeViewData.inputPos = strlen(codeViewData.inputStr);
break;
case KEY_F(7): // next command (f1-f4 generate rubbish at my place)
case KEY_F(4): // next command
if (histBuffPos == histBuff.end()) break;
if (++histBuffPos != histBuff.end()) {
safe_strncpy(codeViewData.inputStr,(*histBuffPos).c_str(),sizeof(codeViewData.inputStr));
} else {
// copy suspInputStr back into inputStr
safe_strncpy(codeViewData.inputStr, codeViewData.suspInputStr, sizeof(codeViewData.inputStr));
}
codeViewData.inputPos = strlen(codeViewData.inputStr);
break;
case KEY_F(5): // Run Program
debugging=false;
CBreakpoint::ActivateBreakpoints(SegPhys(cs)+reg_eip,true);
ignoreAddressOnce = SegPhys(cs)+reg_eip;
DOSBOX_SetNormalLoop();
break;
case KEY_F(9): // Set/Remove TBreakpoint
case KEY_F(9): // Set/Remove Breakpoint
{ PhysPt ptr = GetAddress(codeViewData.cursorSeg,codeViewData.cursorOfs);
if (CBreakpoint::IsBreakpoint(ptr)) CBreakpoint::DeleteBreakpoint(ptr);
else CBreakpoint::AddBreakpoint(codeViewData.cursorSeg, codeViewData.cursorOfs, false);
if (CBreakpoint::IsBreakpoint(ptr)) {
CBreakpoint::DeleteBreakpoint(ptr);
DEBUG_ShowMsg("DEBUG: Breakpoint deletion success.\n");
}
else {
CBreakpoint::AddBreakpoint(codeViewData.cursorSeg, codeViewData.cursorOfs, false);
DEBUG_ShowMsg("DEBUG: Set breakpoint at %04X:%04X\n",codeViewData.cursorSeg,codeViewData.cursorOfs);
}
}
break;
break;
case KEY_F(10): // Step over inst
if (StepOver()) return 0;
else {
@ -1621,28 +1677,54 @@ Bit32u DEBUG_CheckKeys(void) {
CBreakpoint::ignoreOnce = 0;
break;
case 0x0A: //Parse typed Command
codeViewData.inputMode = true;
codeViewData.inputStr[MAXCMDLEN] = '\0';
if(ParseCommand(codeViewData.inputStr)) {
// copy inputStr to prevInputStr so we can restore it if the user hits F3
safe_strncpy(codeViewData.prevInputStr, codeViewData.inputStr, sizeof(codeViewData.prevInputStr));
// clear input line ready for next command
codeViewData.inputStr[0] = 0;
char* cmd = ltrim(codeViewData.inputStr);
if (histBuff.empty() || *--histBuff.end()!=cmd)
histBuff.push_back(cmd);
if (histBuff.size() > MAX_HIST_BUFFER) histBuff.pop_front();
histBuffPos = histBuff.end();
ClearInputLine();
} else {
codeViewData.inputPos = strlen(codeViewData.inputStr);
}
break;
case KEY_BACKSPACE: //backspace (linux)
case 0x7f: // backspace in some terminal emulators (linux)
case 0x08: // delete
if (codeViewData.inputPos == 0) break;
codeViewData.inputPos--;
// fallthrough
case KEY_DC: // delete character
if ((codeViewData.inputPos<0) || (codeViewData.inputPos>=MAXCMDLEN)) break;
if (codeViewData.inputStr[codeViewData.inputPos] != 0) {
codeViewData.inputStr[MAXCMDLEN] = '\0';
for(char* p=&codeViewData.inputStr[codeViewData.inputPos];(*p=*(p+1));p++) {}
}
break;
default:
if ((key>=32) && (key<127)) {
if ((codeViewData.inputPos<0) || (codeViewData.inputPos>=MAXCMDLEN)) break;
codeViewData.inputStr[MAXCMDLEN] = '\0';
if (codeViewData.inputStr[codeViewData.inputPos] == 0) {
codeViewData.inputStr[codeViewData.inputPos++] = char(key);
codeViewData.inputStr[codeViewData.inputPos] = '\0';
} else if (!codeViewData.ovrMode) {
int len = (int) strlen(codeViewData.inputStr);
if (len < MAXCMDLEN) {
for(len++;len>codeViewData.inputPos;len--)
codeViewData.inputStr[len]=codeViewData.inputStr[len-1];
codeViewData.inputStr[codeViewData.inputPos++] = char(key);
}
} else {
codeViewData.inputStr[codeViewData.inputPos++] = char(key);
}
} else if (key==killchar()) {
ClearInputLine();
}
break;
case 0x107: //backspace (linux)
case 0x7f: //backspace in some terminal emulators (linux)
case 0x08: // delete
if (strlen(codeViewData.inputStr)>0) codeViewData.inputStr[strlen(codeViewData.inputStr)-1] = 0;
break;
default : if ((key>=32) && (key<=128) && (strlen(codeViewData.inputStr)<253)) {
Bit32u len = strlen(codeViewData.inputStr);
codeViewData.inputStr[len] = char(key);
codeViewData.inputStr[len+1] = 0;
}
break;
}
if (ret<0) return ret;
if (ret<0) return ret;
if (ret>0) {
ret=(*CallBack_Handlers[ret])();
if (ret) {
@ -1902,7 +1984,7 @@ static void LogInstruction(Bit16u segValue, Bit32u eipValue, ofstream& out) {
char ibytes[200]=""; char tmpc[200];
for (Bitu i=0; i<size; i++) {
Bit8u value;
if (mem_readb_checked(start+i,&value)) sprintf(tmpc,"?? ",value);
if (mem_readb_checked(start+i,&value)) sprintf(tmpc,"%s","?? ");
else sprintf(tmpc,"%02X ",value);
strcat(ibytes,tmpc);
}
@ -1958,7 +2040,6 @@ public:
safe_strncpy(filename,temp_line.c_str(),128);
// Read commandline
Bit16u i =2;
bool ok = false;
args[0] = 0;
for (;cmd->FindCommand(i++,temp_line)==true;) {
strncat(args,temp_line.c_str(),256);
@ -2027,8 +2108,7 @@ void DEBUG_SetupConsole(void) {
#endif
memset((void *)&dbg,0,sizeof(dbg));
debugging=false;
dbg.active_win=3;
input_count=0;
// dbg.active_win=3;
/* Start the Debug Gui */
DBGUI_StartUp();
}
@ -2037,6 +2117,7 @@ static void DEBUG_ShutDown(Section * /*sec*/) {
CBreakpoint::DeleteAll();
CDebugVar::DeleteAll();
curs_set(old_cursor_state);
endwin();
#ifndef WIN32
tcsetattr(0, TCSANOW,&consolesettings);
// printf("\e[0m\e[2J"); //Seems to destroy scrolling
@ -2049,11 +2130,11 @@ Bitu debugCallback;
void DEBUG_Init(Section* sec) {
MSG_Add("DEBUG_CONFIGFILE_HELP","Debugger related options.\n");
// MSG_Add("DEBUG_CONFIGFILE_HELP","Debugger related options.\n");
DEBUG_DrawScreen();
/* Add some keyhandlers */
MAPPER_AddHandler(DEBUG_Enable,MK_pause,MMOD2,"debugger","Debugger");
/* Clear the TBreakpoint list */
/* Reset code overview and input line */
memset((void*)&codeViewData,0,sizeof(codeViewData));
/* setup debug.com */
PROGRAMS_MakeFile("DEBUG.COM",DEBUG_ProgramStart);
@ -2154,7 +2235,7 @@ static void SaveMemory(Bitu seg, Bitu ofs1, Bit32u num) {
sprintf(buffer,"%04X:%04X ",seg,ofs1);
for (Bit16u x=0; x<16; x++) {
Bit8u value;
if (mem_readb_checked(GetAddress(seg,ofs1+x),&value)) sprintf(temp,"?? ",value);
if (mem_readb_checked(GetAddress(seg,ofs1+x),&value)) sprintf(temp,"%s","?? ");
else sprintf(temp,"%02X ",value);
strcat(buffer,temp);
}
@ -2167,7 +2248,7 @@ static void SaveMemory(Bitu seg, Bitu ofs1, Bit32u num) {
sprintf(buffer,"%04X:%04X ",seg,ofs1);
for (Bit16u x=0; x<num; x++) {
Bit8u value;
if (mem_readb_checked(GetAddress(seg,ofs1+x),&value)) sprintf(temp,"?? ",value);
if (mem_readb_checked(GetAddress(seg,ofs1+x),&value)) sprintf(temp,"%s","?? ");
else sprintf(temp,"%02X ",value);
strcat(buffer,temp);
}
@ -2229,7 +2310,7 @@ static void DrawVariables(void) {
Bit16u value;
if (mem_readw_checked(dv->GetAdr(),&value))
snprintf(buffer,DEBUG_VAR_BUF_LEN, "??????", value);
snprintf(buffer,DEBUG_VAR_BUF_LEN, "%s", "??????");
else
snprintf(buffer,DEBUG_VAR_BUF_LEN, "0x%04x", value);
@ -2248,8 +2329,6 @@ static void DrawVariables(void) {
const Bit32u LOGCPUMAX = 20000;
static Bit16u logCpuCS [LOGCPUMAX];
static Bit32u logCpuEIP[LOGCPUMAX];
static Bit32u logCount = 0;
struct TLogInst {
@ -2287,7 +2366,7 @@ void DEBUG_HeavyLogInstruction(void) {
PhysPt start = GetAddress(SegValue(cs),reg_eip);
char dline[200];
Bitu size = DasmI386(dline, start, reg_eip, cpu.code.big);
DasmI386(dline, start, reg_eip, cpu.code.big);
char* res = empty;
if (showExtend) {
res = AnalyzeInstruction(dline,false);

View file

@ -154,7 +154,7 @@ static void DrawBars(void) {
/* Show the Variable Overview bar */
mvaddstr(dbg.win_var->_begy-1,0, "---(Variable Overview )---");
/* Show the Output OverView */
mvaddstr(dbg.win_out->_begy-1,0, "---(OutPut/Input Scroll: home/end )---");
mvaddstr(dbg.win_out->_begy-1,0, "---(Output Scroll: home/end )---");
attrset(0);
}
@ -178,8 +178,8 @@ static void MakeSubWindows(void) {
dbg.win_var=subwin(dbg.win_main,4,win_main_maxx,outy,0);
outy+=5;
/* The Output Window */
dbg.win_out=subwin(dbg.win_main,win_main_maxy-outy-1,win_main_maxx,outy,0);
dbg.input_y=win_main_maxy-1;
dbg.win_out=subwin(dbg.win_main,win_main_maxy-outy,win_main_maxx,outy,0);
// dbg.input_y=win_main_maxy-1;
scrollok(dbg.win_out,TRUE);
DrawBars();
Draw_RegisterLayout();
@ -257,7 +257,7 @@ void LOG_StartUp(void) {
Prop_bool* Pbool = sect->Add_bool(buf,Property::Changeable::Always,true);
Pbool->Set_help("Enable/Disable logging of this type.");
}
MSG_Add("LOG_CONFIGFILE_HELP","Logging related options for the debugger.\n");
// MSG_Add("LOG_CONFIGFILE_HELP","Logging related options for the debugger.\n");
}