Initial skeletons of the model (Team, Thread, Image) and the controller

(TeamDebugger) for debugging a team.


git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@31068 a95241bf-73f2-0310-859d-f6bbb57e9c96
This commit is contained in:
Ingo Weinhold 2009-06-16 00:25:36 +00:00
parent 87c085991f
commit 008dd42650
10 changed files with 593 additions and 5 deletions

View File

@ -0,0 +1,25 @@
/*
* Copyright 2009, Ingo Weinhold, ingo_weinhold@gmx.de.
* Distributed under the terms of the MIT License.
*/
#include "Image.h"
Image::Image(const image_info& imageInfo)
:
fInfo(imageInfo)
{
}
Image::~Image()
{
}
status_t
Image::Init()
{
return B_OK;
}

32
src/apps/debugger/Image.h Normal file
View File

@ -0,0 +1,32 @@
/*
* Copyright 2009, Ingo Weinhold, ingo_weinhold@gmx.de.
* Distributed under the terms of the MIT License.
*/
#ifndef IMAGE_H
#define IMAGE_H
#include <image.h>
#include <util/DoublyLinkedList.h>
class Image : public DoublyLinkedListLinkImpl<Image> {
public:
Image(const image_info& imageInfo);
~Image();
status_t Init();
image_id ID() const { return fInfo.id; }
const char* Name() const { return fInfo.name; }
const image_info& Info() const { return fInfo; }
private:
image_info fInfo;
};
typedef DoublyLinkedList<Image> ImageList;
#endif // IMAGE_H

View File

@ -10,6 +10,11 @@ Application Debugger :
debugger.cpp
ElfFile.cpp
Image.cpp
TeamDebugger.cpp
Team.cpp
Thread.cpp
# DWARF
# attribute_classes.cpp
# AttributeValue.cpp
@ -19,6 +24,7 @@ Application Debugger :
# SourceLanguageInfo.cpp
# tag_names.cpp
: $(TARGET_LIBSUPC++)
: $(TARGET_LIBSUPC++) be
;
HaikuSubInclude gui running_teams_window ;

164
src/apps/debugger/Team.cpp Normal file
View File

@ -0,0 +1,164 @@
/*
* Copyright 2009, Ingo Weinhold, ingo_weinhold@gmx.de.
* Distributed under the terms of the MIT License.
*/
#include "Team.h"
#include <new>
Team::Team(team_id teamID)
:
fID(teamID)
{
}
Team::~Team()
{
while (Image* image = fImages.RemoveHead())
delete image;
while (Thread* thread = fThreads.RemoveHead())
delete thread;
}
status_t
Team::Init()
{
return BLocker::InitCheck();
}
void
Team::SetName(const BString& name)
{
fName = name;
}
void
Team::AddThread(Thread* thread)
{
fThreads.Add(thread);
}
status_t
Team::AddThread(const thread_info& threadInfo, Thread** _thread)
{
Thread* thread = new(std::nothrow) Thread(threadInfo.thread);
if (thread == NULL)
return B_NO_MEMORY;
status_t error = thread->Init();
if (error != B_OK) {
delete thread;
return error;
}
thread->SetName(threadInfo.name);
AddThread(thread);
if (_thread != NULL)
*_thread = thread;
return B_OK;
}
void
Team::RemoveThread(Thread* thread)
{
fThreads.Remove(thread);
}
bool
Team::RemoveThread(thread_id threadID)
{
Thread* thread = ThreadByID(threadID);
if (thread == NULL)
return false;
RemoveThread(thread);
delete thread;
return true;
}
Thread*
Team::ThreadByID(thread_id threadID) const
{
for (ThreadList::ConstIterator it = fThreads.GetIterator();
Thread* thread = it.Next();) {
if (thread->ID() == threadID)
return thread;
}
return NULL;
}
void
Team::AddImage(Image* image)
{
fImages.Add(image);
}
status_t
Team::AddImage(const image_info& imageInfo, Image** _image)
{
Image* image = new(std::nothrow) Image(imageInfo);
if (image == NULL)
return B_NO_MEMORY;
status_t error = image->Init();
if (error != B_OK) {
delete image;
return error;
}
AddImage(image);
if (_image != NULL)
*_image = image;
return B_OK;
}
void
Team::RemoveImage(Image* image)
{
fImages.Remove(image);
}
bool
Team::RemoveImage(image_id imageID)
{
Image* image = ImageByID(imageID);
if (image == NULL)
return false;
RemoveImage(image);
delete image;
return true;
}
Image*
Team::ImageByID(image_id imageID) const
{
for (ImageList::ConstIterator it = fImages.GetIterator();
Image* image = it.Next();) {
if (image->ID() == imageID)
return image;
}
return NULL;
}

