From 5a13e7b045910ee62ae40256dff1d2c06a4bbf77 Mon Sep 17 00:00:00 2001 From: Rene Gollent Date: Wed, 3 Nov 2010 21:52:39 +0000 Subject: [PATCH] Add a means for the user to locate source files if they are not found at the location specified in the debug info. git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@39289 a95241bf-73f2-0310-859d-f6bbb57e9c96 --- src/apps/debugger/Jamfile | 2 +- src/apps/debugger/TeamDebugger.cpp | 10 ++ src/apps/debugger/TeamDebugger.h | 3 + src/apps/debugger/debug_info/Function.cpp | 30 +++++ src/apps/debugger/debug_info/Function.h | 6 +- .../debugger/user_interface/UserInterface.h | 3 + .../gui/team_window/TeamWindow.cpp | 105 +++++++++++++++++- .../gui/team_window/TeamWindow.h | 5 + 8 files changed, 161 insertions(+), 3 deletions(-) diff --git a/src/apps/debugger/Jamfile b/src/apps/debugger/Jamfile index 912c7023f1..0d245d92ae 100644 --- a/src/apps/debugger/Jamfile +++ b/src/apps/debugger/Jamfile @@ -245,7 +245,7 @@ Application Debugger : libshared.a $(TARGET_LIBSTDC++) - be libdebug.so + be tracker libdebug.so : Debugger.rdef ; diff --git a/src/apps/debugger/TeamDebugger.cpp b/src/apps/debugger/TeamDebugger.cpp index e4dc4b7924..b07f958a32 100644 --- a/src/apps/debugger/TeamDebugger.cpp +++ b/src/apps/debugger/TeamDebugger.cpp @@ -1,5 +1,6 @@ /* * Copyright 2009, Ingo Weinhold, ingo_weinhold@gmx.de. + * Copyright 2010, Rene Gollent, rene@gollent.com. * Distributed under the terms of the MIT License. */ @@ -524,6 +525,15 @@ TeamDebugger::MessageReceived(BMessage* message) } +void +TeamDebugger::SourceEntryLocateRequested(const char* sourcePath, + const char* locatedPath) +{ + AutoLocker locker(fFileManager); + fFileManager->SourceEntryLocated(sourcePath, locatedPath); +} + + void TeamDebugger::FunctionSourceCodeRequested(FunctionInstance* functionInstance) { diff --git a/src/apps/debugger/TeamDebugger.h b/src/apps/debugger/TeamDebugger.h index 57228c982e..ac4181d7d8 100644 --- a/src/apps/debugger/TeamDebugger.h +++ b/src/apps/debugger/TeamDebugger.h @@ -48,6 +48,9 @@ private: // UserInterfaceListener virtual void FunctionSourceCodeRequested( FunctionInstance* function); + virtual void SourceEntryLocateRequested( + const char* sourcePath, + const char* locatedPath); virtual void ImageDebugInfoRequested(Image* image); virtual void ValueNodeValueRequested(CpuState* cpuState, ValueNodeContainer* container, diff --git a/src/apps/debugger/debug_info/Function.cpp b/src/apps/debugger/debug_info/Function.cpp index 65e3fe3410..29967e8b45 100644 --- a/src/apps/debugger/debug_info/Function.cpp +++ b/src/apps/debugger/debug_info/Function.cpp @@ -1,5 +1,6 @@ /* * Copyright 2009, Ingo Weinhold, ingo_weinhold@gmx.de. + * Copyright 2010, Rene Gollent, rene@gollent.com. * Distributed under the terms of the MIT License. */ @@ -21,6 +22,10 @@ Function::Function() Function::~Function() { SetSourceCode(NULL, FUNCTION_SOURCE_NOT_LOADED); + if (FirstInstance() != NULL) { + FirstInstance()->SourceFile()->RemoveListener(this); + FirstInstance()->SourceFile()->ReleaseReference(); + } } @@ -70,7 +75,12 @@ Function::RemoveListener(Listener* listener) void Function::AddInstance(FunctionInstance* instance) { + bool firstInstance = fInstances.First() == NULL; fInstances.Add(instance); + if (firstInstance && SourceFile() != NULL) { + instance->SourceFile()->AcquireReference(); + instance->SourceFile()->AddListener(this); + } } @@ -78,6 +88,10 @@ void Function::RemoveInstance(FunctionInstance* instance) { fInstances.Remove(instance); + if (fInstances.First() == NULL && SourceFile() != NULL) { + instance->SourceFile()->RemoveListener(this); + instance->SourceFile()->ReleaseReference(); + } } @@ -94,6 +108,22 @@ Function::NotifySourceCodeChanged() } +void +Function::LocatableFileChanged(LocatableFile* file) +{ + BString locatedPath; + BString path; + file->GetPath(path); + if (file->GetLocatedPath(locatedPath) && locatedPath != path) { + SetSourceCode(NULL, FUNCTION_SOURCE_NOT_LOADED); + for (FunctionInstanceList::Iterator it = fInstances.GetIterator(); + FunctionInstance* instance = it.Next();) { + instance->SetSourceCode(NULL, FUNCTION_SOURCE_NOT_LOADED); + } + } +} + + // #pragma mark - Listener diff --git a/src/apps/debugger/debug_info/Function.h b/src/apps/debugger/debug_info/Function.h index bfaee71026..d901e0e93d 100644 --- a/src/apps/debugger/debug_info/Function.h +++ b/src/apps/debugger/debug_info/Function.h @@ -1,5 +1,6 @@ /* * Copyright 2009, Ingo Weinhold, ingo_weinhold@gmx.de. + * Copyright 2010, Rene Gollent, rene@gollent.com. * Distributed under the terms of the MIT License. */ #ifndef FUNCTION_H @@ -9,12 +10,13 @@ #include #include "FunctionInstance.h" +#include "LocatableFile.h" class FileSourceCode; -class Function : public Referenceable { +class Function : public Referenceable, private LocatableFile::Listener { public: class Listener; @@ -60,6 +62,8 @@ public: void NotifySourceCodeChanged(); + void LocatableFileChanged(LocatableFile* file); + private: typedef DoublyLinkedList ListenerList; diff --git a/src/apps/debugger/user_interface/UserInterface.h b/src/apps/debugger/user_interface/UserInterface.h index 6891a32e97..1df091a544 100644 --- a/src/apps/debugger/user_interface/UserInterface.h +++ b/src/apps/debugger/user_interface/UserInterface.h @@ -61,6 +61,9 @@ public: virtual void FunctionSourceCodeRequested( FunctionInstance* function) = 0; + virtual void SourceEntryLocateRequested( + const char* sourcePath, + const char* locatedPath) = 0; virtual void ImageDebugInfoRequested(Image* image) = 0; virtual void ValueNodeValueRequested(CpuState* cpuState, ValueNodeContainer* container, diff --git a/src/apps/debugger/user_interface/gui/team_window/TeamWindow.cpp b/src/apps/debugger/user_interface/gui/team_window/TeamWindow.cpp index 9001b40c3d..f5906b989c 100644 --- a/src/apps/debugger/user_interface/gui/team_window/TeamWindow.cpp +++ b/src/apps/debugger/user_interface/gui/team_window/TeamWindow.cpp @@ -1,5 +1,6 @@ /* * Copyright 2009, Ingo Weinhold, ingo_weinhold@gmx.de. + * Copyright 2010, Rene Gollent, rene@gollent.com. * Distributed under the terms of the MIT License. */ @@ -9,11 +10,15 @@ #include #include +#include #include #include #include #include #include +#include +#include +#include #include #include #include @@ -27,6 +32,7 @@ #include "FileSourceCode.h" #include "Image.h" #include "ImageDebugInfo.h" +#include "LocatableFile.h" #include "MessageCodes.h" #include "RegistersView.h" #include "StackTrace.h" @@ -43,6 +49,32 @@ enum { }; +enum { + MSG_LOCATE_SOURCE_IF_NEEDED = 'lsin' +}; + + +class PathViewMessageFilter : public BMessageFilter { +public: + PathViewMessageFilter(BMessenger teamWindow) + : + BMessageFilter(B_MOUSE_UP), + fTeamWindowMessenger(teamWindow) + { + } + + virtual filter_result Filter(BMessage*, BHandler**) + { + fTeamWindowMessenger.SendMessage(MSG_LOCATE_SOURCE_IF_NEEDED); + + return B_DISPATCH_MESSAGE; + } + +private: + BMessenger fTeamWindowMessenger; +}; + + // #pragma mark - TeamWindow @@ -171,6 +203,30 @@ void TeamWindow::MessageReceived(BMessage* message) { switch (message->what) { + case B_REFS_RECEIVED: + { + entry_ref locatedPath; + message->FindRef("refs", &locatedPath); + _HandleResolveMissingSourceFile(locatedPath); + break; + } + case MSG_LOCATE_SOURCE_IF_NEEDED: + { + if (fActiveFunction != NULL + && fActiveFunction->GetFunctionDebugInfo() + ->SourceFile() != NULL && fActiveSourceCode != NULL + && fActiveSourceCode->GetSourceFile() == NULL) { + BFilePanel* panel = NULL; + try { + panel = new BFilePanel(B_OPEN_PANEL, + new BMessenger(this)); + panel->Show(); + } catch (...) { + delete panel; + } + } + break; + } case MSG_THREAD_RUN: case MSG_THREAD_STOP: case MSG_THREAD_STEP_OVER: @@ -405,6 +461,9 @@ TeamWindow::_Init() .Add(fStepOutButton = new BButton("Step Out")) .AddGlue() .End() + .Add(fSourcePathView = new BStringView( + "source path", + "Source path unavailable."), 4.0f) .AddSplit(B_HORIZONTAL, 3.0f) .Add(sourceScrollView = new BScrollView("source scroll", NULL, 0, true, true), 3.0f) @@ -457,6 +516,12 @@ TeamWindow::_Init() fStepIntoButton->SetTarget(this); fStepOutButton->SetTarget(this); + fSourcePathView->SetExplicitMaxSize(BSize(B_SIZE_UNLIMITED, B_SIZE_UNSET)); + BMessageFilter* filter = new(std::nothrow) PathViewMessageFilter( + BMessenger(this)); + if (filter != NULL) + fSourcePathView->AddFilter(filter); + // add menus and menu items BMenu* menu = new BMenu("File"); fMenuBar->AddItem(menu); @@ -908,8 +973,27 @@ TeamWindow::_HandleSourceCodeChanged() AutoLocker< ::Team> locker(fTeam); SourceCode* sourceCode = fActiveFunction->GetFunction()->GetSourceCode(); - if (sourceCode == NULL) + if (sourceCode == NULL) { sourceCode = fActiveFunction->GetSourceCode(); + + BString sourceText; + LocatableFile* sourceFile = fActiveFunction->GetFunctionDebugInfo() + ->SourceFile(); + if (sourceFile != NULL && !sourceFile->GetLocatedPath(sourceText)) + sourceFile->GetPath(sourceText); + + if (sourceCode != NULL && sourceCode->GetSourceFile() == NULL + && sourceFile != NULL) { + sourceText.Prepend("Click to locate source file '"); + sourceText += "'"; + fSourcePathView->SetText(sourceText.String()); + } else if (sourceFile != NULL) { + sourceText.Prepend("File: "); + fSourcePathView->SetText(sourceText.String()); + } else + fSourcePathView->SetText("Source file unavailable."); + } + Reference sourceCodeReference(sourceCode); locker.Unlock(); @@ -924,3 +1008,22 @@ TeamWindow::_HandleUserBreakpointChanged(UserBreakpoint* breakpoint) fSourceView->UserBreakpointChanged(breakpoint); fBreakpointsView->UserBreakpointChanged(breakpoint); } + + +void +TeamWindow::_HandleResolveMissingSourceFile(entry_ref& locatedPath) +{ + if (fActiveFunction != NULL) { + LocatableFile* sourceFile = fActiveFunction->GetFunctionDebugInfo() + ->SourceFile(); + if (sourceFile != NULL) { + BString sourcePath; + BString targetPath; + sourceFile->GetPath(sourcePath); + BPath path(&locatedPath); + targetPath = path.Path(); + fListener->SourceEntryLocateRequested(sourcePath, targetPath); + fListener->FunctionSourceCodeRequested(fActiveFunction); + } + } +} diff --git a/src/apps/debugger/user_interface/gui/team_window/TeamWindow.h b/src/apps/debugger/user_interface/gui/team_window/TeamWindow.h index 65c9af7f5f..64796f54a4 100644 --- a/src/apps/debugger/user_interface/gui/team_window/TeamWindow.h +++ b/src/apps/debugger/user_interface/gui/team_window/TeamWindow.h @@ -1,5 +1,6 @@ /* * Copyright 2009, Ingo Weinhold, ingo_weinhold@gmx.de. + * Copyright 2010, Rene Gollent, rene@gollent.com. * Distributed under the terms of the MIT License. */ #ifndef TEAM_WINDOW_H @@ -23,6 +24,7 @@ class BButton; class BMenuBar; +class BStringView; class BTabView; class Image; class RegistersView; @@ -129,6 +131,8 @@ private: void _HandleSourceCodeChanged(); void _HandleUserBreakpointChanged( UserBreakpoint* breakpoint); + void _HandleResolveMissingSourceFile(entry_ref& + locatedPath); private: ::Team* fTeam; @@ -156,6 +160,7 @@ private: BButton* fStepIntoButton; BButton* fStepOutButton; BMenuBar* fMenuBar; + BStringView* fSourcePathView; };