diff --git a/Core/Debugger/Breakpoints.cpp b/Core/Debugger/Breakpoints.cpp index 41503fc1c5..053068c5f6 100644 --- a/Core/Debugger/Breakpoints.cpp +++ b/Core/Debugger/Breakpoints.cpp @@ -37,10 +37,14 @@ MemCheck::MemCheck() numHits = 0; } -void MemCheck::Log(u32 addr, bool write, int size, u32 pc) -{ - if (result & BREAK_ACTION_LOG) - NOTICE_LOG(MEMMAP, "CHK %s%i at %08x (%s), PC=%08x (%s)", write ? "Write" : "Read", size * 8, addr, g_symbolMap->GetDescription(addr).c_str(), pc, g_symbolMap->GetDescription(pc).c_str()); +void MemCheck::Log(u32 addr, bool write, int size, u32 pc) { + if (result & BREAK_ACTION_LOG) { + if (logFormat.empty()) { + NOTICE_LOG(MEMMAP, "CHK %s%i at %08x (%s), PC=%08x (%s)", write ? "Write" : "Read", size * 8, addr, g_symbolMap->GetDescription(addr).c_str(), pc, g_symbolMap->GetDescription(pc).c_str()); + } else { + NOTICE_LOG(MEMMAP, "%s", logFormat.c_str()); + } + } } BreakAction MemCheck::Action(u32 addr, bool write, int size, u32 pc) @@ -264,7 +268,7 @@ void CBreakPoints::ChangeBreakPointAddCond(u32 addr, const BreakPointCond &cond) { breakPoints_[bp].hasCond = true; breakPoints_[bp].cond = cond; - Update(); + Update(addr); } } @@ -274,7 +278,7 @@ void CBreakPoints::ChangeBreakPointRemoveCond(u32 addr) if (bp != INVALID_BREAKPOINT) { breakPoints_[bp].hasCond = false; - Update(); + Update(addr); } } @@ -286,6 +290,14 @@ BreakPointCond *CBreakPoints::GetBreakPointCondition(u32 addr) return NULL; } +void CBreakPoints::ChangeBreakPointLogFormat(u32 addr, const std::string &fmt) { + size_t bp = FindBreakpoint(addr, true, false); + if (bp != INVALID_BREAKPOINT) { + breakPoints_[bp].logFormat = fmt; + Update(addr); + } +} + BreakAction CBreakPoints::ExecBreakPoint(u32 addr) { size_t bp = FindBreakpoint(addr, false); if (bp != INVALID_BREAKPOINT) { @@ -297,7 +309,11 @@ BreakAction CBreakPoints::ExecBreakPoint(u32 addr) { } if (breakPoints_[bp].result & BREAK_ACTION_LOG) { - NOTICE_LOG(JIT, "BKP PC=%08x (%s)", addr, g_symbolMap->GetDescription(addr).c_str()); + if (breakPoints_[bp].logFormat.empty()) { + NOTICE_LOG(JIT, "BKP PC=%08x (%s)", addr, g_symbolMap->GetDescription(addr).c_str()); + } else { + NOTICE_LOG(JIT, "%s", breakPoints_[bp].logFormat.c_str()); + } } if (breakPoints_[bp].result & BREAK_ACTION_PAUSE) { Core_EnableStepping(true); @@ -371,6 +387,14 @@ void CBreakPoints::ClearAllMemChecks() } } +void CBreakPoints::ChangeMemCheckLogFormat(u32 start, u32 end, const std::string &fmt) { + size_t mc = FindMemCheck(start, end); + if (mc != INVALID_MEMCHECK) { + memChecks_[mc].logFormat = fmt; + Update(); + } +} + static inline u32 NotCached(u32 val) { // Remove the cached part of the address. diff --git a/Core/Debugger/Breakpoints.h b/Core/Debugger/Breakpoints.h index c2135e4e38..279ab787e0 100644 --- a/Core/Debugger/Breakpoints.h +++ b/Core/Debugger/Breakpoints.h @@ -41,11 +41,10 @@ struct BreakPointCond { DebugInterface *debug; PostfixExpression expression; - char expressionString[128]; + std::string expressionString; - BreakPointCond() : debug(NULL) + BreakPointCond() : debug(nullptr) { - expressionString[0] = '\0'; } u32 Evaluate() @@ -64,6 +63,7 @@ struct BreakPoint bool temporary; BreakAction result; + std::string logFormat; bool hasCond; BreakPointCond cond; @@ -89,8 +89,6 @@ enum MemCheckCondition MEMCHECK_READWRITE = 0x03, }; - - struct MemCheck { MemCheck(); @@ -99,6 +97,7 @@ struct MemCheck MemCheckCondition cond; BreakAction result; + std::string logFormat; u32 numHits; @@ -146,6 +145,8 @@ public: static void ChangeBreakPointRemoveCond(u32 addr); static BreakPointCond *GetBreakPointCondition(u32 addr); + static void ChangeBreakPointLogFormat(u32 addr, const std::string &fmt); + static BreakAction ExecBreakPoint(u32 addr); static void AddMemCheck(u32 start, u32 end, MemCheckCondition cond, BreakAction result); @@ -153,6 +154,8 @@ public: static void ChangeMemCheck(u32 start, u32 end, MemCheckCondition cond, BreakAction result); static void ClearAllMemChecks(); + static void ChangeMemCheckLogFormat(u32 start, u32 end, const std::string &fmt); + static MemCheck *GetMemCheck(u32 address, int size); static BreakAction ExecMemCheck(u32 address, bool write, int size, u32 pc); static BreakAction ExecOpMemCheck(u32 address, u32 pc); diff --git a/Windows/Debugger/BreakpointWindow.cpp b/Windows/Debugger/BreakpointWindow.cpp index 945b17a6e6..0adf84f891 100644 --- a/Windows/Debugger/BreakpointWindow.cpp +++ b/Windows/Debugger/BreakpointWindow.cpp @@ -1,6 +1,7 @@ #include #include "base/compat.h" +#include "util/text/utf8.h" #include "BreakpointWindow.h" #include "../resource.h" @@ -28,7 +29,7 @@ INT_PTR CALLBACK BreakpointWindow::dlgFunc(HWND hwnd, UINT iMsg, WPARAM wParam, EnableWindow(GetDlgItem(hwnd,IDC_BREAKPOINT_ONCHANGE),bp->memory); EnableWindow(GetDlgItem(hwnd,IDC_BREAKPOINT_SIZE),bp->memory); EnableWindow(GetDlgItem(hwnd,IDC_BREAKPOINT_CONDITION),!bp->memory); - + EnableWindow(GetDlgItem(hwnd,IDC_BREAKPOINT_LOG_FORMAT), bp->log); if (bp->address != -1) { @@ -37,9 +38,10 @@ INT_PTR CALLBACK BreakpointWindow::dlgFunc(HWND hwnd, UINT iMsg, WPARAM wParam, } snprintf(str, sizeof(str), "0x%08X", bp->size); - SetWindowTextA(GetDlgItem(hwnd,IDC_BREAKPOINT_SIZE),str); + SetWindowTextA(GetDlgItem(hwnd, IDC_BREAKPOINT_SIZE),str); - SetWindowTextA(GetDlgItem(hwnd,IDC_BREAKPOINT_CONDITION),bp->condition); + SetWindowTextW(GetDlgItem(hwnd, IDC_BREAKPOINT_CONDITION), ConvertUTF8ToWString(bp->condition).c_str()); + SetWindowTextW(GetDlgItem(hwnd, IDC_BREAKPOINT_LOG_FORMAT), ConvertUTF8ToWString(bp->logFormat).c_str()); return TRUE; case WM_COMMAND: switch (LOWORD(wParam)) @@ -70,6 +72,14 @@ INT_PTR CALLBACK BreakpointWindow::dlgFunc(HWND hwnd, UINT iMsg, WPARAM wParam, break; } break; + case IDC_BREAKPOINT_LOG: + switch (HIWORD(wParam)) + { + case BN_CLICKED: + EnableWindow(GetDlgItem(hwnd, IDC_BREAKPOINT_LOG_FORMAT), bp->GetCheckState(hwnd, IDC_BREAKPOINT_LOG)); + break; + } + break; case IDC_BREAKPOINT_OK: switch (HIWORD(wParam)) { @@ -113,12 +123,12 @@ bool BreakpointWindow::fetchDialogData(HWND hwnd) char str[256],errorMessage[512]; PostfixExpression exp; - memory = SendMessage(GetDlgItem(hwnd,IDC_BREAKPOINT_MEMORY),BM_GETCHECK,0,0) != 0; - read = SendMessage(GetDlgItem(hwnd,IDC_BREAKPOINT_READ),BM_GETCHECK,0,0) != 0; - write = SendMessage(GetDlgItem(hwnd,IDC_BREAKPOINT_WRITE),BM_GETCHECK,0,0) != 0; - enabled = SendMessage(GetDlgItem(hwnd,IDC_BREAKPOINT_ENABLED),BM_GETCHECK,0,0) != 0; - log = SendMessage(GetDlgItem(hwnd,IDC_BREAKPOINT_LOG),BM_GETCHECK,0,0) != 0; - onChange = SendMessage(GetDlgItem(hwnd,IDC_BREAKPOINT_ONCHANGE),BM_GETCHECK,0,0) != 0; + memory = GetCheckState(hwnd, IDC_BREAKPOINT_MEMORY); + read = GetCheckState(hwnd, IDC_BREAKPOINT_READ); + write = GetCheckState(hwnd, IDC_BREAKPOINT_WRITE); + enabled = GetCheckState(hwnd, IDC_BREAKPOINT_ENABLED); + log = GetCheckState(hwnd, IDC_BREAKPOINT_LOG); + onChange = GetCheckState(hwnd, IDC_BREAKPOINT_ONCHANGE); // parse address GetWindowTextA(GetDlgItem(hwnd,IDC_BREAKPOINT_ADDRESS),str,256); @@ -156,11 +166,13 @@ bool BreakpointWindow::fetchDialogData(HWND hwnd) } // condition - GetWindowTextA(GetDlgItem(hwnd,IDC_BREAKPOINT_CONDITION),condition,128); + wchar_t tempCond[512]; + GetWindowTextW(GetDlgItem(hwnd, IDC_BREAKPOINT_CONDITION), tempCond, 512); + condition = ConvertWStringToUTF8(tempCond); compiledCondition.clear(); - if (condition[0] != 0) + if (!condition.empty()) { - if (cpu->initExpression(condition,compiledCondition) == false) + if (cpu->initExpression(condition.c_str(), compiledCondition) == false) { snprintf(errorMessage, sizeof(errorMessage), "Invalid expression \"%s\".",str); MessageBoxA(hwnd,errorMessage,"Error",MB_OK); @@ -168,9 +180,18 @@ bool BreakpointWindow::fetchDialogData(HWND hwnd) } } + wchar_t tempLogFormat[512]; + GetWindowTextW(GetDlgItem(hwnd, IDC_BREAKPOINT_LOG_FORMAT), tempLogFormat, 512); + logFormat = ConvertWStringToUTF8(tempLogFormat); + // TODO: Verify format. + return true; } +bool BreakpointWindow::GetCheckState(HWND hwnd, int dlgItem) { + return SendMessage(GetDlgItem(hwnd, dlgItem), BM_GETCHECK, 0, 0) != 0; +} + bool BreakpointWindow::exec() { bp = this; @@ -198,20 +219,22 @@ void BreakpointWindow::addBreakpoint() cond |= MEMCHECK_WRITE_ONCHANGE; CBreakPoints::AddMemCheck(address, address + size, (MemCheckCondition)cond, result); + CBreakPoints::ChangeMemCheckLogFormat(address, address + size, logFormat); } else { // add breakpoint CBreakPoints::AddBreakPoint(address,false); - if (condition[0] != 0) + if (!condition.empty()) { BreakPointCond cond; cond.debug = cpu; - strcpy(cond.expressionString,condition); + cond.expressionString = condition; cond.expression = compiledCondition; CBreakPoints::ChangeBreakPointAddCond(address,cond); } CBreakPoints::ChangeBreakPoint(address, result); + CBreakPoints::ChangeBreakPointLogFormat(address, logFormat); } } @@ -228,6 +251,8 @@ void BreakpointWindow::loadFromMemcheck(MemCheck& memcheck) address = memcheck.start; size = memcheck.end-address; + + logFormat = memcheck.logFormat; } void BreakpointWindow::loadFromBreakpoint(BreakPoint& breakpoint) @@ -240,10 +265,12 @@ void BreakpointWindow::loadFromBreakpoint(BreakPoint& breakpoint) size = 1; if (breakpoint.hasCond) { - strcpy(condition,breakpoint.cond.expressionString); + condition = breakpoint.cond.expressionString; } else { - condition[0] = 0; + condition.clear(); } + + logFormat = breakpoint.logFormat; } void BreakpointWindow::initBreakpoint(u32 _address) @@ -252,5 +279,5 @@ void BreakpointWindow::initBreakpoint(u32 _address) enabled = true; address = _address; size = 1; - condition[0] = 0; + condition.clear(); } diff --git a/Windows/Debugger/BreakpointWindow.h b/Windows/Debugger/BreakpointWindow.h index 31a80470b5..0a79c79d6f 100644 --- a/Windows/Debugger/BreakpointWindow.h +++ b/Windows/Debugger/BreakpointWindow.h @@ -1,4 +1,5 @@ #pragma once +#include #include "Common/CommonWindows.h" #include "Common/CommonTypes.h" #include "Core/Debugger/DebugInterface.h" @@ -17,11 +18,14 @@ class BreakpointWindow bool onChange; u32 address; u32 size; - char condition[128]; + std::string condition; + std::string logFormat; PostfixExpression compiledCondition; static BreakpointWindow* bp; bool fetchDialogData(HWND hwnd); + bool GetCheckState(HWND hwnd, int dlgItem); + public: BreakpointWindow(HWND parent, DebugInterface* cpu): cpu(cpu) { @@ -32,7 +36,6 @@ public: enabled = log = true; address = -1; size = 1; - condition[0] = 0; }; @@ -44,4 +47,4 @@ public: void loadFromMemcheck(MemCheck& memcheck); void loadFromBreakpoint(BreakPoint& memcheck); void initBreakpoint(u32 address); -}; \ No newline at end of file +}; diff --git a/Windows/ppsspp.rc b/Windows/ppsspp.rc index 447d412f81..5135556f6f 100644 --- a/Windows/ppsspp.rc +++ b/Windows/ppsspp.rc @@ -266,7 +266,7 @@ BEGIN CONTROL "",IDC_TABDATATYPE,"SysTabControl32",TCS_BUTTONS,0,1,205,15 END -IDD_BREAKPOINT DIALOGEX 0, 0, 236, 89 +IDD_BREAKPOINT DIALOGEX 0, 0, 236, 109 STYLE DS_SETFONT | DS_MODALFRAME | DS_FIXEDSYS | WS_POPUP | WS_CAPTION | WS_SYSMENU CAPTION "Breakpoint" FONT 8, "MS Shell Dlg", 400, 0, 0x1 @@ -282,10 +282,12 @@ BEGIN CONTROL "On change",IDC_BREAKPOINT_ONCHANGE,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,170,34,50,10 LTEXT "Condition",IDC_STATIC,7,51,31,8 EDITTEXT IDC_BREAKPOINT_CONDITION,41,49,187,14,ES_AUTOHSCROLL - CONTROL "Break",IDC_BREAKPOINT_ENABLED,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,41,71,41,10 - CONTROL "Log",IDC_BREAKPOINT_LOG,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,96,71,27,10 - DEFPUSHBUTTON "OK",IDC_BREAKPOINT_OK,144,68,41,14 - PUSHBUTTON "Cancel",IDC_BREAKPOINT_CANCEL,186,68,42,14 + LTEXT "Log fmt",IDC_STATIC,7,71,31,8 + EDITTEXT IDC_BREAKPOINT_LOG_FORMAT,41,69,187,14,ES_AUTOHSCROLL + CONTROL "Break",IDC_BREAKPOINT_ENABLED,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,41,91,41,10 + CONTROL "Log",IDC_BREAKPOINT_LOG,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,96,91,27,10 + DEFPUSHBUTTON "OK",IDC_BREAKPOINT_OK,144,88,41,14 + PUSHBUTTON "Cancel",IDC_BREAKPOINT_CANCEL,186,88,42,14 END IDD_DUMPMEMORY DIALOGEX 0, 0, 230, 85 diff --git a/Windows/resource.h b/Windows/resource.h index 5c8af70437..66e88a3620 100644 --- a/Windows/resource.h +++ b/Windows/resource.h @@ -163,6 +163,7 @@ #define IDC_GEDBG_MATRICES 1196 #define IDC_GEDBG_FORCEOPAQUE 1197 #define IDC_GEDBG_SHOWCLUT 1198 +#define IDC_BREAKPOINT_LOG_FORMAT 1199 #define ID_SHADERS_BASE 5000 @@ -340,7 +341,7 @@ #ifndef APSTUDIO_READONLY_SYMBOLS #define _APS_NEXT_RESOURCE_VALUE 256 #define _APS_NEXT_COMMAND_VALUE 40165 -#define _APS_NEXT_CONTROL_VALUE 1199 +#define _APS_NEXT_CONTROL_VALUE 1200 #define _APS_NEXT_SYMED_VALUE 101 #endif #endif