47
src/apps/debugger/Team.h Normal file
View File

@ -0,0 +1,47 @@
/*
* Copyright 2009, Ingo Weinhold, ingo_weinhold@gmx.de.
* Distributed under the terms of the MIT License.
*/
#ifndef TEAM_H
#define TEAM_H
#include <Locker.h>
#include "Image.h"
#include "Thread.h"
class Team : public BLocker {
public:
Team(team_id teamID);
~Team();
status_t Init();
team_id ID() const { return fID; }
const char* Name() const { return fName.String(); }
void SetName(const BString& name);
void AddThread(Thread* thread);
status_t AddThread(const thread_info& threadInfo,
Thread** _thread = NULL);
void RemoveThread(Thread* thread);
bool RemoveThread(thread_id threadID);
Thread* ThreadByID(thread_id threadID) const;
void AddImage(Image* image);
status_t AddImage(const image_info& imageInfo,
Image** _image = NULL);
void RemoveImage(Image* image);
bool RemoveImage(image_id imageID);
Image* ImageByID(image_id imageID) const;
private:
team_id fID;
BString fName;
ThreadList fThreads;
ImageList fImages;
};
#endif // TEAM_H

View File

@ -0,0 +1,205 @@
/*
* Copyright 2009, Ingo Weinhold, ingo_weinhold@gmx.de.
* Distributed under the terms of the MIT License.
*/
#include "TeamDebugger.h"
#include <stdio.h>
#include <new>
#include <AutoLocker.h>
#include "Team.h"
TeamDebugger::TeamDebugger()
:
fLock("team debugger"),
fTeam(NULL),
fTeamID(-1),
fDebuggerPort(-1),
fNubPort(-1),
fDebugEventListener(-1),
fTerminating(false)
{
}
TeamDebugger::~TeamDebugger()
{
AutoLocker<BLocker> locker(fLock);
fTerminating = true;
if (fDebuggerPort >= 0)
delete_port(fDebuggerPort);
locker.Unlock();
if (fDebugEventListener >= 0)
wait_for_thread(fDebugEventListener, NULL);
delete fTeam;
}
status_t
TeamDebugger::Init(team_id teamID)
{
fTeamID = teamID;
status_t error = fLock.InitCheck();
if (error != B_OK)
return error;
// check whether the team exists at all
team_info teamInfo;
error = get_team_info(fTeamID, &teamInfo);
if (error != B_OK)
return error;
// create a team object
fTeam = new(std::nothrow) Team(fTeamID);
if (fTeam == NULL)
return B_NO_MEMORY;
error = fTeam->Init();
if (error != B_OK)
return error;
fTeam->SetName(teamInfo.args);
// TODO: Set a better name!
// create debugger port
char buffer[128];
snprintf(buffer, sizeof(buffer), "team %ld debugger", fTeamID);
fDebuggerPort = create_port(100, buffer);
if (fDebuggerPort < 0)
return fDebuggerPort;
// install as team debugger
fNubPort = install_team_debugger(fTeamID, fDebuggerPort);
if (fNubPort < 0)
return fNubPort;
// TODO: Set the debug event flags!
// get the initial state of the team
AutoLocker<Team> teamLocker(fTeam);
thread_info threadInfo;
int32 cookie = 0;
while (get_next_thread_info(fTeamID, &cookie, &threadInfo) == B_OK) {
error = fTeam->AddThread(threadInfo);
if (error != B_OK)
return error;
}
image_info imageInfo;
cookie = 0;
while (get_next_image_info(fTeamID, &cookie, &imageInfo) == B_OK) {
error = fTeam->AddImage(imageInfo);
if (error != B_OK)
return error;
}
// create the debug event listener
snprintf(buffer, sizeof(buffer), "team %ld debug listener", fTeamID);
fDebugEventListener = spawn_thread(_DebugEventListenerEntry, buffer,
B_NORMAL_PRIORITY, this);
if (fDebugEventListener < 0)
return fDebugEventListener;
resume_thread(fDebugEventListener);
return B_OK;
}
/*static*/ status_t
TeamDebugger::_DebugEventListenerEntry(void* data)
{
return ((TeamDebugger*)data)->_DebugEventListener();
}
status_t
TeamDebugger::_DebugEventListener()
{
while (!fTerminating) {
// read the next message
debug_debugger_message_data message;
int32 messageCode;
ssize_t size = read_port(fDebuggerPort, &messageCode, &message,
sizeof(message));
if (size < 0) {
if (size == B_INTERRUPTED)
continue;
// TODO: Error handling!
break;
}
if (message.origin.team != fTeamID) {
printf("TeamDebugger for team %ld: received message from team %ld!\n", fTeamID,
message.origin.team);
continue;
}
_HandleDebuggerMessage(messageCode, message);
if (messageCode == B_DEBUGGER_MESSAGE_TEAM_DELETED
|| messageCode == B_DEBUGGER_MESSAGE_TEAM_EXEC) {
// TODO:...
break;
}
}
return B_OK;
}
void
TeamDebugger::_HandleDebuggerMessage(int32 messageCode,
const debug_debugger_message_data& message)
{
switch (messageCode) {
case B_DEBUGGER_MESSAGE_THREAD_DEBUGGED:
break;
case B_DEBUGGER_MESSAGE_DEBUGGER_CALL:
break;
case B_DEBUGGER_MESSAGE_BREAKPOINT_HIT:
break;
case B_DEBUGGER_MESSAGE_WATCHPOINT_HIT:
break;
case B_DEBUGGER_MESSAGE_SINGLE_STEP:
break;
case B_DEBUGGER_MESSAGE_EXCEPTION_OCCURRED:
break;
case B_DEBUGGER_MESSAGE_TEAM_CREATED:
break;
case B_DEBUGGER_MESSAGE_TEAM_DELETED:
break;
case B_DEBUGGER_MESSAGE_TEAM_EXEC:
break;
case B_DEBUGGER_MESSAGE_THREAD_CREATED:
break;
case B_DEBUGGER_MESSAGE_THREAD_DELETED:
break;
case B_DEBUGGER_MESSAGE_IMAGE_CREATED:
break;
case B_DEBUGGER_MESSAGE_IMAGE_DELETED:
break;
case B_DEBUGGER_MESSAGE_PRE_SYSCALL:
case B_DEBUGGER_MESSAGE_POST_SYSCALL:
case B_DEBUGGER_MESSAGE_SIGNAL_RECEIVED:
case B_DEBUGGER_MESSAGE_PROFILER_UPDATE:
case B_DEBUGGER_MESSAGE_HANDED_OVER:
// not interested
break;
default:
printf("TeamDebugger for team %ld: unknown message from kernel: "
"%ld\n", fTeamID, messageCode);
break;
}
}

