2 * Copyright 2009-2012, Ingo Weinhold, ingo_weinhold@gmx.de.
3 * Copyright 2010-2017, Rene Gollent, rene@gollent.com.
4 * Distributed under the terms of the MIT License.
8 #include "TeamWindow.h"
14 #include <FilePanel.h>
15 #include <FindDirectory.h>
16 #include <LayoutBuilder.h>
21 #include <MessageFilter.h>
22 #include <MessageRunner.h>
24 #include <PopUpMenu.h>
26 #include <StringView.h>
28 #include <ScrollView.h>
29 #include <SplitView.h>
31 #include <VolumeRoster.h>
33 #include <AutoDeleter.h>
34 #include <AutoLocker.h>
36 #include "AppMessageCodes.h"
37 #include "Breakpoint.h"
38 #include "BreakpointEditWindow.h"
39 #include "ConsoleOutputView.h"
40 #include "CppLanguage.h"
42 #include "DisassembledCode.h"
43 #include "BreakpointEditWindow.h"
44 #include "ExpressionEvaluationWindow.h"
45 #include "ExpressionPromptWindow.h"
46 #include "FileSourceCode.h"
47 #include "GuiSettingsUtils.h"
48 #include "GuiTeamUiSettings.h"
50 #include "ImageDebugInfo.h"
51 #include "InspectorWindow.h"
52 #include "LocatableFile.h"
53 #include "MessageCodes.h"
54 #include "RegistersView.h"
55 #include "StackTrace.h"
56 #include "StackTraceView.h"
57 #include "TeamSettingsWindow.h"
59 #include "TypeComponentPath.h"
61 #include "UserInterface.h"
62 #include "ValueNodeManager.h"
65 #include "WatchPromptWindow.h"
69 MAIN_TAB_INDEX_THREADS
= 0,
70 MAIN_TAB_INDEX_IMAGES
= 1
75 MSG_CHOOSE_DEBUG_REPORT_LOCATION
= 'ccrl',
76 MSG_DEBUG_REPORT_SAVED
= 'drsa',
77 MSG_LOCATE_SOURCE_IF_NEEDED
= 'lsin',
78 MSG_SOURCE_ENTRY_QUERY_COMPLETE
= 'seqc',
79 MSG_CLEAR_STACK_TRACE
= 'clst',
80 MSG_HANDLE_LOAD_SETTINGS
= 'hlst',
81 MSG_UPDATE_STATUS_BAR
= 'upsb'
85 // #pragma mark - ThreadStackFrameSelectionKey
88 struct TeamWindow::ThreadStackFrameSelectionKey
{
91 ThreadStackFrameSelectionKey(::Thread
* thread
)
95 thread
->AcquireReference();
98 ~ThreadStackFrameSelectionKey()
100 thread
->ReleaseReference();
103 uint32
HashValue() const
105 return (uint32
)thread
->ID();
108 bool operator==(const ThreadStackFrameSelectionKey
& other
) const
110 return thread
== other
.thread
;
115 // #pragma mark - ThreadStackFrameSelectionEntry
118 struct TeamWindow::ThreadStackFrameSelectionEntry
119 : ThreadStackFrameSelectionKey
{
120 ThreadStackFrameSelectionEntry
* next
;
121 StackFrame
* selectedFrame
;
123 ThreadStackFrameSelectionEntry(::Thread
* thread
, StackFrame
* frame
)
125 ThreadStackFrameSelectionKey(thread
),
130 inline StackFrame
* SelectedFrame() const
132 return selectedFrame
;
135 void SetSelectedFrame(StackFrame
* frame
)
137 selectedFrame
= frame
;
142 // #pragma mark - ThreadStackFrameSelectionEntryHashDefinition
145 struct TeamWindow::ThreadStackFrameSelectionEntryHashDefinition
{
146 typedef ThreadStackFrameSelectionKey KeyType
;
147 typedef ThreadStackFrameSelectionEntry ValueType
;
149 size_t HashKey(const ThreadStackFrameSelectionKey
& key
) const
151 return key
.HashValue();
154 size_t Hash(const ThreadStackFrameSelectionKey
* value
) const
156 return value
->HashValue();
159 bool Compare(const ThreadStackFrameSelectionKey
& key
,
160 const ThreadStackFrameSelectionKey
* value
) const
162 return key
== *value
;
165 ThreadStackFrameSelectionEntry
*& GetLink(
166 ThreadStackFrameSelectionEntry
* value
) const
173 // #pragma mark - PathViewMessageFilter
176 class PathViewMessageFilter
: public BMessageFilter
{
178 PathViewMessageFilter(BMessenger teamWindow
)
180 BMessageFilter(B_MOUSE_UP
),
181 fTeamWindowMessenger(teamWindow
)
185 virtual filter_result
Filter(BMessage
*, BHandler
**)
187 fTeamWindowMessenger
.SendMessage(MSG_LOCATE_SOURCE_IF_NEEDED
);
189 return B_DISPATCH_MESSAGE
;
193 BMessenger fTeamWindowMessenger
;
197 // #pragma mark - TeamWindow
200 TeamWindow::TeamWindow(::Team
* team
, UserInterfaceListener
* listener
)
202 BWindow(BRect(100, 100, 899, 699), "Team", B_TITLED_WINDOW
,
203 B_ASYNCHRONOUS_CONTROLS
| B_AUTO_UPDATE_SIZE_LIMITS
),
207 fActiveStackTrace(NULL
),
208 fActiveStackFrame(NULL
),
209 fThreadSelectionInfoTable(NULL
),
210 fActiveBreakpoint(NULL
),
211 fActiveFunction(NULL
),
212 fActiveSourceCode(NULL
),
213 fActiveSourceObject(ACTIVE_SOURCE_NONE
),
215 fTraceUpdateRunner(NULL
),
217 fLocalsTabView(NULL
),
218 fThreadListView(NULL
),
219 fImageListView(NULL
),
220 fImageFunctionsView(NULL
),
221 fBreakpointsView(NULL
),
222 fVariablesView(NULL
),
223 fRegistersView(NULL
),
224 fStackTraceView(NULL
),
227 fStepOverButton(NULL
),
228 fStepIntoButton(NULL
),
229 fStepOutButton(NULL
),
231 fSourcePathView(NULL
),
232 fStatusBarView(NULL
),
233 fConsoleOutputView(NULL
),
234 fFunctionSplitView(NULL
),
235 fSourceSplitView(NULL
),
236 fImageSplitView(NULL
),
237 fThreadSplitView(NULL
),
238 fConsoleSplitView(NULL
),
239 fTeamSettingsWindow(NULL
),
240 fBreakpointEditWindow(NULL
),
241 fInspectorWindow(NULL
),
242 fExpressionEvalWindow(NULL
),
243 fExpressionPromptWindow(NULL
),
245 fActiveSourceWorker(-1)
249 fTeam
->AddListener(this);
253 TeamWindow::~TeamWindow()
255 if (fThreadListView
!= NULL
)
256 fThreadListView
->UnsetListener();
257 if (fStackTraceView
!= NULL
)
258 fStackTraceView
->UnsetListener();
259 if (fSourceView
!= NULL
)
260 fSourceView
->UnsetListener();
261 if (fInspectorWindow
!= NULL
) {
262 if (fInspectorWindow
->Lock())
263 fInspectorWindow
->Quit();
265 if (fExpressionEvalWindow
!= NULL
) {
266 if (fExpressionEvalWindow
->Lock())
267 fExpressionEvalWindow
->Quit();
269 if (fExpressionPromptWindow
!= NULL
) {
270 if (fExpressionPromptWindow
->Lock())
271 fExpressionPromptWindow
->Quit();
274 fTeam
->RemoveListener(this);
276 _SetActiveSourceCode(NULL
);
277 _SetActiveFunction(NULL
);
278 _SetActiveBreakpoint(NULL
);
279 _SetActiveStackFrame(NULL
);
280 _SetActiveStackTrace(NULL
);
281 _SetActiveImage(NULL
);
282 _SetActiveThread(NULL
);
286 ThreadStackFrameSelectionEntry
* entry
287 = fThreadSelectionInfoTable
->Clear(true);
289 while (entry
!= NULL
) {
290 ThreadStackFrameSelectionEntry
* next
= entry
->next
;
295 delete fThreadSelectionInfoTable
;
297 if (fActiveSourceWorker
> 0)
298 wait_for_thread(fActiveSourceWorker
, NULL
);
302 /*static*/ TeamWindow
*
303 TeamWindow::Create(::Team
* team
, UserInterfaceListener
* listener
)
305 TeamWindow
* self
= new TeamWindow(team
, listener
);
319 TeamWindow::DispatchMessage(BMessage
* message
, BHandler
* handler
)
321 // Handle function key shortcuts for stepping
322 switch (message
->what
) {
324 if (fActiveThread
!= NULL
&& fTraceUpdateRunner
== NULL
) {
327 if (message
->FindInt32("key", &key
) == B_OK
328 && message
->FindInt32("modifiers", (int32
*)&modifiers
)
332 fListener
->ThreadActionRequested(
333 fActiveThread
->ID(), MSG_THREAD_RUN
);
336 fListener
->ThreadActionRequested(
337 fActiveThread
->ID(), MSG_THREAD_STEP_OVER
);
340 if ((modifiers
& B_SHIFT_KEY
) != 0) {
341 fListener
->ThreadActionRequested(
342 fActiveThread
->ID(), MSG_THREAD_STEP_OUT
);
344 fListener
->ThreadActionRequested(
345 fActiveThread
->ID(), MSG_THREAD_STEP_INTO
);
357 BView
* focusView
= CurrentFocus();
358 if (focusView
!= NULL
) {
359 focusView
->MessageReceived(message
);
364 BWindow::DispatchMessage(message
, handler
);
369 TeamWindow::MessageReceived(BMessage
* message
)
371 switch (message
->what
) {
372 case MSG_TEAM_RESTART_REQUESTED
:
374 fListener
->TeamRestartRequested();
377 case MSG_CHOOSE_DEBUG_REPORT_LOCATION
:
380 char filename
[B_FILE_NAME_LENGTH
];
381 UiUtils::ReportNameForTeam(fTeam
, filename
, sizeof(filename
));
382 BMessenger
msgr(this);
383 fFilePanel
= new BFilePanel(B_SAVE_PANEL
, &msgr
,
384 NULL
, 0, false, new BMessage(MSG_GENERATE_DEBUG_REPORT
));
385 fFilePanel
->SetSaveText(filename
);
393 case MSG_GENERATE_DEBUG_REPORT
:
400 if (message
->FindRef("directory", &ref
) == B_OK
401 && message
->HasString("name")) {
403 path
.Append(message
->FindString("name"));
404 if (get_ref_for_path(path
.Path(), &ref
) == B_OK
)
405 fListener
->DebugReportRequested(&ref
);
409 case MSG_DEBUG_REPORT_SAVED
:
411 status_t finalStatus
= message
->GetInt32("status", B_OK
);
413 if (finalStatus
== B_OK
) {
414 data
.SetToFormat("Debug report successfully saved to '%s'",
415 message
->FindString("path"));
417 data
.SetToFormat("Failed to save debug report: '%s'",
418 strerror(finalStatus
));
421 BAlert
*alert
= new(std::nothrow
) BAlert("Report saved",
422 data
.String(), "Close");
426 alert
->SetFlags(alert
->Flags() | B_CLOSE_ON_ESCAPE
);
430 case MSG_SHOW_INSPECTOR_WINDOW
:
432 if (fInspectorWindow
) {
433 AutoLocker
<BWindow
> lock(fInspectorWindow
);
435 fInspectorWindow
->Activate(true);
438 fInspectorWindow
= InspectorWindow::Create(fTeam
,
440 if (fInspectorWindow
!= NULL
) {
441 fInspectorWindow
->LoadSettings(fUiSettings
);
442 fInspectorWindow
->Show();
449 target_addr_t address
;
450 if (message
->FindUInt64("address", &address
) == B_OK
) {
451 BMessage
addressMessage(MSG_INSPECT_ADDRESS
);
452 addressMessage
.AddUInt64("address", address
);
453 fInspectorWindow
->PostMessage(&addressMessage
);
457 case MSG_INSPECTOR_WINDOW_CLOSED
:
459 _SaveInspectorSettings(CurrentMessage());
460 fInspectorWindow
= NULL
;
464 case MSG_SHOW_EXPRESSION_WINDOW
:
466 if (fExpressionEvalWindow
!= NULL
) {
467 AutoLocker
<BWindow
> lock(fExpressionEvalWindow
);
469 fExpressionEvalWindow
->Activate(true);
472 fExpressionEvalWindow
= ExpressionEvaluationWindow::Create(
473 this, fTeam
, fListener
);
474 if (fExpressionEvalWindow
!= NULL
)
475 fExpressionEvalWindow
->Show();
482 case MSG_EXPRESSION_WINDOW_CLOSED
:
484 fExpressionEvalWindow
= NULL
;
487 case MSG_SHOW_EXPRESSION_PROMPT_WINDOW
:
489 if (fExpressionPromptWindow
!= NULL
) {
490 AutoLocker
<BWindow
> lock(fExpressionPromptWindow
);
492 fExpressionPromptWindow
->Activate(true);
495 fExpressionPromptWindow
= ExpressionPromptWindow::Create(
496 fVariablesView
, this);
497 if (fExpressionPromptWindow
!= NULL
)
498 fExpressionPromptWindow
->Show();
505 case MSG_EXPRESSION_PROMPT_WINDOW_CLOSED
:
507 fExpressionPromptWindow
= NULL
;
510 case MSG_SHOW_TEAM_SETTINGS_WINDOW
:
512 if (fTeamSettingsWindow
!= NULL
) {
513 AutoLocker
<BWindow
> lock(fTeamSettingsWindow
);
515 fTeamSettingsWindow
->Activate(true);
519 = TeamSettingsWindow::Create(
520 fTeam
, fListener
, this);
521 if (fTeamSettingsWindow
!= NULL
)
522 fTeamSettingsWindow
->Show();
529 case MSG_TEAM_SETTINGS_WINDOW_CLOSED
:
531 fTeamSettingsWindow
= NULL
;
534 case MSG_SHOW_BREAKPOINT_EDIT_WINDOW
:
536 if (fBreakpointEditWindow
!= NULL
) {
537 AutoLocker
<BWindow
> lock(fBreakpointEditWindow
);
539 fBreakpointEditWindow
->Activate(true);
541 UserBreakpoint
* breakpoint
;
542 if (message
->FindPointer("breakpoint",
543 reinterpret_cast<void**>(&breakpoint
)) != B_OK
) {
548 fBreakpointEditWindow
549 = BreakpointEditWindow::Create(
550 fTeam
, breakpoint
, fListener
, this);
551 if (fBreakpointEditWindow
!= NULL
)
552 fBreakpointEditWindow
->Show();
559 case MSG_BREAKPOINT_EDIT_WINDOW_CLOSED
:
561 fBreakpointEditWindow
= NULL
;
564 case MSG_SHOW_WATCH_VARIABLE_PROMPT
:
566 target_addr_t address
;
570 if (message
->FindUInt64("address", &address
) != B_OK
571 || message
->FindUInt32("type", &type
) != B_OK
572 || message
->FindInt32("length", &length
) != B_OK
) {
577 WatchPromptWindow
* window
= WatchPromptWindow::Create(
578 fTeam
->GetArchitecture(), address
, type
, length
,
586 case B_REFS_RECEIVED
:
588 entry_ref locatedPath
;
589 if (message
->FindRef("refs", &locatedPath
) != B_OK
)
592 _HandleResolveMissingSourceFile(locatedPath
);
597 case MSG_LOCATE_SOURCE_IF_NEEDED
:
599 _HandleLocateSourceRequest();
602 case MSG_SOURCE_ENTRY_QUERY_COMPLETE
:
604 BStringList
* entries
;
605 if (message
->FindPointer("entries", (void**)&entries
) == B_OK
) {
606 ObjectDeleter
<BStringList
> entryDeleter(entries
);
607 _HandleLocateSourceRequest(entries
);
609 fActiveSourceWorker
= -1;
613 case MSG_THREAD_STOP
:
614 case MSG_THREAD_STEP_OVER
:
615 case MSG_THREAD_STEP_INTO
:
616 case MSG_THREAD_STEP_OUT
:
617 if (fActiveThread
!= NULL
&& fTraceUpdateRunner
== NULL
) {
618 fListener
->ThreadActionRequested(fActiveThread
->ID(),
623 case MSG_CLEAR_STACK_TRACE
:
625 if (fTraceUpdateRunner
!= NULL
) {
626 _SetActiveStackTrace(NULL
);
631 case MSG_HANDLE_LOAD_SETTINGS
:
633 GuiTeamUiSettings
* settings
;
634 if (message
->FindPointer("settings",
635 reinterpret_cast<void**>(&settings
)) != B_OK
) {
639 _LoadSettings(settings
);
642 case MSG_UPDATE_STATUS_BAR
:
644 const char* messageText
;
645 if (message
->FindString("message", &messageText
) == B_OK
)
646 fStatusBarView
->SetText(messageText
);
649 case MSG_TEAM_RENAMED
:
654 case MSG_THREAD_STATE_CHANGED
:
657 if (message
->FindInt32("thread", &threadID
) != B_OK
)
660 _HandleThreadStateChanged(threadID
);
663 case MSG_THREAD_CPU_STATE_CHANGED
:
666 if (message
->FindInt32("thread", &threadID
) != B_OK
)
669 _HandleCpuStateChanged(threadID
);
673 case MSG_THREAD_STACK_TRACE_CHANGED
:
676 if (message
->FindInt32("thread", &threadID
) != B_OK
)
679 _HandleStackTraceChanged(threadID
);
683 case MSG_IMAGE_DEBUG_INFO_CHANGED
:
686 if (message
->FindInt32("image", &imageID
) != B_OK
)
689 _HandleImageDebugInfoChanged(imageID
);
693 case MSG_CONSOLE_OUTPUT_RECEIVED
:
697 if (message
->FindInt32("fd", &fd
) != B_OK
698 || message
->FindString("output", &output
) != B_OK
) {
701 fConsoleOutputView
->ConsoleOutputReceived(fd
, output
);
705 case MSG_USER_BREAKPOINT_CHANGED
:
707 UserBreakpoint
* breakpoint
;
708 if (message
->FindPointer("breakpoint", (void**)&breakpoint
) != B_OK
)
710 BReference
<UserBreakpoint
> breakpointReference(breakpoint
, true);
712 _HandleUserBreakpointChanged(breakpoint
);
716 case MSG_WATCHPOINT_CHANGED
:
718 Watchpoint
* watchpoint
;
719 if (message
->FindPointer("watchpoint", (void**)&watchpoint
) != B_OK
)
721 BReference
<Watchpoint
> watchpointReference(watchpoint
, true);
723 _HandleWatchpointChanged(watchpoint
);
728 case MSG_FUNCTION_SOURCE_CODE_CHANGED
:
730 _HandleSourceCodeChanged();
735 BWindow::MessageReceived(message
);
742 TeamWindow::QuitRequested()
744 fListener
->UserInterfaceQuitRequested();
751 TeamWindow::LoadSettings(const GuiTeamUiSettings
* settings
)
753 BMessage
message(MSG_HANDLE_LOAD_SETTINGS
);
754 message
.AddPointer("settings", settings
);
755 return PostMessage(&message
);
760 TeamWindow::SaveSettings(GuiTeamUiSettings
* settings
)
762 AutoLocker
<BWindow
> lock(this);
763 if (!lock
.IsLocked())
766 BMessage inspectorSettings
;
767 if (fUiSettings
.Settings("inspectorWindow", inspectorSettings
) == B_OK
) {
768 if (!settings
->AddSettings("inspectorWindow", inspectorSettings
))
773 BMessage teamWindowSettings
;
774 if (teamWindowSettings
.AddRect("frame", Frame()) != B_OK
)
777 if (GuiSettingsUtils::ArchiveSplitView(archive
, fSourceSplitView
) != B_OK
)
779 if (teamWindowSettings
.AddMessage("sourceSplit", &archive
) != B_OK
)
782 if (GuiSettingsUtils::ArchiveSplitView(archive
, fFunctionSplitView
) != B_OK
)
784 if (teamWindowSettings
.AddMessage("functionSplit", &archive
) != B_OK
)
787 if (GuiSettingsUtils::ArchiveSplitView(archive
, fImageSplitView
) != B_OK
)
789 if (teamWindowSettings
.AddMessage("imageSplit", &archive
))
792 if (GuiSettingsUtils::ArchiveSplitView(archive
, fThreadSplitView
) != B_OK
)
794 if (teamWindowSettings
.AddMessage("threadSplit", &archive
))
797 if (GuiSettingsUtils::ArchiveSplitView(archive
, fConsoleSplitView
) != B_OK
)
799 if (teamWindowSettings
.AddMessage("consoleSplit", &archive
))
802 if (fImageListView
->SaveSettings(archive
) != B_OK
)
804 if (teamWindowSettings
.AddMessage("imageListView", &archive
))
807 if (fImageFunctionsView
->SaveSettings(archive
) != B_OK
)
809 if (teamWindowSettings
.AddMessage("imageFunctionsView", &archive
))
812 if (fThreadListView
->SaveSettings(archive
) != B_OK
)
814 if (teamWindowSettings
.AddMessage("threadListView", &archive
))
817 if (fVariablesView
->SaveSettings(archive
) != B_OK
)
819 if (teamWindowSettings
.AddMessage("variablesView", &archive
))
822 if (fRegistersView
->SaveSettings(archive
) != B_OK
)
824 if (teamWindowSettings
.AddMessage("registersView", &archive
))
827 if (fStackTraceView
->SaveSettings(archive
) != B_OK
)
829 if (teamWindowSettings
.AddMessage("stackTraceView", &archive
))
832 if (fBreakpointsView
->SaveSettings(archive
) != B_OK
)
834 if (teamWindowSettings
.AddMessage("breakpointsView", &archive
))
837 if (fConsoleOutputView
->SaveSettings(archive
) != B_OK
)
839 if (teamWindowSettings
.AddMessage("consoleOutputView", &archive
))
842 if (!settings
->AddSettings("teamWindow", teamWindowSettings
))
850 TeamWindow::DisplayBackgroundStatus(const char* message
)
852 BMessage
updateMessage(MSG_UPDATE_STATUS_BAR
);
853 updateMessage
.AddString("message", message
);
854 PostMessage(&updateMessage
);
859 TeamWindow::ThreadSelectionChanged(::Thread
* thread
)
861 _SetActiveThread(thread
);
866 TeamWindow::ImageSelectionChanged(Image
* image
)
868 _SetActiveImage(image
);
873 TeamWindow::StackFrameSelectionChanged(StackFrame
* frame
)
875 _SetActiveStackFrame(frame
);
880 TeamWindow::FunctionSelectionChanged(FunctionInstance
* function
)
882 // If the function wasn't already active, it was just selected by the user.
883 if (function
!= NULL
&& function
!= fActiveFunction
)
884 fActiveSourceObject
= ACTIVE_SOURCE_FUNCTION
;
886 _SetActiveFunction(function
);
891 TeamWindow::BreakpointSelectionChanged(BreakpointProxyList
&proxies
)
893 if (proxies
.CountItems() == 0 && fActiveBreakpoint
!= NULL
) {
894 fActiveBreakpoint
->ReleaseReference();
895 fActiveBreakpoint
= NULL
;
896 } else if (proxies
.CountItems() == 1) {
897 BreakpointProxy
* proxy
= proxies
.ItemAt(0);
898 if (proxy
->Type() == BREAKPOINT_PROXY_TYPE_BREAKPOINT
)
899 _SetActiveBreakpoint(proxy
->GetBreakpoint());
901 // if more than one item is selected, do nothing.
906 TeamWindow::SetBreakpointEnabledRequested(UserBreakpoint
* breakpoint
,
909 fListener
->SetBreakpointEnabledRequested(breakpoint
, enabled
);
914 TeamWindow::ClearBreakpointRequested(UserBreakpoint
* breakpoint
)
916 fListener
->ClearBreakpointRequested(breakpoint
);
921 TeamWindow::SetBreakpointRequested(target_addr_t address
, bool enabled
)
923 fListener
->SetBreakpointRequested(address
, enabled
);
928 TeamWindow::ClearBreakpointRequested(target_addr_t address
)
930 fListener
->ClearBreakpointRequested(address
);
935 TeamWindow::ThreadActionRequested(::Thread
* thread
, uint32 action
,
936 target_addr_t address
)
938 if (fTraceUpdateRunner
== NULL
)
939 fListener
->ThreadActionRequested(thread
->ID(), action
, address
);
944 TeamWindow::FunctionSourceCodeRequested(FunctionInstance
* function
,
945 bool forceDisassembly
)
947 fListener
->FunctionSourceCodeRequested(function
, forceDisassembly
);
952 TeamWindow::SetWatchpointEnabledRequested(Watchpoint
* watchpoint
,
955 fListener
->SetWatchpointEnabledRequested(watchpoint
, enabled
);
960 TeamWindow::ClearWatchpointRequested(Watchpoint
* watchpoint
)
962 fListener
->ClearWatchpointRequested(watchpoint
);
967 TeamWindow::ValueNodeValueRequested(CpuState
* cpuState
,
968 ValueNodeContainer
* container
, ValueNode
* valueNode
)
970 fListener
->ValueNodeValueRequested(cpuState
, container
, valueNode
);
975 TeamWindow::ExpressionEvaluationRequested(ExpressionInfo
* info
,
976 StackFrame
* frame
, ::Thread
* thread
)
978 SourceLanguage
* language
;
979 if (_GetActiveSourceLanguage(language
) != B_OK
)
982 BReference
<SourceLanguage
> languageReference(language
, true);
983 fListener
->ExpressionEvaluationRequested(language
, info
, frame
, thread
);
988 TeamWindow::ValueNodeWriteRequested(ValueNode
* node
, CpuState
* state
,
991 fListener
->ValueNodeWriteRequested(node
, state
, newValue
);
996 TeamWindow::TeamRenamed(const Team::Event
& event
)
998 PostMessage(MSG_TEAM_RENAMED
);
1003 TeamWindow::ThreadStateChanged(const Team::ThreadEvent
& event
)
1005 BMessage
message(MSG_THREAD_STATE_CHANGED
);
1006 message
.AddInt32("thread", event
.GetThread()->ID());
1007 PostMessage(&message
);
1012 TeamWindow::ThreadCpuStateChanged(const Team::ThreadEvent
& event
)
1014 BMessage
message(MSG_THREAD_CPU_STATE_CHANGED
);
1015 message
.AddInt32("thread", event
.GetThread()->ID());
1016 PostMessage(&message
);
1021 TeamWindow::ThreadStackTraceChanged(const Team::ThreadEvent
& event
)
1023 BMessage
message(MSG_THREAD_STACK_TRACE_CHANGED
);
1024 message
.AddInt32("thread", event
.GetThread()->ID());
1025 PostMessage(&message
);
1030 TeamWindow::ImageDebugInfoChanged(const Team::ImageEvent
& event
)
1032 BMessage
message(MSG_IMAGE_DEBUG_INFO_CHANGED
);
1033 message
.AddInt32("image", event
.GetImage()->ID());
1034 PostMessage(&message
);
1039 TeamWindow::ConsoleOutputReceived(const Team::ConsoleOutputEvent
& event
)
1041 BMessage
message(MSG_CONSOLE_OUTPUT_RECEIVED
);
1042 message
.AddInt32("fd", event
.Descriptor());
1043 message
.AddString("output", event
.Output());
1044 PostMessage(&message
);
1049 TeamWindow::UserBreakpointChanged(const Team::UserBreakpointEvent
& event
)
1051 BMessage
message(MSG_USER_BREAKPOINT_CHANGED
);
1052 BReference
<UserBreakpoint
> breakpointReference(event
.GetBreakpoint());
1053 if (message
.AddPointer("breakpoint", event
.GetBreakpoint()) == B_OK
1054 && PostMessage(&message
) == B_OK
) {
1055 breakpointReference
.Detach();
1061 TeamWindow::WatchpointChanged(const Team::WatchpointEvent
& event
)
1063 BMessage
message(MSG_WATCHPOINT_CHANGED
);
1064 BReference
<Watchpoint
> watchpointReference(event
.GetWatchpoint());
1065 if (message
.AddPointer("watchpoint", event
.GetWatchpoint()) == B_OK
1066 && PostMessage(&message
) == B_OK
) {
1067 watchpointReference
.Detach();
1073 TeamWindow::DebugReportChanged(const Team::DebugReportEvent
& event
)
1075 BMessage
message(MSG_DEBUG_REPORT_SAVED
);
1076 message
.AddString("path", event
.GetReportPath());
1077 message
.AddInt32("status", event
.GetFinalStatus());
1078 PostMessage(&message
);
1083 TeamWindow::FunctionSourceCodeChanged(Function
* function
)
1085 TRACE_GUI("TeamWindow::FunctionSourceCodeChanged(%p): source: %p, "
1086 "state: %d\n", function
, function
->GetSourceCode(),
1087 function
->SourceCodeState());
1089 PostMessage(MSG_FUNCTION_SOURCE_CODE_CHANGED
);
1096 fThreadSelectionInfoTable
= new ThreadStackFrameSelectionInfoTable
;
1097 if (fThreadSelectionInfoTable
->Init() != B_OK
) {
1098 delete fThreadSelectionInfoTable
;
1099 fThreadSelectionInfoTable
= NULL
;
1100 throw std::bad_alloc();
1103 BScrollView
* sourceScrollView
;
1105 const float splitSpacing
= 3.0f
;
1107 BLayoutBuilder::Group
<>(this, B_VERTICAL
, 0.0f
)
1108 .Add(fMenuBar
= new BMenuBar("Menu"))
1109 .AddSplit(B_VERTICAL
, splitSpacing
)
1110 .GetSplitView(&fFunctionSplitView
)
1111 .SetInsets(B_USE_SMALL_INSETS
)
1112 .Add(fTabView
= new BTabView("tab view"), 0.4f
)
1113 .AddSplit(B_HORIZONTAL
, splitSpacing
)
1114 .GetSplitView(&fSourceSplitView
)
1115 .AddGroup(B_VERTICAL
, B_USE_SMALL_SPACING
)
1116 .AddGroup(B_HORIZONTAL
, B_USE_SMALL_SPACING
)
1117 .Add(fRunButton
= new BButton("Run"))
1118 .Add(fStepOverButton
= new BButton("Step over"))
1119 .Add(fStepIntoButton
= new BButton("Step into"))
1120 .Add(fStepOutButton
= new BButton("Step out"))
1123 .Add(fSourcePathView
= new BStringView(
1125 "Source path unavailable."), 4.0f
)
1126 .Add(sourceScrollView
= new BScrollView("source scroll",
1127 NULL
, 0, true, true), splitSpacing
)
1129 .Add(fLocalsTabView
= new BTabView("locals view"))
1131 .AddSplit(B_VERTICAL
, splitSpacing
)
1132 .GetSplitView(&fConsoleSplitView
)
1134 .Add(fConsoleOutputView
= ConsoleOutputView::Create())
1137 .Add(fStatusBarView
= new BStringView("status", "Ready."));
1139 fStatusBarView
->SetExplicitMinSize(BSize(50.0, B_SIZE_UNSET
));
1140 fStatusBarView
->SetExplicitMaxSize(BSize(B_SIZE_UNLIMITED
, B_SIZE_UNSET
));
1143 sourceScrollView
->SetTarget(fSourceView
= SourceView::Create(fTeam
, this));
1146 BSplitView
* threadGroup
= new BSplitView(B_HORIZONTAL
, splitSpacing
);
1147 threadGroup
->SetName("Threads");
1148 fTabView
->AddTab(threadGroup
);
1149 BLayoutBuilder::Split
<>(threadGroup
)
1150 .GetSplitView(&fThreadSplitView
)
1151 .Add(fThreadListView
= ThreadListView::Create(fTeam
, this))
1152 .Add(fStackTraceView
= StackTraceView::Create(this));
1155 BSplitView
* imagesGroup
= new BSplitView(B_HORIZONTAL
, splitSpacing
);
1156 imagesGroup
->SetName("Images");
1157 fTabView
->AddTab(imagesGroup
);
1158 BLayoutBuilder::Split
<>(imagesGroup
)
1159 .GetSplitView(&fImageSplitView
)
1160 .Add(fImageListView
= ImageListView::Create(fTeam
, this))
1161 .Add(fImageFunctionsView
= ImageFunctionsView::Create(this));
1163 // add breakpoints tab
1164 BGroupView
* breakpointsGroup
= new BGroupView(B_HORIZONTAL
,
1165 B_USE_SMALL_SPACING
);
1166 breakpointsGroup
->SetName("Breakpoints");
1167 fTabView
->AddTab(breakpointsGroup
);
1168 BLayoutBuilder::Group
<>(breakpointsGroup
)
1170 .Add(fBreakpointsView
= BreakpointsView::Create(fTeam
, this));
1172 ValueNodeManager
* manager
= new ValueNodeManager
;
1174 // add local variables tab
1175 BView
* tab
= fVariablesView
= VariablesView::Create(this, manager
);
1176 fLocalsTabView
->AddTab(tab
);
1178 // add registers tab
1179 tab
= fRegistersView
= RegistersView::Create(fTeam
->GetArchitecture());
1180 fLocalsTabView
->AddTab(tab
);
1182 fRunButton
->SetMessage(new BMessage(MSG_THREAD_RUN
));
1183 fStepOverButton
->SetMessage(new BMessage(MSG_THREAD_STEP_OVER
));
1184 fStepIntoButton
->SetMessage(new BMessage(MSG_THREAD_STEP_INTO
));
1185 fStepOutButton
->SetMessage(new BMessage(MSG_THREAD_STEP_OUT
));
1186 fRunButton
->SetTarget(this);
1187 fStepOverButton
->SetTarget(this);
1188 fStepIntoButton
->SetTarget(this);
1189 fStepOutButton
->SetTarget(this);
1191 fSourcePathView
->SetExplicitMinSize(BSize(100.0, B_SIZE_UNSET
));
1192 fSourcePathView
->SetExplicitMaxSize(BSize(B_SIZE_UNLIMITED
, B_SIZE_UNSET
));
1193 BMessageFilter
* filter
= new(std::nothrow
) PathViewMessageFilter(
1196 fSourcePathView
->AddFilter(filter
);
1198 // add menus and menu items
1199 BMenu
* menu
= new BMenu("Debugger");
1200 fMenuBar
->AddItem(menu
);
1201 BMenuItem
* item
= new BMenuItem("Start new team" B_UTF8_ELLIPSIS
,
1202 new BMessage(MSG_SHOW_START_TEAM_WINDOW
));
1203 menu
->AddItem(item
);
1204 item
->SetTarget(be_app
);
1205 item
= new BMenuItem("Show Teams window" B_UTF8_ELLIPSIS
,
1206 new BMessage(MSG_SHOW_TEAMS_WINDOW
));
1207 menu
->AddItem(item
);
1208 item
->SetTarget(be_app
);
1209 menu
= new BMenu("Team");
1210 fMenuBar
->AddItem(menu
);
1211 item
= new BMenuItem("Restart", new BMessage(
1212 MSG_TEAM_RESTART_REQUESTED
), 'R', B_SHIFT_KEY
);
1213 menu
->AddItem(item
);
1214 item
->SetTarget(this);
1215 item
= new BMenuItem("Close", new BMessage(B_QUIT_REQUESTED
),
1217 menu
->AddItem(item
);
1218 item
->SetTarget(this);
1219 menu
->AddSeparatorItem();
1220 item
= new BMenuItem("Settings" B_UTF8_ELLIPSIS
, new BMessage(
1221 MSG_SHOW_TEAM_SETTINGS_WINDOW
));
1222 menu
->AddItem(item
);
1223 item
->SetTarget(this);
1224 menu
= new BMenu("Edit");
1225 fMenuBar
->AddItem(menu
);
1226 item
= new BMenuItem("Copy", new BMessage(B_COPY
), 'C');
1227 menu
->AddItem(item
);
1228 item
->SetTarget(this);
1229 item
= new BMenuItem("Select all", new BMessage(B_SELECT_ALL
), 'A');
1230 menu
->AddItem(item
);
1231 item
->SetTarget(this);
1232 menu
= new BMenu("Tools");
1233 fMenuBar
->AddItem(menu
);
1234 item
= new BMenuItem("Save debug report",
1235 new BMessage(MSG_CHOOSE_DEBUG_REPORT_LOCATION
));
1236 menu
->AddItem(item
);
1237 item
->SetTarget(this);
1238 item
= new BMenuItem("Inspect memory",
1239 new BMessage(MSG_SHOW_INSPECTOR_WINDOW
), 'I');
1240 menu
->AddItem(item
);
1241 item
->SetTarget(this);
1242 item
= new BMenuItem("Evaluate expression",
1243 new BMessage(MSG_SHOW_EXPRESSION_WINDOW
), 'E');
1244 menu
->AddItem(item
);
1245 item
->SetTarget(this);
1247 AutoLocker
< ::Team
> locker(fTeam
);
1248 _UpdateRunButtons();
1253 TeamWindow::_LoadSettings(const GuiTeamUiSettings
* settings
)
1255 BMessage teamWindowSettings
;
1256 // no settings stored yet
1257 if (settings
->Settings("teamWindow", teamWindowSettings
) != B_OK
)
1261 if (teamWindowSettings
.FindRect("frame", &frame
) == B_OK
) {
1262 ResizeTo(frame
.Width(), frame
.Height());
1263 MoveTo(frame
.left
, frame
.top
);
1267 if (teamWindowSettings
.FindMessage("sourceSplit", &archive
) == B_OK
)
1268 GuiSettingsUtils::UnarchiveSplitView(archive
, fSourceSplitView
);
1270 if (teamWindowSettings
.FindMessage("functionSplit", &archive
) == B_OK
)
1271 GuiSettingsUtils::UnarchiveSplitView(archive
, fFunctionSplitView
);
1273 if (teamWindowSettings
.FindMessage("imageSplit", &archive
) == B_OK
)
1274 GuiSettingsUtils::UnarchiveSplitView(archive
, fImageSplitView
);
1276 if (teamWindowSettings
.FindMessage("threadSplit", &archive
) == B_OK
)
1277 GuiSettingsUtils::UnarchiveSplitView(archive
, fThreadSplitView
);
1279 if (teamWindowSettings
.FindMessage("consoleSplit", &archive
) == B_OK
)
1280 GuiSettingsUtils::UnarchiveSplitView(archive
, fConsoleSplitView
);
1282 if (teamWindowSettings
.FindMessage("imageListView", &archive
) == B_OK
)
1283 fImageListView
->LoadSettings(archive
);
1285 if (teamWindowSettings
.FindMessage("imageFunctionsView", &archive
) == B_OK
)
1286 fImageFunctionsView
->LoadSettings(archive
);
1288 if (teamWindowSettings
.FindMessage("threadListView", &archive
) == B_OK
)
1289 fThreadListView
->LoadSettings(archive
);
1291 if (teamWindowSettings
.FindMessage("variablesView", &archive
) == B_OK
)
1292 fVariablesView
->LoadSettings(archive
);
1294 if (teamWindowSettings
.FindMessage("registersView", &archive
) == B_OK
)
1295 fRegistersView
->LoadSettings(archive
);
1297 if (teamWindowSettings
.FindMessage("stackTraceView", &archive
) == B_OK
)
1298 fStackTraceView
->LoadSettings(archive
);
1300 if (teamWindowSettings
.FindMessage("breakpointsView", &archive
) == B_OK
)
1301 fBreakpointsView
->LoadSettings(archive
);
1303 if (teamWindowSettings
.FindMessage("consoleOutputView", &archive
) == B_OK
)
1304 fConsoleOutputView
->LoadSettings(archive
);
1306 fUiSettings
= *settings
;
1311 TeamWindow::_UpdateTitle()
1313 AutoLocker
< ::Team
> lock(fTeam
);
1314 BString name
= fTeam
->Name();
1315 if (fTeam
->ID() >= 0)
1316 name
<< " (" << fTeam
->ID() << ")";
1317 SetTitle(name
.String());
1322 TeamWindow::_SetActiveThread(::Thread
* thread
)
1324 if (thread
== fActiveThread
)
1327 if (fActiveThread
!= NULL
)
1328 fActiveThread
->ReleaseReference();
1330 fActiveThread
= thread
;
1332 if (fActiveThread
!= NULL
)
1333 fActiveThread
->AcquireReference();
1335 AutoLocker
< ::Team
> locker(fTeam
);
1336 _UpdateRunButtons();
1338 StackTrace
* stackTrace
= fActiveThread
!= NULL
1339 ? fActiveThread
->GetStackTrace() : NULL
;
1340 BReference
<StackTrace
> stackTraceReference(stackTrace
);
1341 // hold a reference until we've set it
1345 fThreadListView
->SetThread(fActiveThread
);
1347 _SetActiveStackTrace(stackTrace
);
1353 TeamWindow::_SetActiveImage(Image
* image
)
1355 if (image
== fActiveImage
)
1358 if (fActiveImage
!= NULL
)
1359 fActiveImage
->ReleaseReference();
1361 fActiveImage
= image
;
1363 AutoLocker
< ::Team
> locker(fTeam
);
1365 ImageDebugInfo
* imageDebugInfo
= NULL
;
1366 BReference
<ImageDebugInfo
> imageDebugInfoReference
;
1368 if (fActiveImage
!= NULL
) {
1369 fActiveImage
->AcquireReference();
1371 imageDebugInfo
= fActiveImage
->GetImageDebugInfo();
1372 imageDebugInfoReference
.SetTo(imageDebugInfo
);
1374 // If the debug info is not loaded yet, request it.
1375 if (fActiveImage
->ImageDebugInfoState() == IMAGE_DEBUG_INFO_NOT_LOADED
)
1376 fListener
->ImageDebugInfoRequested(fActiveImage
);
1381 fImageListView
->SetImage(fActiveImage
);
1382 fImageFunctionsView
->SetImageDebugInfo(imageDebugInfo
);
1387 TeamWindow::_SetActiveStackTrace(StackTrace
* stackTrace
)
1389 delete fTraceUpdateRunner
;
1390 fTraceUpdateRunner
= NULL
;
1392 if (stackTrace
== fActiveStackTrace
)
1395 if (fActiveStackTrace
!= NULL
)
1396 fActiveStackTrace
->ReleaseReference();
1398 fActiveStackTrace
= stackTrace
;
1400 if (fActiveStackTrace
!= NULL
)
1401 fActiveStackTrace
->AcquireReference();
1403 fStackTraceView
->SetStackTrace(fActiveStackTrace
);
1404 fSourceView
->SetStackTrace(fActiveStackTrace
, fActiveThread
);
1406 StackFrame
* frame
= NULL
;
1407 if (fActiveStackTrace
!= NULL
) {
1408 ThreadStackFrameSelectionEntry
* entry
1409 = fThreadSelectionInfoTable
->Lookup(fActiveThread
);
1411 frame
= entry
->SelectedFrame();
1413 frame
= fActiveStackTrace
->FrameAt(0);
1416 _SetActiveStackFrame(frame
);
1421 TeamWindow::_SetActiveStackFrame(StackFrame
* frame
)
1423 if (frame
== fActiveStackFrame
)
1426 if (fActiveStackFrame
!= NULL
) {
1427 AutoLocker
< ::Team
> locker(fTeam
);
1428 fActiveStackFrame
->RemoveListener(this);
1431 fActiveStackFrame
->ReleaseReference();
1434 fActiveStackFrame
= frame
;
1436 if (fActiveStackFrame
!= NULL
) {
1437 fActiveStackFrame
->AcquireReference();
1439 AutoLocker
< ::Team
> locker(fTeam
);
1440 fActiveStackFrame
->AddListener(this);
1443 fActiveSourceObject
= ACTIVE_SOURCE_STACK_FRAME
;
1445 ThreadStackFrameSelectionEntry
* entry
1446 = fThreadSelectionInfoTable
->Lookup(fActiveThread
);
1447 if (entry
== NULL
) {
1448 entry
= new(std::nothrow
) ThreadStackFrameSelectionEntry(
1449 fActiveThread
, fActiveStackFrame
);
1453 ObjectDeleter
<ThreadStackFrameSelectionEntry
> entryDeleter(entry
);
1454 if (fThreadSelectionInfoTable
->Insert(entry
) == B_OK
)
1455 entryDeleter
.Detach();
1457 entry
->SetSelectedFrame(fActiveStackFrame
);
1459 _SetActiveFunction(fActiveStackFrame
->Function(), false);
1464 fStackTraceView
->SetStackFrame(fActiveStackFrame
);
1465 if (fActiveStackFrame
!= NULL
)
1466 fVariablesView
->SetStackFrame(fActiveThread
, fActiveStackFrame
);
1468 fVariablesView
->SetStackFrame(NULL
, NULL
);
1469 fSourceView
->SetStackFrame(fActiveStackFrame
);
1474 TeamWindow::_SetActiveBreakpoint(UserBreakpoint
* breakpoint
)
1476 if (breakpoint
== fActiveBreakpoint
)
1479 if (fActiveBreakpoint
!= NULL
)
1480 fActiveBreakpoint
->ReleaseReference();
1482 fActiveBreakpoint
= breakpoint
;
1484 if (fActiveBreakpoint
!= NULL
) {
1485 fActiveBreakpoint
->AcquireReference();
1487 // get the breakpoint's function (more exactly: some function instance)
1488 AutoLocker
< ::Team
> locker(fTeam
);
1490 Function
* function
= fTeam
->FunctionByID(
1491 breakpoint
->Location().GetFunctionID());
1492 FunctionInstance
* functionInstance
= function
!= NULL
1493 ? function
->FirstInstance() : NULL
;
1494 BReference
<FunctionInstance
> functionInstanceReference(
1499 fActiveSourceObject
= ACTIVE_SOURCE_BREAKPOINT
;
1501 _SetActiveFunction(functionInstance
);
1503 // scroll to the breakpoint's source code line number (it is not done
1504 // automatically, if the active function remains the same)
1505 _ScrollToActiveFunction();
1511 TeamWindow::_SetActiveFunction(FunctionInstance
* functionInstance
,
1512 bool searchForFrame
)
1514 if (functionInstance
== fActiveFunction
)
1517 AutoLocker
< ::Team
> locker(fTeam
);
1519 if (fActiveFunction
!= NULL
) {
1520 fActiveFunction
->GetFunction()->RemoveListener(this);
1521 fActiveFunction
->ReleaseReference();
1524 // to avoid listener feedback problems, first unset the active function and
1525 // set the new image, if any
1528 fActiveFunction
= NULL
;
1530 if (functionInstance
!= NULL
)
1531 _SetActiveImage(fTeam
->ImageByAddress(functionInstance
->Address()));
1533 fActiveFunction
= functionInstance
;
1537 SourceCode
* sourceCode
= NULL
;
1538 BReference
<SourceCode
> sourceCodeReference
;
1540 if (fActiveFunction
!= NULL
) {
1541 fActiveFunction
->AcquireReference();
1542 fActiveFunction
->GetFunction()->AddListener(this);
1544 Function
* function
= fActiveFunction
->GetFunction();
1545 sourceCode
= function
->GetSourceCode();
1546 if (sourceCode
== NULL
)
1547 sourceCode
= fActiveFunction
->GetSourceCode();
1548 sourceCodeReference
.SetTo(sourceCode
);
1550 // If the source code is not loaded yet, request it.
1551 if (function
->SourceCodeState() == FUNCTION_SOURCE_NOT_LOADED
)
1552 fListener
->FunctionSourceCodeRequested(fActiveFunction
);
1557 _SetActiveSourceCode(sourceCode
);
1559 fImageFunctionsView
->SetFunction(fActiveFunction
);
1563 if (!searchForFrame
|| fActiveStackTrace
== NULL
)
1566 // look if our current stack trace has a frame matching the selected
1567 // function. If so, set it to match.
1568 StackFrame
* matchingFrame
= NULL
;
1569 BReference
<StackFrame
> frameRef
;
1571 for (int32 i
= 0; i
< fActiveStackTrace
->CountFrames(); i
++) {
1572 StackFrame
* frame
= fActiveStackTrace
->FrameAt(i
);
1573 if (frame
->Function() == fActiveFunction
) {
1574 matchingFrame
= frame
;
1575 frameRef
.SetTo(frame
);
1582 if (matchingFrame
!= NULL
)
1583 _SetActiveStackFrame(matchingFrame
);
1588 TeamWindow::_SetActiveSourceCode(SourceCode
* sourceCode
)
1590 if (sourceCode
== fActiveSourceCode
) {
1591 _ScrollToActiveFunction();
1595 if (fActiveSourceCode
!= NULL
)
1596 fActiveSourceCode
->ReleaseReference();
1598 fActiveSourceCode
= sourceCode
;
1600 if (fActiveSourceCode
!= NULL
)
1601 fActiveSourceCode
->AcquireReference();
1603 fSourceView
->SetSourceCode(fActiveSourceCode
);
1605 _UpdateSourcePathState();
1606 _ScrollToActiveFunction();
1610 TeamWindow::_UpdateCpuState()
1612 // get the CPU state
1613 CpuState
* cpuState
= NULL
;
1614 BReference
<CpuState
> cpuStateReference
;
1615 // hold a reference until the register view has one
1617 if (fActiveThread
!= NULL
) {
1618 // Get the CPU state from the active stack frame or the thread directly.
1619 if (fActiveStackFrame
== NULL
) {
1620 AutoLocker
< ::Team
> locker(fTeam
);
1621 cpuState
= fActiveThread
->GetCpuState();
1622 cpuStateReference
.SetTo(cpuState
);
1625 cpuState
= fActiveStackFrame
->GetCpuState();
1628 fRegistersView
->SetCpuState(cpuState
);
1633 TeamWindow::_UpdateRunButtons()
1635 uint32 threadState
= fActiveThread
!= NULL
1636 ? fActiveThread
->State() : THREAD_STATE_UNKNOWN
;
1638 switch (threadState
) {
1639 case THREAD_STATE_UNKNOWN
:
1640 fRunButton
->SetEnabled(false);
1641 fStepOverButton
->SetEnabled(false);
1642 fStepIntoButton
->SetEnabled(false);
1643 fStepOutButton
->SetEnabled(false);
1645 case THREAD_STATE_RUNNING
:
1646 if (fTraceUpdateRunner
== NULL
) {
1647 fRunButton
->SetLabel("Debug");
1648 fRunButton
->SetMessage(new BMessage(MSG_THREAD_STOP
));
1649 fRunButton
->SetEnabled(true);
1650 fStepOverButton
->SetEnabled(false);
1651 fStepIntoButton
->SetEnabled(false);
1652 fStepOutButton
->SetEnabled(false);
1655 case THREAD_STATE_STOPPED
:
1656 fRunButton
->SetLabel("Run");
1657 fRunButton
->SetMessage(new BMessage(MSG_THREAD_RUN
));
1658 fRunButton
->SetEnabled(true);
1659 fStepOverButton
->SetEnabled(true);
1660 fStepIntoButton
->SetEnabled(true);
1661 fStepOutButton
->SetEnabled(true);
1668 TeamWindow::_UpdateSourcePathState()
1670 LocatableFile
* sourceFile
= NULL
;
1671 BString sourceText
= "Source file unavailable.";
1672 BString truncatedText
;
1674 if (fActiveSourceCode
!= NULL
) {
1675 sourceFile
= fActiveFunction
->GetFunctionDebugInfo()->SourceFile();
1677 if (sourceFile
!= NULL
&& !sourceFile
->GetLocatedPath(sourceText
))
1678 sourceFile
->GetPath(sourceText
);
1680 function_source_state state
= fActiveFunction
->GetFunction()
1681 ->SourceCodeState();
1682 if (state
== FUNCTION_SOURCE_SUPPRESSED
)
1683 sourceText
.Prepend("Disassembly for: ");
1684 else if (state
!= FUNCTION_SOURCE_NOT_LOADED
1685 && fActiveSourceCode
->GetSourceFile() == NULL
1686 && sourceFile
!= NULL
) {
1687 sourceText
.Prepend("Click to locate source file '");
1689 truncatedText
= sourceText
;
1690 fSourcePathView
->TruncateString(&truncatedText
, B_TRUNCATE_MIDDLE
,
1691 fSourcePathView
->Bounds().Width());
1692 } else if (sourceFile
!= NULL
)
1693 sourceText
.Prepend("File: ");
1696 if (!truncatedText
.IsEmpty() && truncatedText
!= sourceText
) {
1697 fSourcePathView
->SetToolTip(sourceText
);
1698 fSourcePathView
->SetText(truncatedText
);
1700 fSourcePathView
->SetText(sourceText
);
1701 fSourcePathView
->SetToolTip((const char*)NULL
);
1707 TeamWindow::_ScrollToActiveFunction()
1709 // Scroll to the active function, if it has been selected manually.
1710 if (fActiveFunction
== NULL
|| fActiveSourceCode
== NULL
)
1713 switch (fActiveSourceObject
) {
1714 case ACTIVE_SOURCE_FUNCTION
:
1715 fSourceView
->ScrollToAddress(fActiveFunction
->Address());
1717 case ACTIVE_SOURCE_BREAKPOINT
:
1719 if (fActiveBreakpoint
== NULL
)
1722 const UserBreakpointLocation
& location
1723 = fActiveBreakpoint
->Location();
1724 int32 line
= location
.GetSourceLocation().Line();
1726 if (location
.SourceFile() != NULL
&& line
>= 0
1727 && fActiveSourceCode
->GetSourceFile()
1728 == location
.SourceFile()) {
1729 fSourceView
->ScrollToLine(line
);
1731 fSourceView
->ScrollToAddress(
1732 fActiveFunction
->Address()
1733 + location
.RelativeAddress());
1737 case ACTIVE_SOURCE_NONE
:
1738 case ACTIVE_SOURCE_STACK_FRAME
:
1745 TeamWindow::_HandleThreadStateChanged(thread_id threadID
)
1747 AutoLocker
< ::Team
> locker(fTeam
);
1749 ::Thread
* thread
= fTeam
->ThreadByID(threadID
);
1753 if (thread
->State() != THREAD_STATE_STOPPED
) {
1754 ThreadStackFrameSelectionEntry
* entry
1755 = fThreadSelectionInfoTable
->Lookup(thread
);
1756 if (entry
!= NULL
) {
1757 fThreadSelectionInfoTable
->Remove(entry
);
1762 // If the thread has been stopped and we don't have an active thread yet
1763 // (or it isn't stopped), switch to this thread. Otherwise ignore the event.
1764 if (thread
->State() == THREAD_STATE_STOPPED
1765 && (fActiveThread
== NULL
1766 || (thread
!= fActiveThread
1767 && fActiveThread
->State() != THREAD_STATE_STOPPED
))) {
1768 _SetActiveThread(thread
);
1769 } else if (thread
!= fActiveThread
) {
1770 // otherwise ignore the event, if the thread is not the active one
1774 // Switch to the threads tab view when the thread has stopped.
1775 if (thread
->State() == THREAD_STATE_STOPPED
) {
1776 fTabView
->Select(MAIN_TAB_INDEX_THREADS
);
1778 // if we hit a breakpoint or exception, raise the window to the
1779 // foreground, since if this occurs while e.g. debugging a GUI
1780 // app, it might not be immediately obvious that such an event
1781 // occurred as the app may simply appear to hang.
1785 _UpdateRunButtons();
1790 TeamWindow::_HandleCpuStateChanged(thread_id threadID
)
1792 // We're only interested in the currently selected thread
1793 if (fActiveThread
== NULL
|| threadID
!= fActiveThread
->ID())
1801 TeamWindow::_HandleStackTraceChanged(thread_id threadID
)
1803 // We're only interested in the currently selected thread
1804 if (fActiveThread
== NULL
|| threadID
!= fActiveThread
->ID())
1807 AutoLocker
< ::Team
> locker(fTeam
);
1809 StackTrace
* stackTrace
= fActiveThread
!= NULL
1810 ? fActiveThread
->GetStackTrace() : NULL
;
1811 BReference
<StackTrace
> stackTraceReference(stackTrace
);
1812 // hold a reference until the register view has one
1816 if (stackTrace
== NULL
) {
1817 if (fTraceUpdateRunner
!= NULL
)
1820 BMessage
message(MSG_CLEAR_STACK_TRACE
);
1821 fTraceUpdateRunner
= new(std::nothrow
) BMessageRunner(this,
1822 message
, 250000, 1);
1823 if (fTraceUpdateRunner
!= NULL
1824 && fTraceUpdateRunner
->InitCheck() == B_OK
) {
1825 fStackTraceView
->SetStackTraceClearPending();
1826 fVariablesView
->SetStackFrameClearPending();
1831 _SetActiveStackTrace(stackTrace
);
1836 TeamWindow::_HandleImageDebugInfoChanged(image_id imageID
)
1838 TRACE_GUI("TeamWindow::_HandleImageDebugInfoChanged(%" B_PRId32
")\n",
1841 // We're only interested in the currently selected thread
1842 if (fActiveImage
== NULL
|| imageID
!= fActiveImage
->ID())
1845 AutoLocker
< ::Team
> locker(fTeam
);
1847 ImageDebugInfo
* imageDebugInfo
= fActiveImage
!= NULL
1848 ? fActiveImage
->GetImageDebugInfo() : NULL
;
1850 TRACE_GUI(" image debug info: %p\n", imageDebugInfo
);
1852 BReference
<ImageDebugInfo
> imageDebugInfoReference(imageDebugInfo
);
1853 // hold a reference until we've set it
1857 fImageFunctionsView
->SetImageDebugInfo(imageDebugInfo
);
1862 TeamWindow::_HandleSourceCodeChanged()
1864 // If we don't have an active function anymore, the message is obsolete.
1865 if (fActiveFunction
== NULL
)
1868 // get a reference to the source code
1869 AutoLocker
< ::Team
> locker(fTeam
);
1871 SourceCode
* sourceCode
= NULL
;
1872 if (fActiveFunction
->GetFunction()->SourceCodeState()
1873 == FUNCTION_SOURCE_LOADED
) {
1874 sourceCode
= fActiveFunction
->GetFunction()->GetSourceCode();
1876 sourceCode
= fActiveFunction
->GetSourceCode();
1878 BReference
<SourceCode
> sourceCodeReference(sourceCode
);
1882 _SetActiveSourceCode(sourceCode
);
1887 TeamWindow::_HandleUserBreakpointChanged(UserBreakpoint
* breakpoint
)
1889 fSourceView
->UserBreakpointChanged(breakpoint
);
1890 fBreakpointsView
->UserBreakpointChanged(breakpoint
);
1895 TeamWindow::_HandleWatchpointChanged(Watchpoint
* watchpoint
)
1897 fBreakpointsView
->WatchpointChanged(watchpoint
);
1902 TeamWindow::_RetrieveMatchingSourceWorker(void* arg
)
1904 TeamWindow
* window
= (TeamWindow
*)arg
;
1906 BStringList
* entries
= new(std::nothrow
) BStringList();
1907 if (entries
== NULL
)
1909 ObjectDeleter
<BStringList
> stringListDeleter(entries
);
1911 if (!window
->Lock())
1915 window
->fActiveFunction
->GetFunctionDebugInfo()->SourceFile()
1919 status_t error
= window
->_RetrieveMatchingSourceEntries(path
, entries
);
1922 BMessenger
messenger(window
);
1923 if (messenger
.IsValid() && messenger
.LockTarget()) {
1924 if (window
->fActiveSourceWorker
== find_thread(NULL
)) {
1925 BMessage
message(MSG_SOURCE_ENTRY_QUERY_COMPLETE
);
1926 message
.AddInt32("error", error
);
1927 message
.AddPointer("entries", entries
);
1928 if (messenger
.SendMessage(&message
) == B_OK
)
1929 stringListDeleter
.Detach();
1939 TeamWindow::_HandleResolveMissingSourceFile(entry_ref
& locatedPath
)
1941 if (fActiveFunction
!= NULL
) {
1942 LocatableFile
* sourceFile
= fActiveFunction
->GetFunctionDebugInfo()
1944 if (sourceFile
!= NULL
) {
1946 sourceFile
->GetPath(sourcePath
);
1947 BString
sourceFileName(sourcePath
);
1948 int32 index
= sourcePath
.FindLast('/');
1950 sourceFileName
.Remove(0, index
+ 1);
1952 BPath
targetFilePath(&locatedPath
);
1953 if (targetFilePath
.InitCheck() != B_OK
)
1956 if (strcmp(sourceFileName
.String(), targetFilePath
.Leaf()) != 0) {
1958 message
.SetToFormat("The names of source file '%s' and located"
1959 " file '%s' differ. Use file anyway?",
1960 sourceFileName
.String(), targetFilePath
.Leaf());
1961 BAlert
* alert
= new(std::nothrow
) BAlert(
1962 "Source path mismatch", message
.String(), "Cancel", "Use");
1966 int32 choice
= alert
->Go();
1971 LocatableFile
* foundSourceFile
= fActiveSourceCode
1973 if (foundSourceFile
!= NULL
)
1974 fListener
->SourceEntryInvalidateRequested(foundSourceFile
);
1975 fListener
->SourceEntryLocateRequested(sourcePath
,
1976 targetFilePath
.Path());
1977 fListener
->FunctionSourceCodeRequested(fActiveFunction
);
1984 TeamWindow::_HandleLocateSourceRequest(BStringList
* entries
)
1986 if (fActiveFunction
== NULL
)
1988 else if (fActiveFunction
->GetFunctionDebugInfo()->SourceFile() == NULL
)
1990 else if (fActiveSourceCode
== NULL
)
1992 else if (fActiveFunction
->GetFunction()->SourceCodeState()
1993 == FUNCTION_SOURCE_NOT_LOADED
) {
1997 if (entries
== NULL
) {
1998 if (fActiveSourceWorker
< 0) {
1999 fActiveSourceWorker
= spawn_thread(&_RetrieveMatchingSourceWorker
,
2000 "source file query worker", B_NORMAL_PRIORITY
, this);
2001 if (fActiveSourceWorker
> 0)
2002 resume_thread(fActiveSourceWorker
);
2007 int32 count
= entries
->CountStrings();
2009 BPopUpMenu
* menu
= new(std::nothrow
) BPopUpMenu("");
2013 BPrivate::ObjectDeleter
<BPopUpMenu
> menuDeleter(menu
);
2014 BMenuItem
* item
= NULL
;
2015 for (int32 i
= 0; i
< count
; i
++) {
2016 item
= new(std::nothrow
) BMenuItem(entries
->StringAt(i
).String(),
2018 if (item
== NULL
|| !menu
->AddItem(item
)) {
2024 menu
->AddSeparatorItem();
2025 BMenuItem
* manualItem
= new(std::nothrow
) BMenuItem(
2026 "Locate manually" B_UTF8_ELLIPSIS
, NULL
);
2027 if (manualItem
== NULL
|| !menu
->AddItem(manualItem
)) {
2033 fSourcePathView
->GetMouse(&point
, NULL
, false);
2034 fSourcePathView
->ConvertToScreen(&point
);
2035 item
= menu
->Go(point
, false, true);
2038 else if (item
!= manualItem
) {
2039 // if the user picks to locate the entry manually,
2040 // then fall through to the usual file panel logic
2041 // as if we'd found no matches at all.
2043 if (get_ref_for_path(item
->Label(), &ref
) == B_OK
) {
2044 _HandleResolveMissingSourceFile(ref
);
2051 if (fFilePanel
== NULL
) {
2052 fFilePanel
= new BFilePanel(B_OPEN_PANEL
,
2053 new BMessenger(this));
2064 TeamWindow::_RetrieveMatchingSourceEntries(const BString
& path
,
2065 BStringList
* _entries
)
2067 BPath
filePath(path
);
2068 status_t error
= filePath
.InitCheck();
2072 _entries
->MakeEmpty();
2076 query
.PushAttr("name");
2077 query
.PushString(filePath
.Leaf());
2080 error
= query
.GetPredicate(&predicate
);
2084 BVolumeRoster roster
;
2086 while (roster
.GetNextVolume(&volume
) == B_OK
) {
2087 if (!volume
.KnowsQuery())
2090 if (query
.SetVolume(&volume
) != B_OK
)
2093 error
= query
.SetPredicate(predicate
.String());
2097 if (query
.Fetch() != B_OK
)
2101 while (query
.GetNextRef(&ref
) == B_OK
) {
2102 filePath
.SetTo(&ref
);
2103 _entries
->Add(filePath
.Path());
2114 TeamWindow::_SaveInspectorSettings(const BMessage
* settings
)
2116 if (fUiSettings
.AddSettings("inspectorWindow", *settings
) != B_OK
)
2124 TeamWindow::_GetActiveSourceLanguage(SourceLanguage
*& _language
)
2126 AutoLocker
< ::Team
> locker(fTeam
);
2128 if (!locker
.IsLocked())
2131 if (fActiveSourceCode
!= NULL
) {
2132 _language
= fActiveSourceCode
->GetSourceLanguage();
2133 _language
->AcquireReference();
2137 // if we made it this far, we were unable to acquire a source
2138 // language corresponding to the active function. As such,
2139 // try to fall back to the C++-style parser.
2140 _language
= new(std::nothrow
) CppLanguage();
2141 if (_language
== NULL
)