Пример #1
0
void
TeamWindow::_SetActiveThread(::Thread* thread)
{
	if (thread == fActiveThread)
		return;

	if (fActiveThread != NULL)
		fActiveThread->ReleaseReference();

	fActiveThread = thread;

	if (fActiveThread != NULL)
		fActiveThread->AcquireReference();

	AutoLocker< ::Team> locker(fTeam);
	_UpdateRunButtons();

	StackTrace* stackTrace = fActiveThread != NULL
		? fActiveThread->GetStackTrace() : NULL;
	BReference<StackTrace> stackTraceReference(stackTrace);
		// hold a reference until we've set it

	locker.Unlock();

	fThreadListView->SetThread(fActiveThread);

	_SetActiveStackTrace(stackTrace);
	_UpdateCpuState();
}
Пример #2
0
void
TeamWindow::_HandleThreadStateChanged(thread_id threadID)
{
	AutoLocker< ::Team> locker(fTeam);

	::Thread* thread = fTeam->ThreadByID(threadID);
	if (thread == NULL)
		return;

	// If the thread has been stopped and we don't have an active thread yet
	// (or it isn't stopped), switch to this thread. Otherwise ignore the event.
	if (thread->State() == THREAD_STATE_STOPPED
		&& (fActiveThread == NULL
			|| (thread != fActiveThread
				&& fActiveThread->State() != THREAD_STATE_STOPPED))) {
		_SetActiveThread(thread);
	} else if (thread != fActiveThread) {
		// otherwise ignore the event, if the thread is not the active one
		return;
	}

	// Switch to the threads tab view when the thread has stopped.
	if (thread->State() == THREAD_STATE_STOPPED) {
		fTabView->Select(MAIN_TAB_INDEX_THREADS);

		// if we hit a breakpoint or exception, raise the window to the
		// foreground, since if this occurs while e.g. debugging a GUI
		// app, it might not be immediately obvious that such an event
		// occurred as the app may simply appear to hang.
		Activate();
	}

	_UpdateRunButtons();
}
Пример #3
0
void
TeamWindow::_HandleThreadStateChanged(thread_id threadID)
{
	AutoLocker< ::Team> locker(fTeam);

	::Thread* thread = fTeam->ThreadByID(threadID);
	if (thread == NULL)
		return;

	// If the thread has been stopped and we don't have an active thread yet
	// (or it isn't stopped), switch to this thread. Otherwise ignore the event.
	if (thread->State() == THREAD_STATE_STOPPED
		&& (fActiveThread == NULL
			|| (thread != fActiveThread
				&& fActiveThread->State() != THREAD_STATE_STOPPED))) {
		_SetActiveThread(thread);
	} else if (thread != fActiveThread) {
		// otherwise ignore the event, if the thread is not the active one
		return;
	}

	// Switch to the threads tab view when the thread has stopped.
	if (thread->State() == THREAD_STATE_STOPPED)
		fTabView->Select(MAIN_TAB_INDEX_THREADS);

	_UpdateRunButtons();
}
Пример #4
0
void
TeamWindow::_Init()
{
	BScrollView* sourceScrollView;

	const float splitSpacing = 3.0f;

	BLayoutBuilder::Group<>(this, B_VERTICAL, 0.0f)
		.Add(fMenuBar = new BMenuBar("Menu"))
		.AddSplit(B_VERTICAL, splitSpacing)
			.GetSplitView(&fFunctionSplitView)
			.SetInsets(B_USE_SMALL_INSETS)
			.Add(fTabView = new BTabView("tab view"), 0.4f)
			.AddSplit(B_HORIZONTAL, splitSpacing)
				.GetSplitView(&fSourceSplitView)
				.AddGroup(B_VERTICAL, B_USE_SMALL_SPACING)
					.AddGroup(B_HORIZONTAL, B_USE_SMALL_SPACING)
						.Add(fRunButton = new BButton("Run"))
						.Add(fStepOverButton = new BButton("Step over"))
						.Add(fStepIntoButton = new BButton("Step into"))
						.Add(fStepOutButton = new BButton("Step out"))
						.AddGlue()
					.End()
					.Add(fSourcePathView = new BStringView(
						"source path",
						"Source path unavailable."), 4.0f)
					.Add(sourceScrollView = new BScrollView("source scroll",
						NULL, 0, true, true), splitSpacing)
				.End()
				.Add(fLocalsTabView = new BTabView("locals view"))
			.End()
			.AddSplit(B_VERTICAL, splitSpacing)
				.GetSplitView(&fConsoleSplitView)
				.SetInsets(0.0)
				.Add(fConsoleOutputView = ConsoleOutputView::Create())
			.End()
		.End();

	// add source view
	sourceScrollView->SetTarget(fSourceView = SourceView::Create(fTeam, this));

	// add threads tab
	BSplitView* threadGroup = new BSplitView(B_HORIZONTAL, splitSpacing);
	threadGroup->SetName("Threads");
	fTabView->AddTab(threadGroup);
	BLayoutBuilder::Split<>(threadGroup)
		.GetSplitView(&fThreadSplitView)
		.Add(fThreadListView = ThreadListView::Create(fTeam, this))
		.Add(fStackTraceView = StackTraceView::Create(this));

	// add images tab
	BSplitView* imagesGroup = new BSplitView(B_HORIZONTAL, splitSpacing);
	imagesGroup->SetName("Images");
	fTabView->AddTab(imagesGroup);
	BLayoutBuilder::Split<>(imagesGroup)
		.GetSplitView(&fImageSplitView)
		.Add(fImageListView = ImageListView::Create(fTeam, this))
		.Add(fImageFunctionsView = ImageFunctionsView::Create(this));

	// add breakpoints tab
	BGroupView* breakpointsGroup = new BGroupView(B_HORIZONTAL,
		B_USE_SMALL_SPACING);
	breakpointsGroup->SetName("Breakpoints");
	fTabView->AddTab(breakpointsGroup);
	BLayoutBuilder::Group<>(breakpointsGroup)
//		.SetInsets(0.0f)
		.Add(fBreakpointsView = BreakpointsView::Create(fTeam, this));

	// add local variables tab
	BView* tab = fVariablesView = VariablesView::Create(this);
	fLocalsTabView->AddTab(tab);

	// add registers tab
	tab = fRegistersView = RegistersView::Create(fTeam->GetArchitecture());
	fLocalsTabView->AddTab(tab);

	fRunButton->SetMessage(new BMessage(MSG_THREAD_RUN));
	fStepOverButton->SetMessage(new BMessage(MSG_THREAD_STEP_OVER));
	fStepIntoButton->SetMessage(new BMessage(MSG_THREAD_STEP_INTO));
	fStepOutButton->SetMessage(new BMessage(MSG_THREAD_STEP_OUT));
	fRunButton->SetTarget(this);
	fStepOverButton->SetTarget(this);
	fStepIntoButton->SetTarget(this);
	fStepOutButton->SetTarget(this);

	fSourcePathView->SetExplicitMinSize(BSize(100.0, B_SIZE_UNSET));
	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("Team");
	fMenuBar->AddItem(menu);
	BMenuItem* item = new BMenuItem("Restart", new BMessage(
		MSG_TEAM_RESTART_REQUESTED), 'R', B_SHIFT_KEY);
	menu->AddItem(item);
	item->SetTarget(this);
	item = new BMenuItem("Close", new BMessage(B_QUIT_REQUESTED),
		'W');
	menu->AddItem(item);
	item->SetTarget(this);
	menu = new BMenu("Edit");
	fMenuBar->AddItem(menu);
	item = new BMenuItem("Copy", new BMessage(B_COPY), 'C');
	menu->AddItem(item);
	item->SetTarget(this);
	item = new BMenuItem("Select all", new BMessage(B_SELECT_ALL), 'A');
	menu->AddItem(item);
	item->SetTarget(this);
	menu = new BMenu("Tools");
	fMenuBar->AddItem(menu);
	item = new BMenuItem("Save debug report",
		new BMessage(MSG_CHOOSE_DEBUG_REPORT_LOCATION));
	menu->AddItem(item);
	item->SetTarget(this);
	item = new BMenuItem("Inspect memory",
		new BMessage(MSG_SHOW_INSPECTOR_WINDOW), 'I');
	menu->AddItem(item);
	item->SetTarget(this);

	AutoLocker< ::Team> locker(fTeam);
	_UpdateRunButtons();
}
Пример #5
0
void
TeamWindow::MessageReceived(BMessage* message)
{
	switch (message->what) {
		case MSG_TEAM_RESTART_REQUESTED:
		{
			fListener->TeamRestartRequested();
			break;
		}
		case MSG_CHOOSE_DEBUG_REPORT_LOCATION:
		{
			try {
				char filename[B_FILE_NAME_LENGTH];
				UiUtils::ReportNameForTeam(fTeam, filename, sizeof(filename));
				BMessenger msgr(this);
				fFilePanel = new BFilePanel(B_SAVE_PANEL, &msgr,
					NULL, 0, false, new BMessage(MSG_GENERATE_DEBUG_REPORT));
				fFilePanel->SetSaveText(filename);
				fFilePanel->Show();
			} catch (...) {
				delete fFilePanel;
				fFilePanel = NULL;
			}
			break;
		}
		case MSG_GENERATE_DEBUG_REPORT:
		{
			delete fFilePanel;
			fFilePanel = NULL;

			BPath path;
			entry_ref ref;
			if (message->FindRef("directory", &ref) == B_OK
				&& message->HasString("name")) {
				path.SetTo(&ref);
				path.Append(message->FindString("name"));
				if (get_ref_for_path(path.Path(), &ref) == B_OK)
					fListener->DebugReportRequested(&ref);
			}
			break;
		}
		case MSG_DEBUG_REPORT_SAVED:
		{
			BString data;
			data.SetToFormat("Debug report successfully saved to '%s'",
				message->FindString("path"));
			BAlert *alert = new(std::nothrow) BAlert("Report saved",
				data.String(), "Close");
			if (alert == NULL)
				break;

			alert->SetFlags(alert->Flags() | B_CLOSE_ON_ESCAPE);
			alert->Go();
			break;
		}
		case MSG_SHOW_INSPECTOR_WINDOW:
		{
			if (fInspectorWindow) {
				fInspectorWindow->Activate(true);
			} else {
				try {
					fInspectorWindow = InspectorWindow::Create(fTeam,
						fListener, this);
					if (fInspectorWindow != NULL) {
						BMessage settings;
						fInspectorWindow->LoadSettings(fUiSettings);
						fInspectorWindow->Show();
					}
	           	} catch (...) {
	           		// TODO: notify user
	           	}
			}

			target_addr_t address;
			if (message->FindUInt64("address", &address) == B_OK) {
				BMessage addressMessage(MSG_INSPECT_ADDRESS);
				addressMessage.AddUInt64("address", address);
				fInspectorWindow->PostMessage(&addressMessage);
			}
           	break;
		}
		case MSG_INSPECTOR_WINDOW_CLOSED:
		{
			_SaveInspectorSettings(CurrentMessage());
			fInspectorWindow = NULL;
			break;

		}
		case MSG_SHOW_BREAK_CONDITION_CONFIG_WINDOW:
		{
			if (fBreakConditionConfigWindow) {
				fBreakConditionConfigWindow->Activate(true);
			} else {
				try {
					fBreakConditionConfigWindow
						= BreakConditionConfigWindow::Create(
						fTeam, fListener, this);
					if (fBreakConditionConfigWindow != NULL)
						fBreakConditionConfigWindow->Show();
	           	} catch (...) {
	           		// TODO: notify user
	           	}
			}
			break;
		}
		case MSG_BREAK_CONDITION_CONFIG_WINDOW_CLOSED:
		{
			fBreakConditionConfigWindow = NULL;
			break;
		}
		case MSG_SHOW_WATCH_VARIABLE_PROMPT:
		{
			target_addr_t address;
			uint32 type;
			int32 length;

			if (message->FindUInt64("address", &address) != B_OK
				|| message->FindUInt32("type", &type) != B_OK
				|| message->FindInt32("length", &length) != B_OK) {
				break;
			}

			try {
				WatchPromptWindow* window = WatchPromptWindow::Create(
					fTeam->GetArchitecture(), address, type, length,
					fListener);
				window->Show();
			} catch (...) {
				// TODO: notify user
			}
			break;
		}
		case B_REFS_RECEIVED:
		{
			entry_ref locatedPath;
			if (message->FindRef("refs", &locatedPath) != B_OK)
				break;

			_HandleResolveMissingSourceFile(locatedPath);
			break;
		}
		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;
		}
		case MSG_THREAD_RUN:
		case MSG_THREAD_STOP:
		case MSG_THREAD_STEP_OVER:
		case MSG_THREAD_STEP_INTO:
		case MSG_THREAD_STEP_OUT:
			if (fActiveThread != NULL && fTraceUpdateRunner == NULL) {
				fListener->ThreadActionRequested(fActiveThread->ID(),
					message->what);
			}
			break;

		case MSG_CLEAR_STACK_TRACE:
		{
			if (fTraceUpdateRunner != NULL) {
				_SetActiveStackTrace(NULL);
				_UpdateRunButtons();
			}
			break;
		}
		case MSG_THREAD_STATE_CHANGED:
		{
			int32 threadID;
			if (message->FindInt32("thread", &threadID) != B_OK)
				break;

			_HandleThreadStateChanged(threadID);
			break;
		}
		case MSG_THREAD_CPU_STATE_CHANGED:
		{
			int32 threadID;
			if (message->FindInt32("thread", &threadID) != B_OK)
				break;

			_HandleCpuStateChanged(threadID);
			break;
		}

		case MSG_THREAD_STACK_TRACE_CHANGED:
		{
			int32 threadID;
			if (message->FindInt32("thread", &threadID) != B_OK)
				break;

			_HandleStackTraceChanged(threadID);
			break;
		}

		case MSG_IMAGE_DEBUG_INFO_CHANGED:
		{
			int32 imageID;
			if (message->FindInt32("image", &imageID) != B_OK)
				break;

			_HandleImageDebugInfoChanged(imageID);
			break;
		}

		case MSG_CONSOLE_OUTPUT_RECEIVED:
		{
			int32 fd;
			BString output;
			if (message->FindInt32("fd", &fd) != B_OK
					|| message->FindString("output", &output) != B_OK) {
				break;
			}
			fConsoleOutputView->ConsoleOutputReceived(fd, output);
			break;
		}

		case MSG_USER_BREAKPOINT_CHANGED:
		{
			UserBreakpoint* breakpoint;
			if (message->FindPointer("breakpoint", (void**)&breakpoint) != B_OK)
				break;
			BReference<UserBreakpoint> breakpointReference(breakpoint, true);

			_HandleUserBreakpointChanged(breakpoint);
			break;
		}

		case MSG_WATCHPOINT_CHANGED:
		{
			Watchpoint* watchpoint;
			if (message->FindPointer("watchpoint", (void**)&watchpoint) != B_OK)
				break;
			BReference<Watchpoint> watchpointReference(watchpoint, true);

			_HandleWatchpointChanged(watchpoint);
			break;

		}

		case MSG_FUNCTION_SOURCE_CODE_CHANGED:
		{
			_HandleSourceCodeChanged();
			break;
		}

		default:
			BWindow::MessageReceived(message);
			break;
	}
}