View File

@ -0,0 +1,40 @@
/*
* Copyright 2009, Ingo Weinhold, ingo_weinhold@gmx.de.
* Distributed under the terms of the MIT License.
*/
#ifndef TEAM_DEBUGGER_H
#define TEAM_DEBUGGER_H
#include <debugger.h>
#include <Locker.h>
class Team;
class TeamDebugger {
public:
TeamDebugger();
~TeamDebugger();
status_t Init(team_id teamID);
private:
static status_t _DebugEventListenerEntry(void* data);
status_t _DebugEventListener();
void _HandleDebuggerMessage(int32 messageCode,
const debug_debugger_message_data& message);
private:
BLocker fLock;
Team* fTeam;
team_id fTeamID;
port_id fDebuggerPort;
port_id fNubPort;
thread_id fDebugEventListener;
volatile bool fTerminating;
};
#endif // TEAM_DEBUGGER_H

View File

@ -0,0 +1,32 @@
/*
* Copyright 2009, Ingo Weinhold, ingo_weinhold@gmx.de.
* Distributed under the terms of the MIT License.
*/
#include "Thread.h"
Thread::Thread(thread_id threadID)
:
fID(threadID)
{
}
Thread::~Thread()
{
}
status_t
Thread::Init()
{
return B_OK;
}
void
Thread::SetName(const BString& name)
{
fName = name;
}

View File

@ -0,0 +1,36 @@
/*
* Copyright 2009, Ingo Weinhold, ingo_weinhold@gmx.de.
* Distributed under the terms of the MIT License.
*/
#ifndef THREAD_H
#define THREAD_H
#include <OS.h>
#include <String.h>
#include <util/DoublyLinkedList.h>
class Thread : public DoublyLinkedListLinkImpl<Thread> {
public:
Thread(thread_id threadID);
~Thread();
status_t Init();
thread_id ID() const { return fID; }
const char* Name() const { return fName.String(); }
void SetName(const BString& name);
private:
thread_id fID;
BString fName;
};
typedef DoublyLinkedList<Thread> ThreadList;
#endif // THREAD_H

View File

@ -5,7 +5,7 @@
#include <stdio.h>
#include "DwarfManager.h"
//#include "DwarfManager.h"
int
@ -18,9 +18,10 @@ main(int argc, const char* const* argv)
const char* fileName = argv[1];
DwarfManager manager;
manager.LoadFile(fileName);
manager.FinishLoading();
// DwarfManager manager;
// manager.LoadFile(fileName);
// manager.FinishLoading();
(void)fileName;
return 0;
}