* Added a stopped reason and additional info to Thread. ThreadHandler sets

both accordingly.
* The threads view shows the thread states now. Also added tool tips with
  additional info.


git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@33591 a95241bf-73f2-0310-859d-f6bbb57e9c96
This commit is contained in:
Ingo Weinhold
2009-10-15 04:40:33 +00:00
parent acb006cb55
commit 1851e9f3e0
6 changed files with 176 additions and 33 deletions
+23 -12
View File
@@ -93,14 +93,16 @@ ThreadHandler::SetBreakpointAndRun(target_addr_t address)
bool
ThreadHandler::HandleThreadDebugged(ThreadDebuggedEvent* event)
{
return _HandleThreadStopped(NULL);
return _HandleThreadStopped(NULL, THREAD_STOPPED_DEBUGGED);
}
bool
ThreadHandler::HandleDebuggerCall(DebuggerCallEvent* event)
{
return _HandleThreadStopped(NULL);
BString message;
fDebuggerInterface->ReadMemoryString(event->Message(), 1024, message);
return _HandleThreadStopped(NULL, THREAD_STOPPED_DEBUGGER_CALL, message);
}
@@ -155,14 +157,15 @@ ThreadHandler::HandleBreakpointHit(BreakpointHitEvent* event)
}
}
return _HandleThreadStopped(cpuState);
return _HandleThreadStopped(cpuState, THREAD_STOPPED_BREAKPOINT);
}
bool
ThreadHandler::HandleWatchpointHit(WatchpointHitEvent* event)
{
return _HandleThreadStopped(event->GetCpuState());
return _HandleThreadStopped(event->GetCpuState(),
THREAD_STOPPED_WATCHPOINT);
}
@@ -175,14 +178,17 @@ ThreadHandler::HandleSingleStep(SingleStepEvent* event)
return true;
}
return _HandleThreadStopped(event->GetCpuState());
return _HandleThreadStopped(event->GetCpuState(),
THREAD_STOPPED_SINGLE_STEP);
}
bool
ThreadHandler::HandleExceptionOccurred(ExceptionOccurredEvent* event)
{
return _HandleThreadStopped(NULL);
char buffer[256];
get_debug_exception_string(event->Exception(), buffer, sizeof(buffer));
return _HandleThreadStopped(NULL, THREAD_STOPPED_EXCEPTION, buffer);
}
@@ -209,8 +215,10 @@ ThreadHandler::HandleThreadAction(uint32 action)
// When continuing the thread update thread state before actually issuing
// the command, since we need to unlock.
if (action != MSG_THREAD_STOP)
_SetThreadState(THREAD_STATE_RUNNING, NULL);
if (action != MSG_THREAD_STOP) {
_SetThreadState(THREAD_STATE_RUNNING, NULL, THREAD_STOPPED_UNKNOWN,
BString());
}
locker.Unlock();
@@ -372,22 +380,25 @@ ThreadHandler::GetImageDebugInfo(Image* image, ImageDebugInfo*& _info)
bool
ThreadHandler::_HandleThreadStopped(CpuState* cpuState)
ThreadHandler::_HandleThreadStopped(CpuState* cpuState, uint32 stoppedReason,
const BString& stoppedReasonInfo)
{
_ClearContinuationState();
AutoLocker<Team> locker(fThread->GetTeam());
_SetThreadState(THREAD_STATE_STOPPED, cpuState);
_SetThreadState(THREAD_STATE_STOPPED, cpuState, stoppedReason,
stoppedReasonInfo);
return true;
}
void
ThreadHandler::_SetThreadState(uint32 state, CpuState* cpuState)
ThreadHandler::_SetThreadState(uint32 state, CpuState* cpuState,
uint32 stoppedReason, const BString& stoppedReasonInfo)
{
fThread->SetState(state);
fThread->SetState(state, stoppedReason, stoppedReasonInfo);
fThread->SetCpuState(cpuState);
}
+6 -2
View File
@@ -64,10 +64,14 @@ private:
virtual status_t GetImageDebugInfo(Image* image,
ImageDebugInfo*& _info);
bool _HandleThreadStopped(CpuState* cpuState);
bool _HandleThreadStopped(CpuState* cpuState,
uint32 stoppedReason,
const BString& stoppedReasonInfo
= BString());
void _SetThreadState(uint32 state,
CpuState* cpuState);
CpuState* cpuState, uint32 stoppedReason,
const BString& stoppedReasonInfo);
Statement* _GetStatementAtInstructionPointer(
StackFrame* frame);
@@ -6,8 +6,6 @@
#include "ThreadListView.h"
#include <stdio.h>
#include <new>
#include <Looper.h>
@@ -15,6 +13,7 @@
#include <AutoLocker.h>
#include <ObjectList.h>
#include <ToolTip.h>
#include "table/TableColumns.h"
@@ -27,22 +26,23 @@ enum {
// #pragma mark - ThreadsTableModel
class ThreadListView::ThreadsTableModel : public TableModel {
class ThreadListView::ThreadsTableModel : public TableModel,
public TableToolTipProvider {
public:
ThreadsTableModel(Team* team)
:
fTeam(team)
{
Update();
Update(-1);
}
~ThreadsTableModel()
{
fTeam = NULL;
Update();
Update(-1);
}
bool Update()
bool Update(thread_id threadID)
{
if (fTeam == NULL) {
for (int32 i = 0; Thread* thread = fThreads.ItemAt(i); i++)
@@ -61,6 +61,8 @@ public:
// remove no longer existing threads
while (Thread* oldThread = fThreads.ItemAt(index)) {
if (oldThread == newThread) {
if (threadID >= 0 && oldThread->ID() == threadID)
NotifyRowsChanged(index, 1);
index++;
newThread = it.Next();
} else {
@@ -90,7 +92,7 @@ public:
virtual int32 CountColumns() const
{
return 2;
return 3;
}
virtual int32 CountRows() const
@@ -109,6 +111,38 @@ public:
value.SetTo(thread->ID());
return true;
case 1:
{
switch (thread->State()) {
case THREAD_STATE_RUNNING:
value.SetTo("Running", B_VARIANT_DONT_COPY_DATA);
return true;
case THREAD_STATE_STOPPED:
break;
case THREAD_STATE_UNKNOWN:
default:
value.SetTo("?", B_VARIANT_DONT_COPY_DATA);
return true;
}
// thread is stopped -- get the reason
switch (thread->StoppedReason()) {
case THREAD_STOPPED_DEBUGGER_CALL:
value.SetTo("Call", B_VARIANT_DONT_COPY_DATA);
return true;
case THREAD_STOPPED_EXCEPTION:
value.SetTo("Exception", B_VARIANT_DONT_COPY_DATA);
return true;
case THREAD_STOPPED_BREAKPOINT:
case THREAD_STOPPED_WATCHPOINT:
case THREAD_STOPPED_SINGLE_STEP:
case THREAD_STOPPED_DEBUGGED:
case THREAD_STOPPED_UNKNOWN:
default:
value.SetTo("Debugged", B_VARIANT_DONT_COPY_DATA);
return true;
}
}
case 2:
value.SetTo(thread->Name(), B_VARIANT_DONT_COPY_DATA);
return true;
default:
@@ -116,6 +150,57 @@ public:
}
}
virtual bool GetToolTipForTableCell(int32 rowIndex, int32 columnIndex,
BToolTip** _tip)
{
Thread* thread = fThreads.ItemAt(rowIndex);
if (thread == NULL)
return false;
BString text;
text << "Thread: \"" << thread->Name() << "\" (" << thread->ID()
<< ")\n";
switch (thread->State()) {
case THREAD_STATE_RUNNING:
text << "Running";
break;
case THREAD_STATE_STOPPED:
{
switch (thread->StoppedReason()) {
case THREAD_STOPPED_DEBUGGER_CALL:
text << "Called debugger(): "
<< thread->StoppedReasonInfo();
break;
case THREAD_STOPPED_EXCEPTION:
text << "Caused exception: "
<< thread->StoppedReasonInfo();
break;
case THREAD_STOPPED_BREAKPOINT:
case THREAD_STOPPED_WATCHPOINT:
case THREAD_STOPPED_SINGLE_STEP:
case THREAD_STOPPED_DEBUGGED:
case THREAD_STOPPED_UNKNOWN:
default:
text << "Stopped for debugging";
break;
}
break;
}
case THREAD_STATE_UNKNOWN:
default:
text << "Current State Unknown";
break;
}
BTextToolTip* tip = new(std::nothrow) BTextToolTip(text);
if (tip == NULL)
return false;
*_tip = tip;
return true;
}
Thread* ThreadAt(int32 index) const
{
return fThreads.ItemAt(index);
@@ -206,9 +291,14 @@ ThreadListView::MessageReceived(BMessage* message)
{
switch (message->what) {
case MSG_SYNC_THREAD_LIST:
if (fThreadsTableModel != NULL)
fThreadsTableModel->Update();
{
thread_id threadID;
if (message->FindInt32("thread", &threadID) != B_OK)
threadID = -1;
fThreadsTableModel->Update(threadID);
break;
}
default:
BGroupView::MessageReceived(message);
break;
@@ -230,6 +320,16 @@ ThreadListView::ThreadRemoved(const Team::ThreadEvent& event)
}
void
ThreadListView::ThreadStateChanged(const Team::ThreadEvent& event)
{
BMessage message(MSG_SYNC_THREAD_LIST);
message.AddInt32("thread", event.GetThread()->ID());
Looper()->PostMessage(&message, this);
}
void
ThreadListView::TableSelectionChanged(Table* table)
{
@@ -237,10 +337,8 @@ ThreadListView::TableSelectionChanged(Table* table)
return;
Thread* thread = NULL;
if (fThreadsTableModel != NULL) {
TableSelectionModel* selectionModel = table->SelectionModel();
thread = fThreadsTableModel->ThreadAt(selectionModel->RowAt(0));
}
TableSelectionModel* selectionModel = table->SelectionModel();
thread = fThreadsTableModel->ThreadAt(selectionModel->RowAt(0));
fListener->ThreadSelectionChanged(thread);
}
@@ -253,17 +351,19 @@ ThreadListView::_Init()
AddChild(fThreadsTable->ToView());
// columns
fThreadsTable->AddColumn(new Int32TableColumn(0, "ID", 40, 20, 1000,
fThreadsTable->AddColumn(new Int32TableColumn(0, "ID", 60, 20, 1000,
B_TRUNCATE_MIDDLE, B_ALIGN_RIGHT));
fThreadsTable->AddColumn(new StringTableColumn(1, "Name", 80, 40, 1000,
fThreadsTable->AddColumn(new StringTableColumn(1, "State", 80, 40, 1000,
B_TRUNCATE_END, B_ALIGN_LEFT));
fThreadsTable->AddColumn(new StringTableColumn(2, "Name", 200, 40, 1000,
B_TRUNCATE_END, B_ALIGN_LEFT));
fThreadsTable->SetSelectionMode(B_SINGLE_SELECTION_LIST);
fThreadsTable->AddTableListener(this);
fThreadsTableModel = new(std::nothrow) ThreadsTableModel(fTeam);
fThreadsTableModel = new ThreadsTableModel(fTeam);
fThreadsTable->SetTableModel(fThreadsTableModel);
fThreadsTable->ResizeAllColumnsToPreferred();
fThreadsTable->SetToolTipProvider(fThreadsTableModel);
fTeam->AddListener(this);
}
@@ -40,6 +40,8 @@ private:
// Team::Listener
virtual void ThreadAdded(const Team::ThreadEvent& event);
virtual void ThreadRemoved(const Team::ThreadEvent& event);
virtual void ThreadStateChanged(
const Team::ThreadEvent& event);
// TableListener
virtual void TableSelectionChanged(Table* table);
+6 -1
View File
@@ -5,6 +5,8 @@
#include "Thread.h"
#include <stdio.h>
#include "CpuState.h"
#include "StackTrace.h"
#include "Team.h"
@@ -15,6 +17,7 @@ Thread::Thread(Team* team, thread_id threadID)
fTeam(team),
fID(threadID),
fState(THREAD_STATE_UNKNOWN),
fStoppedReason(THREAD_STOPPED_UNKNOWN),
fCpuState(NULL),
fStackTrace(NULL)
{
@@ -52,12 +55,14 @@ Thread::SetName(const BString& name)
void
Thread::SetState(uint32 state)
Thread::SetState(uint32 state, uint32 reason, const BString& info)
{
if (state == fState)
return;
fState = state;
fStoppedReason = reason;
fStoppedReasonInfo = info;
// unset CPU state and stack trace, if the thread isn't stopped
if (fState != THREAD_STATE_STOPPED) {
+22 -1
View File
@@ -17,12 +17,24 @@ class StackTrace;
class Team;
// general thread state
enum {
THREAD_STATE_UNKNOWN,
THREAD_STATE_RUNNING,
THREAD_STATE_STOPPED
};
// reason why stopped
enum {
THREAD_STOPPED_UNKNOWN,
THREAD_STOPPED_DEBUGGED,
THREAD_STOPPED_DEBUGGER_CALL,
THREAD_STOPPED_BREAKPOINT,
THREAD_STOPPED_WATCHPOINT,
THREAD_STOPPED_SINGLE_STEP,
THREAD_STOPPED_EXCEPTION
};
class Thread : public Referenceable, public DoublyLinkedListLinkImpl<Thread> {
public:
@@ -40,7 +52,14 @@ public:
void SetName(const BString& name);
uint32 State() const { return fState; }
void SetState(uint32 state);
void SetState(uint32 state,
uint32 reason = THREAD_STOPPED_UNKNOWN,
const BString& info = BString());
uint32 StoppedReason() const
{ return fStoppedReason; }
const BString& StoppedReasonInfo() const
{ return fStoppedReasonInfo; }
CpuState* GetCpuState() const { return fCpuState; }
void SetCpuState(CpuState* state);
@@ -53,6 +72,8 @@ private:
thread_id fID;
BString fName;
uint32 fState;
uint32 fStoppedReason;
BString fStoppedReasonInfo;
CpuState* fCpuState;
StackTrace* fStackTrace;
};