From 80cc08d45db32d7eb5573c81098ef101894fa6c9 Mon Sep 17 00:00:00 2001 From: Ulf Wohlers Date: Fri, 21 Feb 2003 20:36:45 +0000 Subject: [PATCH] additional debug info / memory dump / create variable names Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@678 --- src/debug/debug.cpp | 324 ++++++++++++++++++++++++++++++++++++++++++-- 1 file changed, 313 insertions(+), 11 deletions(-) diff --git a/src/debug/debug.cpp b/src/debug/debug.cpp index 42968860..c1fa56e6 100644 --- a/src/debug/debug.cpp +++ b/src/debug/debug.cpp @@ -48,6 +48,8 @@ int old_cursor_state; static void DrawCode(void); static bool DEBUG_Log_Loop(int count); static void DEBUG_RaiseTimerIrq(void); +char* AnalyzeInstruction(char* inst); +void SaveMemory(Bit16u seg, Bit16u ofs1, Bit32s num); class DEBUG; DEBUG* pDebugcom = 0; @@ -88,7 +90,37 @@ struct SCodeViewData { } codeViewData; -static Bit16u dataSeg,dataOfs; +static Bit16u dataSeg,dataOfs; +static bool showExtend = true; + +/********************/ +/* DebugVar stuff */ +/********************/ + +class CDebugVar +{ +public: + CDebugVar(char* _name, PhysPt _adr) { adr=_adr; (strlen(name)<15)?strcpy(name,_name):strncpy(name,_name,15); name[15]=0; }; + + 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 varList; +}; + +std::list CDebugVar::varList; + /********************/ /* Breakpoint stuff */ @@ -551,8 +583,17 @@ static void DrawCode(void) mvwprintw(dbg.win_code,i,0,"%04X:%04X ",codeViewData.useCS,disEIP); for (c=0;c=size*2;c--) waddch(dbg.win_code,' '); + + char* res = 0; + if (showExtend) res = AnalyzeInstruction(dline); waddstr(dbg.win_code,dline); - for (c=30-strlen(dline);c>0;c--) waddch(dbg.win_code,' '); + for (c=28-strlen(dline);c>0;c--) waddch(dbg.win_code,' '); + if (showExtend) { + waddstr(dbg.win_code,res); + for (c=strlen(res);c<20;c++) waddch(dbg.win_code,' '); + } else { + for (c=0;c<20;c++) waddch(dbg.win_code,' '); + } start+=size; disEIP+=size; @@ -679,6 +720,66 @@ bool ParseCommand(char* str) char* found = str; for(char* idx = found;*idx != 0; idx++) *idx = toupper(*idx); + + found = trim(found); + + found = strstr(str,"MEMDUMP "); + if (found) { // Insert variable + found+=8; + Bit16u seg = GetHexValue(found,found); found++; + Bit32u ofs = GetHexValue(found,found); found++; + Bit32u num = GetHexValue(found,found); found++; + SaveMemory(seg,ofs,num); + return true; + }; + + found = strstr(str,"IV "); + if (found) { // Insert variable + found+=3; + Bit16u seg = GetHexValue(found,found); found++; + Bit32u ofs = GetHexValue(found,found); found++; + char name[16]; + for (int i=0; i<16; i++) { + if ((found[i]!=' ') && (found[i]!=0)) name[i] = found[i]; + else { name[i] = 0; break; }; + }; + name[15] = 0; + + char buffer[128]; + sprintf(buffer,"DEBUG: Created debug var %s at %04X:%04X",name,seg,ofs); + LOG_DEBUG(buffer); + CDebugVar::InsertVariable(name,PhysMake(seg,ofs)); + return true; + } + + found = strstr(str,"SV "); + if (found) { // Save variables + found+=3; + char name[13]; + for (int i=0; i<12; i++) { + if ((found[i]!=' ') && (found[i]!=0)) name[i] = found[i]; + else { name[i] = 0; break; }; + }; + name[12] = 0; + if (CDebugVar::SaveVars(name)) LOG_DEBUG("DEBUG: Variable list save (%s) : ok.",name); + else LOG_DEBUG("DEBUG: Variable list save (%s) : failure",name); + return true; + } + + found = strstr(str,"LV "); + if (found) { // Save variables + found+=3; + char name[13]; + for (int i=0; i<12; i++) { + if ((found[i]!=' ') && (found[i]!=0)) name[i] = found[i]; + else { name[i] = 0; break; }; + }; + name[12] = 0; + if (CDebugVar::LoadVars(name)) LOG_DEBUG("DEBUG: Variable list load (%s) : ok.",name); + else LOG_DEBUG("DEBUG: Variable list load (%s) : failure",name); + return true; + } + found = strstr(str,"BP "); if (found) { // Add new breakpoint found+=3; @@ -736,7 +837,7 @@ bool ParseCommand(char* str) return true; } found = strstr(str,"C "); - if (found) { // Set code overview + if (found==(char*)str) { // Set code overview found++; Bit16u codeSeg = GetHexValue(found,found); found++; Bit32u codeOfs = GetHexValue(found,found); @@ -746,7 +847,7 @@ bool ParseCommand(char* str) return true; } found = strstr(str,"D "); - if (found) { // Set data overview + if (found==(char*)str) { // Set data overview found++; dataSeg = GetHexValue(found,found); found++; dataOfs = GetHexValue(found,found); @@ -806,7 +907,8 @@ bool ParseCommand(char* str) DOSBOX_SetNormalLoop(); Interrupt(intNr); return true; - } + } + #if C_HEAVY_DEBUG found = strstr(str,"HEAVYLOG"); if (found) { // Create Cpu log file @@ -826,6 +928,7 @@ bool ParseCommand(char* str) wprintw(dbg.win_out,"Return - Enable command line input\n"); wprintw(dbg.win_out,"D/E/S/X/B - Set data view to DS:SI/ES:DI/SS:SP/DS:DX/ES:BX\n"); wprintw(dbg.win_out,"R/F - Scroll data view\n"); + wprintw(dbg.win_out,"V - Toggle additional info\n"); wprintw(dbg.win_out,"Debugger commands (enter all values in hex or as register):\n"); wprintw(dbg.win_out,"--------------------------------------------------------------------------\n"); wprintw(dbg.win_out,"BP [segment]:[offset] - Set breakpoint\n"); @@ -844,13 +947,93 @@ bool ParseCommand(char* str) #endif wprintw(dbg.win_out,"SR [reg] [value] - Set register value\n"); wprintw(dbg.win_out,"SM [seg]:[off] [val] [.]..- Set memory with following values\n"); + + wprintw(dbg.win_out,"IV [seg]:[off] [name] - Create var name for memory address\n"); + wprintw(dbg.win_out,"SV [filename] - Save var list in file\n"); + wprintw(dbg.win_out,"LV [seg]:[off] [name] - Load var list from file\n"); + + wprintw(dbg.win_out,"MEMDUMP [seg]:[off] [len] - Write memory to file memdump.txt\n"); wprintw(dbg.win_out,"H - Help\n"); + wrefresh(dbg.win_out); return TRUE; } return false; }; +char* AnalyzeInstruction(char* inst) +{ + static char result[256]; + + char instu[256]; + char prefix[3]; + Bit16u seg; + + strcpy(instu,inst); + upcase(instu); + + result[0] = 0; + char* pos = strchr(instu,'['); + if (pos) { + // Segment prefix ? + if (*(pos-1)==':') { + char* segpos = pos-3; + prefix[0] = tolower(*segpos); + prefix[1] = tolower(*(segpos+1)); + prefix[2] = 0; + seg = GetHexValue(segpos,segpos); + } else { + if (strstr(pos,"SP") || strstr(pos,"BP")) { + seg = SegValue(ss); + strcpy(prefix,"ss"); + } else { + seg = SegValue(ds); + strcpy(prefix,"ds"); + }; + }; + + pos++; + Bit32u adr = GetHexValue(pos,pos); + while (*pos!=']') { + if (*pos=='+') { + pos++; + adr += GetHexValue(pos,pos); + } else if (*pos=='-') { + pos++; + adr -= GetHexValue(pos,pos); + } else + pos++; + }; + switch (DasmLastOperandSize()) { + case 8 : { Bit8u val = mem_readb( PhysMake (seg,adr) ); + sprintf(result,"%s:[%04X]=%02X",prefix,adr,val); + } break; + case 16: { Bit16u val = mem_readw( PhysMake (seg,adr) ); + sprintf(result,"%s:[%04X]=%04X",prefix,adr,val); + } break; + case 32: { Bit32u val = mem_readd( PhysMake (seg,adr) ); + sprintf(result,"%s:[%04X]=%08X",prefix,adr,val); + } break; + } + // Variable found ? + CDebugVar* var = CDebugVar::FindVar(PhysMake(seg,adr)); + if (var) { + // Replace occurance + char* pos1 = strchr(inst,'['); + char* pos2 = strchr(inst,']'); + if (pos1 && pos2) { + char temp[256]; + strcpy(temp,pos2); // save end + pos1++; *pos1 = 0; // cut after '[' + strcat(inst,var->GetName()); // add var name + strcat(inst,temp); // add end + }; + }; + }; + return result; +}; + + Bit32u DEBUG_CheckKeys(void) { if (codeViewData.inputMode) { @@ -928,6 +1111,8 @@ Bit32u DEBUG_CheckKeys(void) { case 'T' : DEBUG_RaiseTimerIrq(); LOG_DEBUG("Debug: Timer Int started."); break; + case 'V' : showExtend = !showExtend; + break; case 0x0A : // Return : input codeViewData.inputMode = true; @@ -1017,13 +1202,21 @@ static void DEBUG_RaiseTimerIrq(void) { static void LogInstruction(Bit16u segValue, Bit32u eipValue, char* buffer) { + static char empty[15] = { 32,32,32,32,32,32,32,32,32,32,32,32,32,32,0 }; + PhysPt start = PhysMake(segValue,eipValue); char dline[200];Bitu size; size = DasmI386(dline, start, reg_eip, false); Bitu len = strlen(dline); + char* res = empty; + if (showExtend) { + res = AnalyzeInstruction(dline); + if (!res || (strlen(res)==0)) res = empty; + }; + if (len<30) for (Bitu i=0; i<30-len; i++) strcat(dline," "); // Get register values - sprintf(buffer,"%04X:%08X %s EAX:%08X EBX:%08X ECX:%08X EDX:%08X ESI:%08X EDI:%08X EBP:%08X ESP:%08X DS:%04X ES:%04X FS:%04X GS:%04X SS:%04X CF:%01X ZF:%01X SF:%01X OF:%01X AF:%01X PF:%01X\n",segValue,eipValue,dline,reg_eax,reg_ebx,reg_ecx,reg_edx,reg_esi,reg_edi,reg_ebp,reg_esp,SegValue(ds),SegValue(es),SegValue(fs),SegValue(gs),SegValue(ss),get_CF(),get_ZF(),get_SF(),get_OF(),get_AF(),get_PF()); + sprintf(buffer,"%04X:%08X %s %s EAX:%08X EBX:%08X ECX:%08X EDX:%08X ESI:%08X EDI:%08X EBP:%08X ESP:%08X DS:%04X ES:%04X FS:%04X GS:%04X SS:%04X CF:%01X ZF:%01X SF:%01X OF:%01X AF:%01X PF:%01X\n",segValue,eipValue,dline,res,reg_eax,reg_ebx,reg_ecx,reg_edx,reg_esi,reg_edi,reg_ebp,reg_esp,SegValue(ds),SegValue(es),SegValue(fs),SegValue(gs),SegValue(ss),get_CF(),get_ZF(),get_SF(),get_OF(),get_AF(),get_PF()); }; static bool DEBUG_Log_Loop(int count) { @@ -1148,6 +1341,7 @@ void DEBUG_SetupConsole(void) static void DEBUG_ShutDown(Section * sec) { CBreakpoint::DeleteAll(); + CDebugVar::DeleteAll(); #ifndef WIN32 curs_set(old_cursor_state); tcsetattr(0, TCSANOW,&consolesettings); @@ -1171,18 +1365,120 @@ void DEBUG_Init(Section* sec) { sec->AddDestroyFunction(&DEBUG_ShutDown); } +// DEBUGGING VAR STUFF + +void CDebugVar::InsertVariable(char* name, PhysPt adr) +{ + varList.push_back(new CDebugVar(name,adr)); +}; + +void CDebugVar::DeleteAll(void) +{ + std::list::iterator i; + CDebugVar* bp; + for(i=varList.begin(); i != varList.end(); i++) { + bp = static_cast(*i); + delete bp; + }; + (varList.clear)(); +}; + +CDebugVar* CDebugVar::FindVar(PhysPt pt) +{ + std::list::iterator i; + CDebugVar* bp; + for(i=varList.begin(); i != varList.end(); i++) { + bp = static_cast(*i); + if (bp->GetAdr()==pt) return bp; + }; + return 0; +}; + +bool CDebugVar::SaveVars(char* name) +{ + FILE* f = fopen(name,"wb+"); + if (!f) return false; + + // write number of vars + Bit16u num = varList.size(); + fwrite(&num,1,sizeof(num),f); + + std::list::iterator i; + CDebugVar* bp; + for(i=varList.begin(); i != varList.end(); i++) { + bp = static_cast(*i); + // name + fwrite(bp->GetName(),1,16,f); + // adr + PhysPt adr = bp->GetAdr(); + fwrite(&adr,1,sizeof(adr),f); + }; + fclose(f); + return true; +}; + +bool CDebugVar::LoadVars(char* name) +{ + FILE* f = fopen(name,"rb"); + if (!f) return false; + + // read number of vars + Bit16u num; + fread(&num,1,sizeof(num),f); + + for (Bit16u i=0; i0) { + + sprintf(buffer,"%04X:%04X ",seg,ofs1); + for (Bit16u x=0; x<16; x++) { + sprintf (temp,"%02X ",mem_readb(PhysMake(seg,ofs1+x))); + strcat (buffer,temp); + }; + ofs1+=16; + num-=16; + + fprintf(f,"%s\n",buffer); + }; + fclose(f); + LOG_DEBUG("DEBUG: Memory dump success."); +}; + // HEAVY DEBUGGING STUFF #if C_HEAVY_DEBUG -const Bit16u LOGCPUMAX = 200; +const Bit32u LOGCPUMAX = 200; static Bit16u logCpuCS [LOGCPUMAX]; static Bit32u logCpuEIP[LOGCPUMAX]; static Bit32u logCount = 0; typedef struct SLogInst { - char buffer[256]; + char buffer[512]; } TLogInst; TLogInst logInst[LOGCPUMAX]; @@ -1190,12 +1486,16 @@ TLogInst logInst[LOGCPUMAX]; void DEBUG_HeavyLogInstruction(void) { LogInstruction(SegValue(cs),reg_eip,logInst[logCount++].buffer); - if (logCount>=LOGCPUMAX) logCount = 0; + if (logCount>=LOGCPUMAX) { + logCount = 0; + }; }; void DEBUG_HeavyWriteLogInstruction(void) { if (!logHeavy) return; + + logHeavy = false; LOG_DEBUG("DEBUG: Creating cpu log LOGCPU_INT_CD.TXT"); @@ -1205,7 +1505,7 @@ void DEBUG_HeavyWriteLogInstruction(void) return; } - Bit16u startLog = logCount; + Bit32u startLog = logCount; do { // Write Intructions fprintf(f,"%s",logInst[startLog++].buffer); @@ -1226,8 +1526,9 @@ bool DEBUG_HeavyIsBreakpoint(void) skipFirstInstruction = false; return false; } - + PhysPt where = SegPhys(cs)+reg_eip; + if (CBreakpoint::CheckBreakpoint(where)) { exitLoop = true; DEBUG_Enable(); @@ -1240,3 +1541,4 @@ bool DEBUG_HeavyIsBreakpoint(void) #endif // DEBUG +