Added view to show registers. Doesn't look particularly nice, but seems to work.
git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@31122 a95241bf-73f2-0310-859d-f6bbb57e9c96
This commit is contained in:
parent
8c724eb86c
commit
15b6b23934
248
src/apps/debugger/gui/team_window/RegisterView.cpp
Normal file
248
src/apps/debugger/gui/team_window/RegisterView.cpp
Normal file
@ -0,0 +1,248 @@
|
||||
/*
|
||||
* Copyright 2009, Ingo Weinhold, ingo_weinhold@gmx.de.
|
||||
* Distributed under the terms of the MIT License.
|
||||
*/
|
||||
|
||||
#include "RegisterView.h"
|
||||
|
||||
#include <stdio.h>
|
||||
|
||||
#include <new>
|
||||
|
||||
#include "table/TableColumns.h"
|
||||
|
||||
#include "Architecture.h"
|
||||
#include "CpuState.h"
|
||||
#include "Register.h"
|
||||
|
||||
|
||||
// #pragma mark - RegisterValueColumn
|
||||
|
||||
|
||||
class RegisterView::RegisterValueColumn : public StringTableColumn {
|
||||
public:
|
||||
RegisterValueColumn(int32 modelIndex, const char* title, float width,
|
||||
float minWidth, float maxWidth, uint32 truncate = B_TRUNCATE_MIDDLE,
|
||||
alignment align = B_ALIGN_RIGHT)
|
||||
:
|
||||
StringTableColumn(modelIndex, title, width, minWidth, maxWidth,
|
||||
truncate, align)
|
||||
{
|
||||
}
|
||||
|
||||
protected:
|
||||
virtual BField* PrepareField(const Variant& value) const
|
||||
{
|
||||
char buffer[64];
|
||||
return StringTableColumn::PrepareField(
|
||||
Variant(_ToString(value, buffer, sizeof(buffer)),
|
||||
VARIANT_DONT_COPY_DATA));
|
||||
}
|
||||
|
||||
virtual int CompareValues(const Variant& a, const Variant& b)
|
||||
{
|
||||
// If neither value is a number, compare the strings. If only one value
|
||||
// is a number, it is considered to be greater.
|
||||
if (!a.IsNumber()) {
|
||||
if (b.IsNumber())
|
||||
return -1;
|
||||
char bufferA[64];
|
||||
char bufferB[64];
|
||||
return StringTableColumn::CompareValues(
|
||||
Variant(_ToString(a, bufferA, sizeof(bufferA)),
|
||||
VARIANT_DONT_COPY_DATA),
|
||||
Variant(_ToString(b, bufferB, sizeof(bufferB)),
|
||||
VARIANT_DONT_COPY_DATA));
|
||||
}
|
||||
|
||||
if (!b.IsNumber())
|
||||
return 1;
|
||||
|
||||
// If either value is floating point, we compare floating point values.
|
||||
if (a.IsFloat() || b.IsFloat()) {
|
||||
double valueA = a.ToDouble();
|
||||
double valueB = b.ToDouble();
|
||||
return valueA < valueB ? -1 : (valueA == valueB ? 0 : 1);
|
||||
}
|
||||
|
||||
uint64 valueA = a.ToUInt64();
|
||||
uint64 valueB = b.ToUInt64();
|
||||
return valueA < valueB ? -1 : (valueA == valueB ? 0 : 1);
|
||||
}
|
||||
|
||||
private:
|
||||
const char* _ToString(const Variant& value, char* buffer,
|
||||
size_t bufferSize) const
|
||||
{
|
||||
if (!value.IsNumber())
|
||||
return value.ToString();
|
||||
|
||||
switch (value.Type()) {
|
||||
case B_FLOAT_TYPE:
|
||||
case B_DOUBLE_TYPE:
|
||||
snprintf(buffer, bufferSize, "%g", value.ToDouble());
|
||||
break;
|
||||
case B_INT8_TYPE:
|
||||
case B_UINT8_TYPE:
|
||||
snprintf(buffer, bufferSize, "0x%02x", value.ToUInt8());
|
||||
break;
|
||||
case B_INT16_TYPE:
|
||||
case B_UINT16_TYPE:
|
||||
snprintf(buffer, bufferSize, "0x%04x", value.ToUInt16());
|
||||
break;
|
||||
case B_INT32_TYPE:
|
||||
case B_UINT32_TYPE:
|
||||
snprintf(buffer, bufferSize, "0x%08lx", value.ToUInt32());
|
||||
break;
|
||||
case B_INT64_TYPE:
|
||||
case B_UINT64_TYPE:
|
||||
default:
|
||||
snprintf(buffer, bufferSize, "0x%016llx", value.ToUInt64());
|
||||
break;
|
||||
}
|
||||
|
||||
return buffer;
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
// #pragma mark - RegisterTableModel
|
||||
|
||||
|
||||
class RegisterView::RegisterTableModel : public TableModel {
|
||||
public:
|
||||
RegisterTableModel(Architecture* architecture)
|
||||
:
|
||||
fArchitecture(architecture),
|
||||
fCpuState(NULL)
|
||||
{
|
||||
}
|
||||
|
||||
~RegisterTableModel()
|
||||
{
|
||||
}
|
||||
|
||||
void SetCpuState(CpuState* cpuState)
|
||||
{
|
||||
fCpuState = cpuState;
|
||||
|
||||
NotifyRowsChanged(0, CountRows());
|
||||
}
|
||||
|
||||
virtual int32 CountColumns() const
|
||||
{
|
||||
return 2;
|
||||
}
|
||||
|
||||
virtual int32 CountRows() const
|
||||
{
|
||||
return fArchitecture->CountRegisters();
|
||||
}
|
||||
|
||||
virtual bool GetValueAt(int32 rowIndex, int32 columnIndex, Variant& value)
|
||||
{
|
||||
if (rowIndex < 0 || rowIndex >= fArchitecture->CountRegisters())
|
||||
return false;
|
||||
|
||||
const Register* reg = fArchitecture->Registers() + rowIndex;
|
||||
|
||||
switch (columnIndex) {
|
||||
case 0:
|
||||
value.SetTo(reg->Name(), VARIANT_DONT_COPY_DATA);
|
||||
return true;
|
||||
case 1:
|
||||
if (fCpuState == NULL)
|
||||
return false;
|
||||
if (!fCpuState->GetRegisterValue(reg, value))
|
||||
value.SetTo("?", VARIANT_DONT_COPY_DATA);
|
||||
return true;
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
private:
|
||||
Architecture* fArchitecture;
|
||||
CpuState* fCpuState;
|
||||
};
|
||||
|
||||
|
||||
// #pragma mark - RegisterView
|
||||
|
||||
|
||||
RegisterView::RegisterView(Architecture* architecture)
|
||||
:
|
||||
BGroupView(B_VERTICAL),
|
||||
fArchitecture(architecture),
|
||||
fRegisterTable(NULL),
|
||||
fRegisterTableModel(NULL)
|
||||
{
|
||||
SetName("Registers");
|
||||
}
|
||||
|
||||
|
||||
RegisterView::~RegisterView()
|
||||
{
|
||||
SetCpuState(NULL);
|
||||
fRegisterTable->SetTableModel(NULL);
|
||||
delete fRegisterTableModel;
|
||||
}
|
||||
|
||||
|
||||
/*static*/ RegisterView*
|
||||
RegisterView::Create(Architecture* architecture)
|
||||
{
|
||||
RegisterView* self = new RegisterView(architecture);
|
||||
|
||||
try {
|
||||
self->_Init();
|
||||
} catch (...) {
|
||||
delete self;
|
||||
throw;
|
||||
}
|
||||
|
||||
return self;
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
RegisterView::SetCpuState(CpuState* cpuState)
|
||||
{
|
||||
if (cpuState == fCpuState)
|
||||
return;
|
||||
|
||||
if (fCpuState != NULL)
|
||||
fCpuState->RemoveReference();
|
||||
|
||||
fCpuState = cpuState;
|
||||
|
||||
if (fCpuState != NULL)
|
||||
fCpuState->AddReference();
|
||||
|
||||
fRegisterTableModel->SetCpuState(fCpuState);
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
RegisterView::TableRowInvoked(Table* table, int32 rowIndex)
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
RegisterView::_Init()
|
||||
{
|
||||
fRegisterTable = new Table("register list", 0);
|
||||
AddChild(fRegisterTable->ToView());
|
||||
|
||||
// columns
|
||||
fRegisterTable->AddColumn(new StringTableColumn(0, "Register", 80, 40, 1000,
|
||||
B_TRUNCATE_END, B_ALIGN_LEFT));
|
||||
fRegisterTable->AddColumn(new RegisterValueColumn(1, "Value", 80, 40, 1000,
|
||||
B_TRUNCATE_END, B_ALIGN_RIGHT));
|
||||
|
||||
fRegisterTableModel = new RegisterTableModel(fArchitecture);
|
||||
fRegisterTable->SetTableModel(fRegisterTableModel);
|
||||
|
||||
fRegisterTable->AddTableListener(this);
|
||||
}
|
45
src/apps/debugger/gui/team_window/RegisterView.h
Normal file
45
src/apps/debugger/gui/team_window/RegisterView.h
Normal file
@ -0,0 +1,45 @@
|
||||
/*
|
||||
* Copyright 2009, Ingo Weinhold, ingo_weinhold@gmx.de.
|
||||
* Distributed under the terms of the MIT License.
|
||||
*/
|
||||
#ifndef REGISTER_VIEW_H
|
||||
#define REGISTER_VIEW_H
|
||||
|
||||
#include <GroupView.h>
|
||||
|
||||
#include "table/Table.h"
|
||||
#include "Team.h"
|
||||
|
||||
|
||||
class Architecture;
|
||||
|
||||
|
||||
class RegisterView : public BGroupView, private TableListener {
|
||||
public:
|
||||
RegisterView(Architecture* architecture);
|
||||
~RegisterView();
|
||||
|
||||
static RegisterView* Create(Architecture* architecture);
|
||||
// throws
|
||||
|
||||
void SetCpuState(CpuState* cpuState);
|
||||
|
||||
private:
|
||||
class RegisterValueColumn;
|
||||
class RegisterTableModel;
|
||||
|
||||
private:
|
||||
// TableListener
|
||||
virtual void TableRowInvoked(Table* table, int32 rowIndex);
|
||||
|
||||
void _Init();
|
||||
|
||||
private:
|
||||
Architecture* fArchitecture;
|
||||
CpuState* fCpuState;
|
||||
Table* fRegisterTable;
|
||||
RegisterTableModel* fRegisterTableModel;
|
||||
};
|
||||
|
||||
|
||||
#endif // REGISTER_VIEW_H
|
@ -16,8 +16,10 @@
|
||||
|
||||
#include <AutoLocker.h>
|
||||
|
||||
#include "CpuState.h"
|
||||
#include "ImageListView.h"
|
||||
#include "MessageCodes.h"
|
||||
#include "RegisterView.h"
|
||||
#include "TeamDebugModel.h"
|
||||
|
||||
|
||||
@ -32,8 +34,10 @@ TeamWindow::TeamWindow(TeamDebugModel* debugModel, Listener* listener)
|
||||
fActiveThread(NULL),
|
||||
fListener(listener),
|
||||
fTabView(NULL),
|
||||
fLocalsTabView(NULL),
|
||||
fThreadListView(NULL),
|
||||
fImageListView(NULL),
|
||||
fRegisterView(NULL),
|
||||
fRunButton(NULL),
|
||||
fStepOverButton(NULL),
|
||||
fStepIntoButton(NULL),
|
||||
@ -95,7 +99,16 @@ TeamWindow::MessageReceived(BMessage* message)
|
||||
_HandleThreadStateChanged(threadID);
|
||||
break;
|
||||
}
|
||||
// case MSG_THREAD_CPU_STATE_CHANGED:
|
||||
case MSG_THREAD_CPU_STATE_CHANGED:
|
||||
{
|
||||
int32 threadID;
|
||||
if (message->FindInt32("thread", &threadID) != B_OK)
|
||||
break;
|
||||
|
||||
_HandleCpuStateChanged(threadID);
|
||||
break;
|
||||
}
|
||||
|
||||
// case MSG_THREAD_STACK_TRACE_CHANGED:
|
||||
|
||||
default:
|
||||
@ -131,18 +144,18 @@ TeamWindow::ThreadStateChanged(const Team::ThreadEvent& event)
|
||||
void
|
||||
TeamWindow::ThreadCpuStateChanged(const Team::ThreadEvent& event)
|
||||
{
|
||||
// BMessage message(MSG_THREAD_CPU_STATE_CHANGED);
|
||||
// message.AddInt32("thread", event.GetThread()->ID());
|
||||
// PostMessage(&message);
|
||||
BMessage message(MSG_THREAD_CPU_STATE_CHANGED);
|
||||
message.AddInt32("thread", event.GetThread()->ID());
|
||||
PostMessage(&message);
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
TeamWindow::ThreadStackTraceChanged(const Team::ThreadEvent& event)
|
||||
{
|
||||
// BMessage message(MSG_THREAD_STACK_TRACE_CHANGED);
|
||||
// message.AddInt32("thread", event.GetThread()->ID());
|
||||
// PostMessage(&message);
|
||||
BMessage message(MSG_THREAD_STACK_TRACE_CHANGED);
|
||||
message.AddInt32("thread", event.GetThread()->ID());
|
||||
PostMessage(&message);
|
||||
}
|
||||
|
||||
|
||||
@ -162,7 +175,7 @@ TeamWindow::_Init()
|
||||
.End()
|
||||
.AddSplit(B_HORIZONTAL, 3.0f)
|
||||
.Add(new BTextView("source view"), 3.0f)
|
||||
.Add(new BTextView("variables view"))
|
||||
.Add(fLocalsTabView = new BTabView("locals view"))
|
||||
.End()
|
||||
.End()
|
||||
.End();
|
||||
@ -183,6 +196,14 @@ TeamWindow::_Init()
|
||||
.Add(fImageListView = ImageListView::Create())
|
||||
.Add(new BTextView("source files"));
|
||||
|
||||
// add local variables tab
|
||||
BView* tab = new BTextView("Variables");
|
||||
fLocalsTabView->AddTab(tab);
|
||||
|
||||
// add registers tab
|
||||
tab = fRegisterView = RegisterView::Create(fDebugModel->GetArchitecture());
|
||||
fLocalsTabView->AddTab(tab);
|
||||
|
||||
fThreadListView->SetTeam(fDebugModel->GetTeam());
|
||||
fImageListView->SetTeam(fDebugModel->GetTeam());
|
||||
|
||||
@ -210,6 +231,15 @@ TeamWindow::_SetActiveThread(::Thread* thread)
|
||||
|
||||
AutoLocker<TeamDebugModel> locker(fDebugModel);
|
||||
_UpdateRunButtons();
|
||||
|
||||
CpuState* cpuState = fActiveThread != NULL
|
||||
? fActiveThread->GetCpuState() : NULL;
|
||||
Reference<CpuState> reference(cpuState);
|
||||
// hold a reference until the register view has one
|
||||
|
||||
locker.Unlock();
|
||||
|
||||
fRegisterView->SetCpuState(cpuState);
|
||||
}
|
||||
|
||||
|
||||
@ -258,6 +288,26 @@ TeamWindow::_HandleThreadStateChanged(thread_id threadID)
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
TeamWindow::_HandleCpuStateChanged(thread_id threadID)
|
||||
{
|
||||
// We're only interested in the currently selected thread
|
||||
if (fActiveThread == NULL || threadID != fActiveThread->ID())
|
||||
return;
|
||||
|
||||
AutoLocker<TeamDebugModel> locker(fDebugModel);
|
||||
|
||||
CpuState* cpuState = fActiveThread != NULL
|
||||
? fActiveThread->GetCpuState() : NULL;
|
||||
Reference<CpuState> reference(cpuState);
|
||||
// hold a reference until the register view has one
|
||||
|
||||
locker.Unlock();
|
||||
|
||||
fRegisterView->SetCpuState(cpuState);
|
||||
}
|
||||
|
||||
|
||||
// #pragma mark - Listener
|
||||
|
||||
|
||||
|
@ -15,6 +15,7 @@
|
||||
class BButton;
|
||||
class BTabView;
|
||||
class ImageListView;
|
||||
class RegisterView;
|
||||
class TeamDebugModel;
|
||||
|
||||
|
||||
@ -53,14 +54,17 @@ private:
|
||||
void _UpdateRunButtons();
|
||||
|
||||
void _HandleThreadStateChanged(thread_id threadID);
|
||||
void _HandleCpuStateChanged(thread_id threadID);
|
||||
|
||||
private:
|
||||
TeamDebugModel* fDebugModel;
|
||||
::Thread* fActiveThread;
|
||||
Listener* fListener;
|
||||
BTabView* fTabView;
|
||||
BTabView* fLocalsTabView;
|
||||
ThreadListView* fThreadListView;
|
||||
ImageListView* fImageListView;
|
||||
RegisterView* fRegisterView;
|
||||
BButton* fRunButton;
|
||||
BButton* fStepOverButton;
|
||||
BButton* fStepIntoButton;
|
||||
|
Loading…
Reference in New Issue
Block a user