From d9b10dea3bc62910fc0123a9751a4fa1c8b98f69 Mon Sep 17 00:00:00 2001 From: Ingo Weinhold Date: Fri, 3 Jul 2009 14:23:19 +0000 Subject: [PATCH] * 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 --- src/apps/debugger/TeamDebugger.cpp | 24 +++++++-- src/apps/debugger/TeamDebugger.h | 3 +- src/apps/debugger/ThreadHandler.cpp | 20 ++++++++ src/apps/debugger/ThreadHandler.h | 3 ++ .../debugger_interface/DebuggerInterface.cpp | 50 +++++++++++++++---- .../debugger_interface/DebuggerInterface.h | 3 ++ src/apps/debugger/model/Image.h | 1 + src/apps/debugger/model/ImageInfo.cpp | 11 ++-- src/apps/debugger/model/ImageInfo.h | 6 ++- src/apps/debugger/model/SymbolInfo.cpp | 21 ++++++++ src/apps/debugger/model/SymbolInfo.h | 4 ++ src/apps/debugger/model/Thread.cpp | 7 +++ src/apps/debugger/model/Thread.h | 2 + 13 files changed, 136 insertions(+), 19 deletions(-) diff --git a/src/apps/debugger/TeamDebugger.cpp b/src/apps/debugger/TeamDebugger.cpp index ebc223de19..e0535a009b 100644 --- a/src/apps/debugger/TeamDebugger.cpp +++ b/src/apps/debugger/TeamDebugger.cpp @@ -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 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 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; } diff --git a/src/apps/debugger/TeamDebugger.h b/src/apps/debugger/TeamDebugger.h index 926302841f..4af98241ef 100644 --- a/src/apps/debugger/TeamDebugger.h +++ b/src/apps/debugger/TeamDebugger.h @@ -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,...); diff --git a/src/apps/debugger/ThreadHandler.cpp b/src/apps/debugger/ThreadHandler.cpp index 7093ae4ea8..cb8f28d4f4 100644 --- a/src/apps/debugger/ThreadHandler.cpp +++ b/src/apps/debugger/ThreadHandler.cpp @@ -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) { diff --git a/src/apps/debugger/ThreadHandler.h b/src/apps/debugger/ThreadHandler.h index a58b29b0a9..6b85f663e1 100644 --- a/src/apps/debugger/ThreadHandler.h +++ b/src/apps/debugger/ThreadHandler.h @@ -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( diff --git a/src/apps/debugger/debugger_interface/DebuggerInterface.cpp b/src/apps/debugger/debugger_interface/DebuggerInterface.cpp index 0714c3b640..12ac495e9c 100644 --- a/src/apps/debugger/debugger_interface/DebuggerInterface.cpp +++ b/src/apps/debugger/debugger_interface/DebuggerInterface.cpp @@ -423,8 +423,8 @@ DebuggerInterface::GetImageInfos(BObjectList& 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& 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: diff --git a/src/apps/debugger/debugger_interface/DebuggerInterface.h b/src/apps/debugger/debugger_interface/DebuggerInterface.h index 2e3038ba21..8a2beadf21 100644 --- a/src/apps/debugger/debugger_interface/DebuggerInterface.h +++ b/src/apps/debugger/debugger_interface/DebuggerInterface.h @@ -47,6 +47,9 @@ public: virtual status_t GetImageInfos(BObjectList& infos); virtual status_t GetSymbolInfos(team_id team, image_id image, BObjectList& 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); diff --git a/src/apps/debugger/model/Image.h b/src/apps/debugger/model/Image.h index 10e22934e6..41abe18ce5 100644 --- a/src/apps/debugger/model/Image.h +++ b/src/apps/debugger/model/Image.h @@ -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; diff --git a/src/apps/debugger/model/ImageInfo.cpp b/src/apps/debugger/model/ImageInfo.cpp index 72ee170500..fb056ca615 100644 --- a/src/apps/debugger/model/ImageInfo.cpp +++ b/src/apps/debugger/model/ImageInfo.cpp @@ -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; diff --git a/src/apps/debugger/model/ImageInfo.h b/src/apps/debugger/model/ImageInfo.h index 83fb53beab..a57a0b03b6 100644 --- a/src/apps/debugger/model/ImageInfo.h +++ b/src/apps/debugger/model/ImageInfo.h @@ -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; diff --git a/src/apps/debugger/model/SymbolInfo.cpp b/src/apps/debugger/model/SymbolInfo.cpp index 942ed66d09..990cef626d 100644 --- a/src/apps/debugger/model/SymbolInfo.cpp +++ b/src/apps/debugger/model/SymbolInfo.cpp @@ -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; +} diff --git a/src/apps/debugger/model/SymbolInfo.h b/src/apps/debugger/model/SymbolInfo.h index ecae1c36dd..883d2b5524 100644 --- a/src/apps/debugger/model/SymbolInfo.h +++ b/src/apps/debugger/model/SymbolInfo.h @@ -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; } diff --git a/src/apps/debugger/model/Thread.cpp b/src/apps/debugger/model/Thread.cpp index d456b10608..0f70e2a3d2 100644 --- a/src/apps/debugger/model/Thread.cpp +++ b/src/apps/debugger/model/Thread.cpp @@ -37,6 +37,13 @@ Thread::Init() } +bool +Thread::IsMainThread() const +{ + return fID == fTeam->ID(); +} + + void Thread::SetName(const BString& name) { diff --git a/src/apps/debugger/model/Thread.h b/src/apps/debugger/model/Thread.h index 7b5f8da105..f9a93f3981 100644 --- a/src/apps/debugger/model/Thread.h +++ b/src/apps/debugger/model/Thread.h @@ -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);