Debugger: Implement #10970.

- If a source file cannot be found, and the user clicks the item to locate it,
  Debugger now attempts to query all volumes for the corresponding filename.
  If any are found, they are presented in a menu, along with an option to
  locate the file manually as before (since the file may potentially live on
  an unindexed volume). If no matches are found via query, we fall through to
  the file panel directly as before.
This commit is contained in:
Rene Gollent
2014-06-24 17:39:04 -04:00
parent f7566626e5
commit 2661ce4605
2 changed files with 138 additions and 18 deletions
@@ -21,12 +21,16 @@
#include <MessageFilter.h>
#include <MessageRunner.h>
#include <Path.h>
#include <PopUpMenu.h>
#include <Query.h>
#include <StringView.h>
#include <TabView.h>
#include <ScrollView.h>
#include <SplitView.h>
#include <TextView.h>
#include <VolumeRoster.h>
#include <AutoDeleter.h>
#include <AutoLocker.h>
#include "Breakpoint.h"
@@ -378,24 +382,7 @@ TeamWindow::MessageReceived(BMessage* message)
}
case MSG_LOCATE_SOURCE_IF_NEEDED:
{
if (fActiveFunction != NULL
&& fActiveFunction->GetFunctionDebugInfo()
->SourceFile() != NULL && fActiveSourceCode != NULL
&& fActiveSourceCode->GetSourceFile() == NULL
&& fActiveFunction->GetFunction()->SourceCodeState()
!= FUNCTION_SOURCE_NOT_LOADED) {
try {
if (fFilePanel == NULL) {
fFilePanel = new BFilePanel(B_OPEN_PANEL,
new BMessenger(this));
}
fFilePanel->Show();
} catch (...) {
delete fFilePanel;
fFilePanel = NULL;
}
}
break;
_HandleLocateSourceRequest();
}
case MSG_THREAD_RUN:
case MSG_THREAD_STOP:
@@ -1582,6 +1569,135 @@ TeamWindow::_HandleResolveMissingSourceFile(entry_ref& locatedPath)
}
void
TeamWindow::_HandleLocateSourceRequest()
{
if (fActiveFunction == NULL)
return;
else if (fActiveFunction->GetFunctionDebugInfo()->SourceFile() == NULL)
return;
else if (fActiveSourceCode == NULL)
return;
else if (fActiveSourceCode->GetSourceFile() != NULL)
return;
else if (fActiveFunction->GetFunction()->SourceCodeState()
== FUNCTION_SOURCE_NOT_LOADED) {
return;
}
BStringList entries;
if (_RetrieveMatchingSourceEntries(entries) != B_OK)
return;
int32 count = entries.CountStrings();
if (count > 0) {
entries.Sort();
BPopUpMenu* menu = new(std::nothrow) BPopUpMenu("");
if (menu == NULL)
return;
BPrivate::ObjectDeleter<BPopUpMenu> menuDeleter(menu);
BMenuItem* item = NULL;
for (int32 i = 0; i < count; i++) {
item = new(std::nothrow) BMenuItem(entries.StringAt(i).String(),
NULL);
if (item == NULL || !menu->AddItem(item)) {
delete item;
return;
}
}
menu->AddSeparatorItem();
BMenuItem* manualItem = new(std::nothrow) BMenuItem(
"Locate manually" B_UTF8_ELLIPSIS, NULL);
if (manualItem == NULL || !menu->AddItem(manualItem)) {
delete manualItem;
return;
}
BPoint point;
fSourcePathView->GetMouse(&point, NULL, false);
fSourcePathView->ConvertToScreen(&point);
item = menu->Go(point, false, true);
if (item == NULL)
return;
else if (item != manualItem) {
// if the user picks to locate the entry manually,
// then fall through to the usual file panel logic
// as if we'd found no matches at all.
entry_ref ref;
if (get_ref_for_path(item->Label(), &ref) == B_OK) {
_HandleResolveMissingSourceFile(ref);
return;
}
}
}
try {
if (fFilePanel == NULL) {
fFilePanel = new BFilePanel(B_OPEN_PANEL,
new BMessenger(this));
}
fFilePanel->Show();
} catch (...) {
delete fFilePanel;
fFilePanel = NULL;
}
}
status_t
TeamWindow::_RetrieveMatchingSourceEntries(BStringList& _entries)
{
BString data;
fActiveFunction->GetFunctionDebugInfo()->SourceFile()->GetPath(data);
BPath path;
status_t error = path.SetTo(data);
if (error != B_OK)
return error;
_entries.MakeEmpty();
BQuery query;
BString predicate;
query.PushAttr("name");
query.PushString(path.Leaf());
query.PushOp(B_EQ);
error = query.GetPredicate(&predicate);
if (error != B_OK)
return error;
BVolumeRoster roster;
BVolume volume;
while (roster.GetNextVolume(&volume) == B_OK) {
if (!volume.KnowsQuery())
continue;
if (query.SetVolume(&volume) != B_OK)
continue;
error = query.SetPredicate(predicate.String());
if (error != B_OK)
continue;
if (query.Fetch() != B_OK)
continue;
entry_ref ref;
while (query.GetNextRef(&ref) == B_OK) {
path.SetTo(&ref);
_entries.Add(path.Path());
}
query.Clear();
}
return B_OK;
}
status_t
TeamWindow::_SaveInspectorSettings(const BMessage* settings)
{
@@ -28,6 +28,7 @@ class BFilePanel;
class BMenuBar;
class BMessageRunner;
class BSplitView;
class BStringList;
class BStringView;
class BTabView;
class ConsoleOutputView;
@@ -169,6 +170,9 @@ private:
Watchpoint* watchpoint);
void _HandleResolveMissingSourceFile(entry_ref&
locatedPath);
void _HandleLocateSourceRequest();
status_t _RetrieveMatchingSourceEntries(
BStringList& _entries);
status_t _SaveInspectorSettings(
const BMessage* settings);