Improved debugger search functions.

- Generalized result dialog.
- Find value display results using result dialog.
This commit is contained in:
Jean-Philip Desjardins 2017-05-04 10:51:29 -04:00
parent 95c743dbfb
commit ef51be3768
7 changed files with 187 additions and 157 deletions

View File

@ -25,6 +25,8 @@
#define PREF_DEBUGGER_MEMORYVIEW_BYTEWIDTH "debugger.memoryview.bytewidth"
#define FIND_MAX_ADDRESS 0x02000000
CDebugger::CDebugger(CPS2VM& virtualMachine)
: m_virtualMachine(virtualMachine)
{
@ -67,10 +69,10 @@ CDebugger::CDebugger(CPS2VM& virtualMachine)
m_threadsView->Show(SW_HIDE);
m_threadsView->OnGotoAddress.connect(boost::bind(&CDebugger::OnThreadsViewAddressDblClick, this, _1));
//Find Callers View Initialization
m_findCallersView = new CFindCallersViewWnd(m_pMDIClient->m_hWnd);
m_findCallersView->Show(SW_HIDE);
m_findCallersView->AddressSelected.connect([&] (uint32 address) { OnFindCallersAddressDblClick(address); });
//Address List View Initialization
m_addressListView = new CAddressListViewWnd(m_pMDIClient->m_hWnd);
m_addressListView->Show(SW_HIDE);
m_addressListView->AddressSelected.connect([&] (uint32 address) { OnFindCallersAddressDblClick(address); });
//Debug Views Initialization
m_nCurrentView = -1;
@ -242,24 +244,23 @@ void CDebugger::StepCPU()
void CDebugger::FindValue()
{
Framework::Win32::CInputBox Input(_T("Find Value in Memory"), _T("Enter value to find:"), _T("00000000"));
Framework::Win32::CInputBox input(_T("Find Value in Memory"), _T("Enter value to find:"), _T("00000000"));
const TCHAR* sValue = Input.GetValue(m_hWnd);
if(sValue == NULL) return;
auto valueString = input.GetValue(m_hWnd);
if(!valueString) return;
uint32 nValue = 0;
_stscanf(sValue, _T("%x"), &nValue);
if(nValue == 0) return;
uint32 targetValue = 0;
auto scanned = _stscanf(valueString, _T("%x"), &targetValue);
if(scanned == 0) return;
printf("Search results for 0x%0.8X\r\n", nValue);
printf("-----------------------------\r\n");
for(unsigned int i = 0; i < PS2::EE_RAM_SIZE; i += 4)
{
if(*(uint32*)&m_virtualMachine.m_ee->m_ram[i] == nValue)
{
printf("0x%0.8X\r\n", i);
}
}
auto context = GetCurrentView()->GetContext();
auto title = string_format(_T("Search results for 0x%08X"), targetValue);
auto refs = FindValueRefs(context, targetValue);
m_addressListView->SetTitle(std::move(title));
m_addressListView->SetAddressList(std::move(refs));
m_addressListView->Show(SW_SHOW);
m_addressListView->SetFocus();
}
void CDebugger::AssembleJAL()
@ -621,6 +622,36 @@ CCallStackWnd* CDebugger::GetCallStackWindow()
return GetCurrentView()->GetCallStackWindow();
}
std::vector<uint32> CDebugger::FindCallers(CMIPS* context, uint32 address)
{
std::vector<uint32> callers;
for(uint32 i = 0; i < FIND_MAX_ADDRESS; i += 4)
{
uint32 opcode = context->m_pMemoryMap->GetInstruction(i);
uint32 ea = context->m_pArch->GetInstructionEffectiveAddress(context, i, opcode);
if(ea == address)
{
callers.push_back(i);
}
}
return callers;
}
std::vector<uint32> CDebugger::FindValueRefs(CMIPS* context, uint32 targetValue)
{
std::vector<uint32> refs;
for(uint32 i = 0; i < FIND_MAX_ADDRESS; i += 4)
{
uint32 valueAtAddress = context->m_pMemoryMap->GetWord(i);
if(valueAtAddress == targetValue)
//if((valueAtAddress & 0xFFFF) == targetValue)
{
refs.push_back(i);
}
}
return refs;
}
void CDebugger::CreateAccelerators()
{
Framework::Win32::CAcceleratorTableGenerator generator;
@ -798,10 +829,26 @@ void CDebugger::OnExecutableUnloading()
void CDebugger::OnFindCallersRequested(uint32 address)
{
auto context = GetCurrentView()->GetContext();
auto callers = FindCallers(context, address);
auto title =
[&] ()
{
auto functionName = context->m_Functions.Find(address);
if(functionName)
{
return string_format(_T("Find Callers For '%s' (0x%0.8X)"),
string_cast<std::tstring>(functionName).c_str(), address);
}
else
{
return string_format(_T("Find Callers For 0x%0.8X"), address);
}
}();
m_findCallersView->FindCallers(context, address);
m_findCallersView->Show(SW_SHOW);
m_findCallersView->SetFocus();
m_addressListView->SetAddressList(std::move(callers));
m_addressListView->SetTitle(std::move(title));
m_addressListView->Show(SW_SHOW);
m_addressListView->SetFocus();
}
void CDebugger::OnFindCallersAddressDblClick(uint32 address)

View File

@ -5,7 +5,7 @@
#include "FunctionsView.h"
#include "ThreadsViewWnd.h"
#include "DebugView.h"
#include "./Debugger/FindCallersViewWnd.h"
#include "./Debugger/AddressListViewWnd.h"
#include "../PS2VM.h"
class CDebugger : public Framework::Win32::CMDIFrame, public boost::signals2::trackable
@ -66,6 +66,10 @@ private:
CRegViewWnd* GetRegisterViewWindow();
CCallStackWnd* GetCallStackWindow();
//Search functions
static std::vector<uint32> FindCallers(CMIPS*, uint32);
static std::vector<uint32> FindValueRefs(CMIPS*, uint32);
//Event handlers
void OnFunctionsViewFunctionDblClick(uint32);
void OnFunctionsViewFunctionsStateChange();
@ -87,7 +91,7 @@ private:
CFunctionsView* m_pFunctionsView = nullptr;
CThreadsViewWnd* m_threadsView = nullptr;
CDebugView* m_pView[DEBUGVIEW_MAX];
CFindCallersViewWnd* m_findCallersView = nullptr;
CAddressListViewWnd* m_addressListView = nullptr;
unsigned int m_nCurrentView;
CPS2VM& m_virtualMachine;
};

