* Extended ImageInfo and Image so they know the image type.
* Added DebuggerInterface::GetSymbolInfo(). * Implementing stopping the thread in main() when the debugger started the debugged program. git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@31393 a95241bf-73f2-0310-859d-f6bbb57e9c96
This commit is contained in:
parent
9774f385b5
commit
d9b10dea3b
@ -24,6 +24,7 @@
|
||||
#include "Jobs.h"
|
||||
#include "LocatableFile.h"
|
||||
#include "MessageCodes.h"
|
||||
#include "SymbolInfo.h"
|
||||
#include "Statement.h"
|
||||
#include "TeamDebugInfo.h"
|
||||
#include "TeamDebugModel.h"
|
||||
@ -288,6 +289,7 @@ TeamDebugger::Init(team_id teamID, thread_id threadID, bool stopInMain)
|
||||
// get the initial state of the team
|
||||
AutoLocker< ::Team> teamLocker(fTeam);
|
||||
|
||||
ThreadHandler* mainThreadHandler = NULL;
|
||||
{
|
||||
BObjectList<ThreadInfo> threadInfos(20, true);
|
||||
status_t error = fDebuggerInterface->GetThreadInfos(threadInfos);
|
||||
@ -305,17 +307,24 @@ TeamDebugger::Init(team_id teamID, thread_id threadID, bool stopInMain)
|
||||
|
||||
fThreadHandlers.Insert(handler);
|
||||
|
||||
if (thread->IsMainThread())
|
||||
mainThreadHandler = handler;
|
||||
|
||||
handler->Init();
|
||||
}
|
||||
}
|
||||
|
||||
Image* appImage = NULL;
|
||||
{
|
||||
BObjectList<ImageInfo> imageInfos(20, true);
|
||||
status_t error = fDebuggerInterface->GetImageInfos(imageInfos);
|
||||
for (int32 i = 0; ImageInfo* info = imageInfos.ItemAt(i); i++) {
|
||||
error = _AddImage(*info);
|
||||
Image* image;
|
||||
error = _AddImage(*info, &image);
|
||||
if (error != B_OK)
|
||||
return error;
|
||||
if (image->Type() == B_APP_IMAGE)
|
||||
appImage = image;
|
||||
}
|
||||
}
|
||||
|
||||
@ -348,7 +357,13 @@ TeamDebugger::Init(team_id teamID, thread_id threadID, bool stopInMain)
|
||||
// if requested, stop the given thread
|
||||
if (threadID >= 0) {
|
||||
if (stopInMain) {
|
||||
// TODO: Set a temporary breakpoint in main and run the thread.
|
||||
SymbolInfo symbolInfo;
|
||||
if (appImage != NULL && mainThreadHandler != NULL
|
||||
&& fDebuggerInterface->GetSymbolInfo(
|
||||
fTeam->ID(), appImage->ID(), "main", B_SYMBOL_TYPE_TEXT,
|
||||
symbolInfo) == B_OK) {
|
||||
mainThreadHandler->SetBreakpointAndRun(symbolInfo.Address());
|
||||
}
|
||||
} else {
|
||||
debug_thread(threadID);
|
||||
// TODO: Superfluous, if the thread is already stopped.
|
||||
@ -852,7 +867,7 @@ TeamDebugger::_GetThreadHandler(thread_id threadID)
|
||||
|
||||
|
||||
status_t
|
||||
TeamDebugger::_AddImage(const ImageInfo& imageInfo)
|
||||
TeamDebugger::_AddImage(const ImageInfo& imageInfo, Image** _image)
|
||||
{
|
||||
LocatableFile* file = NULL;
|
||||
if (strchr(imageInfo.Name(), '/') != NULL)
|
||||
@ -868,6 +883,9 @@ TeamDebugger::_AddImage(const ImageInfo& imageInfo)
|
||||
if (imageHandler != NULL)
|
||||
fImageHandlers->Insert(imageHandler);
|
||||
|
||||
if (_image != NULL)
|
||||
*_image = image;
|
||||
|
||||
return B_OK;
|
||||
}
|
||||
|
||||
|
@ -94,7 +94,8 @@ private:
|
||||
|
||||
ThreadHandler* _GetThreadHandler(thread_id threadID);
|
||||
|
||||
status_t _AddImage(const ImageInfo& imageInfo);
|
||||
status_t _AddImage(const ImageInfo& imageInfo,
|
||||
Image** _image = NULL);
|
||||
|
||||
void _NotifyUser(const char* title,
|
||||
const char* text,...);
|
||||
|
@ -70,6 +70,26 @@ ThreadHandler::Init()
|
||||
}
|
||||
|
||||
|
||||
status_t
|
||||
ThreadHandler::SetBreakpointAndRun(target_addr_t address)
|
||||
{
|
||||
status_t error = _InstallTemporaryBreakpoint(address);
|
||||
if (error != B_OK)
|
||||
return error;
|
||||
|
||||
fPreviousInstructionPointer = 0;
|
||||
resume_thread(ThreadID());
|
||||
// TODO: This should probably better be a DebuggerInterface method,
|
||||
// but this method is used only when debugging a local team anyway.
|
||||
// Pretend "step out" mode, so that the temporary breakpoint hit will not
|
||||
// be ignored.
|
||||
fStepMode = STEP_OUT;
|
||||
fSingleStepping = false;
|
||||
|
||||
return B_OK;
|
||||
}
|
||||
|
||||
|
||||
bool
|
||||
ThreadHandler::HandleThreadDebugged(ThreadDebuggedEvent* event)
|
||||
{
|
||||
|
@ -37,6 +37,9 @@ public:
|
||||
thread_id ThreadID() const { return fThread->ID(); }
|
||||
Thread* GetThread() const { return fThread; }
|
||||
|
||||
status_t SetBreakpointAndRun(target_addr_t address);
|
||||
// team lock held
|
||||
|
||||
// All Handle*() methods are invoked in team debugger thread,
|
||||
// looper lock held.
|
||||
bool HandleThreadDebugged(
|
||||
|
@ -423,8 +423,8 @@ DebuggerInterface::GetImageInfos(BObjectList<ImageInfo>& infos)
|
||||
int32 cookie = 0;
|
||||
while (get_next_image_info(fTeamID, &cookie, &imageInfo) == B_OK) {
|
||||
ImageInfo* info = new(std::nothrow) ImageInfo(fTeamID, imageInfo.id,
|
||||
imageInfo.name, (addr_t)imageInfo.text, imageInfo.text_size,
|
||||
(addr_t)imageInfo.data, imageInfo.data_size);
|
||||
imageInfo.name, imageInfo.type, (addr_t)imageInfo.text,
|
||||
imageInfo.text_size, (addr_t)imageInfo.data, imageInfo.data_size);
|
||||
if (info == NULL || !infos.AddItem(info)) {
|
||||
delete info;
|
||||
return B_NO_MEMORY;
|
||||
@ -438,9 +438,9 @@ DebuggerInterface::GetImageInfos(BObjectList<ImageInfo>& infos)
|
||||
if ((addr_t)imageInfo.text >= USER_COMMPAGE_ADDR
|
||||
&& (addr_t)imageInfo.text < USER_COMMPAGE_ADDR + COMMPAGE_SIZE) {
|
||||
ImageInfo* info = new(std::nothrow) ImageInfo(B_SYSTEM_TEAM,
|
||||
imageInfo.id, imageInfo.name, (addr_t)imageInfo.text,
|
||||
imageInfo.text_size, (addr_t)imageInfo.data,
|
||||
imageInfo.data_size);
|
||||
imageInfo.id, imageInfo.name, imageInfo.type,
|
||||
(addr_t)imageInfo.text, imageInfo.text_size,
|
||||
(addr_t)imageInfo.data, imageInfo.data_size);
|
||||
if (info == NULL || !infos.AddItem(info)) {
|
||||
delete info;
|
||||
return B_NO_MEMORY;
|
||||
@ -498,6 +498,36 @@ DebuggerInterface::GetSymbolInfos(team_id team, image_id image,
|
||||
}
|
||||
|
||||
|
||||
status_t
|
||||
DebuggerInterface::GetSymbolInfo(team_id team, image_id image, const char* name,
|
||||
int32 symbolType, SymbolInfo& info)
|
||||
{
|
||||
// create a lookup context
|
||||
// TODO: It's a bit expensive to create a lookup context just for one
|
||||
// symbol!
|
||||
debug_symbol_lookup_context* lookupContext;
|
||||
status_t error = debug_create_symbol_lookup_context(team, &lookupContext);
|
||||
if (error != B_OK)
|
||||
return error;
|
||||
|
||||
// try to get the symbol
|
||||
void* foundAddress;
|
||||
size_t foundSize;
|
||||
int32 foundType;
|
||||
error = debug_get_symbol(lookupContext, image, name, symbolType,
|
||||
&foundAddress, &foundSize, &foundType);
|
||||
if (error == B_OK) {
|
||||
info.SetTo((target_addr_t)(addr_t)foundAddress, foundSize, foundType,
|
||||
name);
|
||||
}
|
||||
|
||||
// delete the lookup context
|
||||
debug_delete_symbol_lookup_context(lookupContext);
|
||||
|
||||
return error;
|
||||
}
|
||||
|
||||
|
||||
status_t
|
||||
DebuggerInterface::GetThreadInfo(thread_id thread, ThreadInfo& info)
|
||||
{
|
||||
@ -638,8 +668,9 @@ DebuggerInterface::_CreateDebugEvent(int32 messageCode,
|
||||
const image_info& info = message.image_created.info;
|
||||
event = new(std::nothrow) ImageCreatedEvent(message.origin.team,
|
||||
message.origin.thread,
|
||||
ImageInfo(fTeamID, info.id, info.name, (addr_t)info.text,
|
||||
info.text_size, (addr_t)info.data, info.data_size));
|
||||
ImageInfo(fTeamID, info.id, info.name, info.type,
|
||||
(addr_t)info.text, info.text_size, (addr_t)info.data,
|
||||
info.data_size));
|
||||
break;
|
||||
}
|
||||
case B_DEBUGGER_MESSAGE_IMAGE_DELETED:
|
||||
@ -647,8 +678,9 @@ DebuggerInterface::_CreateDebugEvent(int32 messageCode,
|
||||
const image_info& info = message.image_deleted.info;
|
||||
event = new(std::nothrow) ImageDeletedEvent(message.origin.team,
|
||||
message.origin.thread,
|
||||
ImageInfo(fTeamID, info.id, info.name, (addr_t)info.text,
|
||||
info.text_size, (addr_t)info.data, info.data_size));
|
||||
ImageInfo(fTeamID, info.id, info.name, info.type,
|
||||
(addr_t)info.text, info.text_size, (addr_t)info.data,
|
||||
info.data_size));
|
||||
break;
|
||||
}
|
||||
default:
|
||||
|
@ -47,6 +47,9 @@ public:
|
||||
virtual status_t GetImageInfos(BObjectList<ImageInfo>& infos);
|
||||
virtual status_t GetSymbolInfos(team_id team, image_id image,
|
||||
BObjectList<SymbolInfo>& infos);
|
||||
virtual status_t GetSymbolInfo(team_id team, image_id image,
|
||||
const char* name, int32 symbolType,
|
||||
SymbolInfo& info);
|
||||
|
||||
virtual status_t GetThreadInfo(thread_id thread,
|
||||
ThreadInfo& info);
|
||||
|
@ -39,6 +39,7 @@ public:
|
||||
image_id ID() const { return fInfo.ImageID(); }
|
||||
const char* Name() const { return fInfo.Name(); }
|
||||
const ImageInfo& Info() const { return fInfo; }
|
||||
image_type Type() const { return fInfo.Type(); }
|
||||
LocatableFile* ImageFile() const { return fImageFile; }
|
||||
|
||||
bool ContainsAddress(target_addr_t address) const;
|
||||
|
@ -23,6 +23,7 @@ ImageInfo::ImageInfo(const ImageInfo& other)
|
||||
fTeam(other.fTeam),
|
||||
fImage(other.fImage),
|
||||
fName(other.fName),
|
||||
fType(other.fType),
|
||||
fTextBase(other.fTextBase),
|
||||
fTextSize(other.fTextSize),
|
||||
fDataBase(other.fDataBase),
|
||||
@ -32,12 +33,13 @@ ImageInfo::ImageInfo(const ImageInfo& other)
|
||||
|
||||
|
||||
ImageInfo::ImageInfo(team_id team, image_id image, const BString& name,
|
||||
target_addr_t textBase, target_size_t textSize, target_addr_t dataBase,
|
||||
target_size_t dataSize)
|
||||
image_type type, target_addr_t textBase, target_size_t textSize,
|
||||
target_addr_t dataBase, target_size_t dataSize)
|
||||
:
|
||||
fTeam(team),
|
||||
fImage(image),
|
||||
fName(name),
|
||||
fType(type),
|
||||
fTextBase(textBase),
|
||||
fTextSize(textSize),
|
||||
fDataBase(dataBase),
|
||||
@ -48,12 +50,13 @@ ImageInfo::ImageInfo(team_id team, image_id image, const BString& name,
|
||||
|
||||
void
|
||||
ImageInfo::SetTo(team_id team, image_id image, const BString& name,
|
||||
target_addr_t textBase, target_size_t textSize, target_addr_t dataBase,
|
||||
target_size_t dataSize)
|
||||
image_type type, target_addr_t textBase, target_size_t textSize,
|
||||
target_addr_t dataBase, target_size_t dataSize)
|
||||
{
|
||||
fTeam = team;
|
||||
fImage = image;
|
||||
fName = name;
|
||||
fType = type;
|
||||
fTextBase = textBase;
|
||||
fTextSize = textSize;
|
||||
fDataBase = dataBase;
|
||||
|
@ -16,14 +16,14 @@ public:
|
||||
ImageInfo();
|
||||
ImageInfo(const ImageInfo& other);
|
||||
ImageInfo(team_id team, image_id image,
|
||||
const BString& name,
|
||||
const BString& name, image_type type,
|
||||
target_addr_t textBase,
|
||||
target_size_t textSize,
|
||||
target_addr_t dataBase,
|
||||
target_size_t dataSize);
|
||||
|
||||
void SetTo(team_id team, image_id image,
|
||||
const BString& name,
|
||||
const BString& name, image_type type,
|
||||
target_addr_t textBase,
|
||||
target_size_t textSize,
|
||||
target_addr_t dataBase,
|
||||
@ -32,6 +32,7 @@ public:
|
||||
team_id TeamID() const { return fTeam; }
|
||||
image_id ImageID() const { return fImage; }
|
||||
const char* Name() const { return fName.String(); }
|
||||
image_type Type() const { return fType; }
|
||||
|
||||
target_addr_t TextBase() const { return fTextBase; }
|
||||
target_size_t TextSize() const { return fTextSize; }
|
||||
@ -42,6 +43,7 @@ private:
|
||||
thread_id fTeam;
|
||||
image_id fImage;
|
||||
BString fName;
|
||||
image_type fType;
|
||||
target_addr_t fTextBase;
|
||||
target_size_t fTextSize;
|
||||
target_addr_t fDataBase;
|
||||
|
@ -6,6 +6,16 @@
|
||||
#include "SymbolInfo.h"
|
||||
|
||||
|
||||
SymbolInfo::SymbolInfo()
|
||||
:
|
||||
fAddress(0),
|
||||
fSize(0),
|
||||
fType(0),
|
||||
fName()
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
SymbolInfo::SymbolInfo(target_addr_t address, target_size_t size, uint32 type,
|
||||
const BString& name)
|
||||
:
|
||||
@ -20,3 +30,14 @@ SymbolInfo::SymbolInfo(target_addr_t address, target_size_t size, uint32 type,
|
||||
SymbolInfo::~SymbolInfo()
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
SymbolInfo::SetTo(target_addr_t address, target_size_t size, uint32 type,
|
||||
const BString& name)
|
||||
{
|
||||
fAddress = address;
|
||||
fSize = size;
|
||||
fType = type;
|
||||
fName = name;
|
||||
}
|
||||
|
@ -12,11 +12,15 @@
|
||||
|
||||
class SymbolInfo {
|
||||
public:
|
||||
SymbolInfo();
|
||||
SymbolInfo(target_addr_t address,
|
||||
target_size_t size, uint32 type,
|
||||
const BString& name);
|
||||
~SymbolInfo();
|
||||
|
||||
void SetTo(target_addr_t address, target_size_t size,
|
||||
uint32 type, const BString& name);
|
||||
|
||||
target_addr_t Address() const { return fAddress; }
|
||||
target_size_t Size() const { return fSize; }
|
||||
uint32 Type() const { return fType; }
|
||||
|
@ -37,6 +37,13 @@ Thread::Init()
|
||||
}
|
||||
|
||||
|
||||
bool
|
||||
Thread::IsMainThread() const
|
||||
{
|
||||
return fID == fTeam->ID();
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
Thread::SetName(const BString& name)
|
||||
{
|
||||
|
@ -34,6 +34,8 @@ public:
|
||||
Team* GetTeam() const { return fTeam; }
|
||||
thread_id ID() const { return fID; }
|
||||
|
||||
bool IsMainThread() const;
|
||||
|
||||
const char* Name() const { return fName.String(); }
|
||||
void SetName(const BString& name);
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user