View File

@ -0,0 +1,80 @@
#include "AddressListViewWnd.h"
#include "win32/DpiUtils.h"
#include "../resource.h"
#include "string_format.h"
#include "string_cast.h"
#define WND_STYLE (WS_CLIPSIBLINGS | WS_CLIPCHILDREN | WS_THICKFRAME | WS_CAPTION | WS_SYSMENU | WS_CHILD | WS_MAXIMIZEBOX)
CAddressListViewWnd::CAddressListViewWnd(HWND parentWnd)
{
auto windowRect = Framework::Win32::PointsToPixels(Framework::Win32::CRect(0, 0, 700, 400));
Create(NULL, Framework::Win32::CDefaultWndClass().GetName(), _T(""), WND_STYLE, windowRect, parentWnd, NULL);
SetClassPtr();
m_addressListBox = Framework::Win32::CListBox(m_hWnd, Framework::Win32::CRect(0, 0, 10, 10), WS_VSCROLL | LBS_NOTIFY | LBS_NOINTEGRALHEIGHT);
RefreshLayout();
}
void CAddressListViewWnd::SetTitle(std::tstring title)
{
SetText(title.c_str());
}
void CAddressListViewWnd::SetAddressList(AddressList addressList)
{
m_addressListBox.ResetContent();
for(const auto& address : addressList)
{
auto addressString = string_format(_T("0x%08X"), address);
auto itemIdx = m_addressListBox.AddString(addressString.c_str());
m_addressListBox.SetItemData(itemIdx, address);
}
}
long CAddressListViewWnd::OnSize(unsigned int, unsigned int width, unsigned int height)
{
RefreshLayout();
return TRUE;
}
long CAddressListViewWnd::OnCommand(unsigned short, unsigned short cmd, HWND senderWnd)
{
if(CWindow::IsCommandSource(&m_addressListBox, senderWnd))
{
switch(cmd)
{
case LBN_DBLCLK:
{
auto selection = m_addressListBox.GetCurrentSelection();
if(selection != -1)
{
auto selectedAddress = m_addressListBox.GetItemData(selection);
AddressSelected(selectedAddress);
}
}
break;
}
}
return TRUE;
}
long CAddressListViewWnd::OnSysCommand(unsigned int cmd, LPARAM)
{
switch(cmd)
{
case SC_CLOSE:
Show(SW_HIDE);
return FALSE;
}
return TRUE;
}
void CAddressListViewWnd::RefreshLayout()
{
auto clientRect = GetClientRect();
clientRect.Inflate(-5, -5);
m_addressListBox.SetSizePosition(clientRect);
}

View File

@ -0,0 +1,31 @@
#pragma once
#include <boost/signals2.hpp>
#include "win32/MDIChild.h"
#include "win32/ListBox.h"
class CAddressListViewWnd : public Framework::Win32::CMDIChild
{
public:
typedef std::vector<uint32> AddressList;
typedef boost::signals2::signal<void (uint32)> AddressSelectedEvent;
CAddressListViewWnd(HWND);
virtual ~CAddressListViewWnd() = default;
void SetTitle(std::tstring);
void SetAddressList(AddressList);
AddressSelectedEvent AddressSelected;
protected:
long OnSize(unsigned int, unsigned int, unsigned int) override;
long OnCommand(unsigned short, unsigned short, HWND) override;
long OnSysCommand(unsigned int cmd, LPARAM) override;
private:
void RefreshLayout();
Framework::Win32::CListBox m_addressListBox;
};

View File

@ -1,103 +0,0 @@
#include "FindCallersViewWnd.h"
#include "win32/DpiUtils.h"
#include "../resource.h"
#include "string_format.h"
#include "string_cast.h"
#define WND_STYLE (WS_CLIPSIBLINGS | WS_CLIPCHILDREN | WS_THICKFRAME | WS_CAPTION | WS_SYSMENU | WS_CHILD | WS_MAXIMIZEBOX)
#define MAX_ADDRESS 0x02000000
CFindCallersViewWnd::CFindCallersViewWnd(HWND parentWnd)
{
auto windowRect = Framework::Win32::PointsToPixels(Framework::Win32::CRect(0, 0, 700, 400));
Create(NULL, Framework::Win32::CDefaultWndClass().GetName(), _T(""), WND_STYLE, windowRect, parentWnd, NULL);
SetClassPtr();
m_callersList = Framework::Win32::CListBox(m_hWnd, Framework::Win32::CRect(0, 0, 10, 10), WS_VSCROLL | LBS_NOTIFY | LBS_NOINTEGRALHEIGHT);
RefreshLayout();
}
CFindCallersViewWnd::~CFindCallersViewWnd()
{
}
long CFindCallersViewWnd::OnSize(unsigned int, unsigned int width, unsigned int height)
{
RefreshLayout();
return TRUE;
}
long CFindCallersViewWnd::OnCommand(unsigned short, unsigned short cmd, HWND senderWnd)
{
if(CWindow::IsCommandSource(&m_callersList, senderWnd))
{
switch(cmd)
{
case LBN_DBLCLK:
{
auto selection = m_callersList.GetCurrentSelection();
if(selection != -1)
{
auto selectedAddress = m_callersList.GetItemData(selection);
AddressSelected(selectedAddress);
}
}
break;
}
}
return TRUE;
}
long CFindCallersViewWnd::OnSysCommand(unsigned int cmd, LPARAM)
{
switch(cmd)
{
case SC_CLOSE:
Show(SW_HIDE);
return FALSE;
}
return TRUE;
}
void CFindCallersViewWnd::RefreshLayout()
{
auto clientRect = GetClientRect();
clientRect.Inflate(-5, -5);
m_callersList.SetSizePosition(clientRect);
}
void CFindCallersViewWnd::FindCallers(CMIPS* context, uint32 address)
{
m_callersList.ResetContent();
auto functionName = context->m_Functions.Find(address);
auto title = std::tstring();
if(functionName)
{
title = string_format(_T("Find Callers For '%s' (0x%0.8X)"),
string_cast<std::tstring>(functionName).c_str(), address);
}
else
{
title = string_format(_T("Find Callers For 0x%0.8X"), address);
}
SetText(title.c_str());
for(uint32 i = 0; i < MAX_ADDRESS; i += 4)
{
uint32 opcode = context->m_pMemoryMap->GetInstruction(i);
uint32 ea = context->m_pArch->GetInstructionEffectiveAddress(context, i, opcode);
if(ea == address)
{
auto callerName = string_format(_T("0x%0.8X"), i);
auto itemIdx = m_callersList.AddString(callerName.c_str());
m_callersList.SetItemData(itemIdx, i);
}
}
}

View File

@ -1,29 +0,0 @@
#pragma once
#include <boost/signals2.hpp>
#include "win32/MDIChild.h"
#include "win32/ListBox.h"
#include "../../MIPS.h"
class CFindCallersViewWnd : public Framework::Win32::CMDIChild
{
public:
typedef boost::signals2::signal<void (uint32)> AddressSelectedEvent;
CFindCallersViewWnd(HWND);
virtual ~CFindCallersViewWnd();
void FindCallers(CMIPS*, uint32);
AddressSelectedEvent AddressSelected;
protected:
long OnSize(unsigned int, unsigned int, unsigned int) override;
long OnCommand(unsigned short, unsigned short, HWND) override;
long OnSysCommand(unsigned int cmd, LPARAM) override;
private:
void RefreshLayout();
Framework::Win32::CListBox m_callersList;
};

View File

@ -887,7 +887,7 @@ if (WIN32)
../Source/ui_win32/CdromSelectionWnd.cpp
../Source/ui_win32/CommandSink.cpp
../Source/ui_win32/DebugExpressionEvaluator.cpp
../Source/ui_win32/Debugger/FindCallersViewWnd.cpp
../Source/ui_win32/Debugger/AddressListViewWnd.cpp
../Source/ui_win32/DebugUtils.cpp
../Source/ui_win32/DirectXControl.cpp
../Source/ui_win32/DisAsm.cpp