Beispiel #1
0
status_t
set_port_owner(port_id id, team_id newTeamID)
{
	TRACE(("set_port_owner(id = %ld, team = %ld)\n", id, newTeamID));

	if (id < 0)
		return B_BAD_PORT_ID;

	int32 slot = id % sMaxPorts;

	MutexLocker locker(sPorts[slot].lock);

	if (sPorts[slot].id != id) {
		TRACE(("set_port_owner: invalid port_id %ld\n", id));
		return B_BAD_PORT_ID;
	}

	InterruptsSpinLocker teamLocker(gTeamSpinlock);

	struct team* team = team_get_team_struct_locked(newTeamID);
	if (team == NULL) {
		T(OwnerChange(sPorts[slot], newTeamID, B_BAD_TEAM_ID));
		return B_BAD_TEAM_ID;
	}

	// transfer ownership to other team
	list_remove_link(&sPorts[slot].team_link);
	list_add_item(&team->port_list, &sPorts[slot].team_link);
	sPorts[slot].owner = newTeamID;

	T(OwnerChange(sPorts[slot], newTeamID, B_OK));
	return B_OK;
}
void
BreakpointManager::UninstallTemporaryBreakpoint(target_addr_t address,
	BreakpointClient* client)
{
	AutoLocker<BLocker> installLocker(fLock);
	AutoLocker<Team> teamLocker(fTeam);

	Breakpoint* breakpoint = fTeam->BreakpointAtAddress(address);
	if (breakpoint == NULL)
		return;

	// remove the client
	breakpoint->RemoveClient(client);

	// check whether the breakpoint needs to be uninstalled
	bool uninstall = !breakpoint->ShouldBeInstalled()
		&& breakpoint->IsInstalled();

	// if unused remove it
	BReference<Breakpoint> breakpointReference(breakpoint);
	if (breakpoint->IsUnused())
		fTeam->RemoveBreakpoint(breakpoint);

	teamLocker.Unlock();

	if (uninstall) {
		fDebuggerInterface->UninstallBreakpoint(address);
		breakpoint->SetInstalled(false);
	}
}
Beispiel #3
0
void
BreakpointsView::_UpdateButtons()
{
	AutoLocker<Team> teamLocker(fTeam);

	bool hasEnabled = false;
	bool hasDisabled = false;
	bool valid = false;

	for (int32 i = 0; i < fSelectedBreakpoints.CountItems(); i++) {
		BreakpointProxy* proxy = fSelectedBreakpoints.ItemAt(i);
		switch (proxy->Type()) {
			case BREAKPOINT_PROXY_TYPE_BREAKPOINT:
			{
				UserBreakpoint* breakpoint = proxy->GetBreakpoint();
				if (breakpoint->IsValid()) {
					valid = true;
					if (breakpoint->IsEnabled())
						hasEnabled = true;
					else
						hasDisabled = true;
				}
				break;
			}
			case BREAKPOINT_PROXY_TYPE_WATCHPOINT:
			{
				Watchpoint* watchpoint = proxy->GetWatchpoint();
				valid = true;
				if (watchpoint->IsEnabled())
					hasEnabled = true;
				else
					hasDisabled = true;
				break;
			}
			default:
				break;
		}
	}

	if (valid) {
		// if we have at least one disabled breakpoint in the
		// selection, we leave the button as an Enable button
		if (hasEnabled && !hasDisabled) {
			fToggleBreakpointButton->SetLabel("Disable");
			fToggleBreakpointButton->SetMessage(
				new BMessage(MSG_DISABLE_BREAKPOINT));
		} else {
			fToggleBreakpointButton->SetLabel("Enable");
			fToggleBreakpointButton->SetMessage(
				new BMessage(MSG_ENABLE_BREAKPOINT));
		}

		fToggleBreakpointButton->SetEnabled(true);
		fRemoveBreakpointButton->SetEnabled(true);
	} else {
		fToggleBreakpointButton->SetLabel("Enable");
		fToggleBreakpointButton->SetEnabled(false);
		fRemoveBreakpointButton->SetEnabled(false);
	}
}
void
BreakpointEditWindow::_Init()
{
	fConditionInput = new BTextControl(NULL, NULL, NULL);
	BLayoutItem* textLayoutItem = fConditionInput->CreateTextViewLayoutItem();
	textLayoutItem->SetExplicitMinSize(BSize(200.0, B_SIZE_UNSET));
	BLayoutBuilder::Group<>(this, B_VERTICAL)
		.SetInsets(B_USE_DEFAULT_SPACING)
		.Add((fAlwaysRadio = new BRadioButton("Break always",
				new BMessage(MSG_SET_BREAK_ALWAYS))))
		.AddGroup(B_HORIZONTAL)
			.Add((fConditionRadio = new BRadioButton("Break on condition: ",
				new BMessage(MSG_SET_BREAK_ON_CONDITION))))
			.Add(textLayoutItem)
		.End()
		.AddGroup(B_HORIZONTAL)
			.AddGlue()
			.Add((fSaveButton = new BButton("Save",
				new BMessage(MSG_SAVE_BREAKPOINT_SETTINGS))))
			.Add((fCancelButton = new BButton("Cancel",
				new BMessage(B_CANCEL))))
		.End()
	.End();

	AutoLocker< ::Team> teamLocker(fTeam);
	if (fTargetBreakpoint->HasCondition()) {
		fConditionRadio->SetValue(B_CONTROL_ON);
		fConditionInput->SetText(fTargetBreakpoint->Condition());
	} else {
		fAlwaysRadio->SetValue(B_CONTROL_ON);
		fConditionInput->SetEnabled(false);
	}
}
status_t
DebugReportGenerator::_GenerateReport(const entry_ref& outputPath)
{
	BFile file(&outputPath, B_WRITE_ONLY | B_CREATE_FILE | B_ERASE_FILE);
	status_t result = file.InitCheck();
	if (result != B_OK)
		return result;

	result = _GenerateReportHeader(file);
	if (result != B_OK)
		return result;

	result = _DumpRunningThreads(file);
	if (result != B_OK)
		return result;

	result = _DumpLoadedImages(file);
	if (result != B_OK)
		return result;

	result = _DumpAreas(file);
	if (result != B_OK)
		return result;

	result = _DumpSemaphores(file);
	if (result != B_OK)
		return result;

	BPath path(&outputPath);

	AutoLocker< ::Team> teamLocker(fTeam);
	fTeam->NotifyDebugReportChanged(path.Path());

	return B_OK;
}
Beispiel #6
0
static void
notify_loading_app(status_t result, bool suspend)
{
	Team* team = thread_get_current_thread()->team;

	TeamLocker teamLocker(team);

	if (team->loading_info) {
		// there's indeed someone waiting
		struct team_loading_info* loadingInfo = team->loading_info;
		team->loading_info = NULL;

		loadingInfo->result = result;
		loadingInfo->done = true;

		// we're done with the team stuff, get the scheduler lock instead
		teamLocker.Unlock();
		InterruptsSpinLocker schedulerLocker(gSchedulerLock);

		// wake up the waiting thread
		if (loadingInfo->thread->state == B_THREAD_SUSPENDED)
			scheduler_enqueue_in_run_queue(loadingInfo->thread);

		// suspend ourselves, if desired
		if (suspend) {
			thread_get_current_thread()->next_state = B_THREAD_SUSPENDED;
			scheduler_reschedule();
		}
	}
}
Beispiel #7
0
	bool _GetBreakpointValueAt(UserBreakpoint* breakpoint, int32 rowIndex,
		int32 columnIndex, BVariant &value)
	{
		const UserBreakpointLocation& location = breakpoint->Location();

		switch (columnIndex) {
			case 0:
				value.SetTo((int32)breakpoint->IsEnabled());
				return true;
			case 1:
				value.SetTo(location.GetFunctionID()->FunctionName(),
					B_VARIANT_DONT_COPY_DATA);
				return true;
			case 2:
			{
				LocatableFile* sourceFile = location.SourceFile();
				BString data;
				if (sourceFile != NULL) {
					data.SetToFormat("%s:%" B_PRId32, sourceFile->Name(),
						location.GetSourceLocation().Line() + 1);
				} else {
					AutoLocker<Team> teamLocker(fTeam);
					if (UserBreakpointInstance* instance
							= breakpoint->InstanceAt(0)) {
						data.SetToFormat("%#" B_PRIx64, instance->Address());
					}
				}
				value.SetTo(data);
				return true;
			}
			default:
				return false;
		}
	}
Beispiel #8
0
void
CliContext::PrintCurrentThread()
{
	AutoLocker<Team> teamLocker(fTeam);

	if (fCurrentThread != NULL) {
		printf("current thread: %" B_PRId32 " \"%s\"\n", fCurrentThread->ID(),
			fCurrentThread->Name());
	} else
		printf("no current thread\n");
}
void
DebugReportGenerator::FunctionSourceCodeChanged(Function* function)
{
	AutoLocker< ::Team> teamLocker(fTeam);
	if (function == fSourceWaitingFunction) {
		if (function->FirstInstance()->SourceCodeState()
				== FUNCTION_SOURCE_LOADED
		   || function->FirstInstance()->SourceCodeState()
				== FUNCTION_SOURCE_UNAVAILABLE) {
			release_sem(fTeamDataSem);
		}
	}
}
Beispiel #10
0
void
InspectorWindow::_SetCurrentBlock(TeamMemoryBlock* block)
{
	AutoLocker< ::Team> teamLocker(fTeam);
	if (fCurrentBlock != NULL) {
		fCurrentBlock->RemoveListener(this);
		fCurrentBlock->ReleaseReference();
	}

	fCurrentBlock = block;
	fMemoryView->SetTargetAddress(fCurrentBlock, fCurrentAddress);
	_UpdateWritableOptions();
}
status_t
BreakpointManager::InstallTemporaryBreakpoint(target_addr_t address,
	BreakpointClient* client)
{
	AutoLocker<BLocker> installLocker(fLock);
	AutoLocker<Team> teamLocker(fTeam);

	// create a breakpoint, if it doesn't exist yet
	Breakpoint* breakpoint = fTeam->BreakpointAtAddress(address);
	if (breakpoint == NULL) {
		Image* image = fTeam->ImageByAddress(address);
		if (image == NULL)
			return B_BAD_ADDRESS;

		breakpoint = new(std::nothrow) Breakpoint(image, address);
		if (breakpoint == NULL)
			return B_NO_MEMORY;

		if (!fTeam->AddBreakpoint(breakpoint))
			return B_NO_MEMORY;
	}

	BReference<Breakpoint> breakpointReference(breakpoint);

	// add the client
	status_t error;
	if (breakpoint->AddClient(client)) {
		if (breakpoint->IsInstalled())
			return B_OK;

		// install
		teamLocker.Unlock();

		error = fDebuggerInterface->InstallBreakpoint(address);
		if (error == B_OK) {
			breakpoint->SetInstalled(true);
			return B_OK;
		}

		teamLocker.Lock();

		breakpoint->RemoveClient(client);
	} else
		error = B_NO_MEMORY;

	// clean up on error
	if (breakpoint->IsUnused())
		fTeam->RemoveBreakpoint(breakpoint);

	return error;
}
bool
CommandLineUserInterface::_ReportTargetThreadStopNeeded() const
{
	if (fReportTargetThread < 0)
		return false;

	Team* team = fContext.GetTeam();
	AutoLocker<Team> teamLocker(team);
	Thread* thread = team->ThreadByID(fReportTargetThread);
	if (thread == NULL)
		return false;

	return thread->State() != THREAD_STATE_STOPPED;
}
Beispiel #13
0
void
core_dump_trap_thread()
{
	Thread* thread = thread_get_current_thread();
	ConditionVariableEntry conditionVariableEntry;
	TeamLocker teamLocker(thread->team);

	while ((atomic_get(&thread->flags) & THREAD_FLAGS_TRAP_FOR_CORE_DUMP)
			!= 0) {
		thread->team->CoreDumpCondition()->Add(&conditionVariableEntry);
		teamLocker.Unlock();
		conditionVariableEntry.Wait();
		teamLocker.Lock();
	}
}
Beispiel #14
0
InspectorWindow::~InspectorWindow()
{
	_SetCurrentBlock(NULL);

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

	if (fExpressionInfo != NULL) {
		fExpressionInfo->RemoveListener(this);
		fExpressionInfo->ReleaseReference();
	}

	AutoLocker< ::Team> teamLocker(fTeam);
	fTeam->RemoveListener(this);
}
Beispiel #15
0
status_t
ThreadHandler::GetImageDebugInfo(Image* image, ImageDebugInfo*& _info)
{
	AutoLocker<Team> teamLocker(fThread->GetTeam());

	if (image->GetImageDebugInfo() != NULL) {
		_info = image->GetImageDebugInfo();
		_info->AcquireReference();
		return B_OK;
	}

	// Let's be lazy. If the image debug info has not been loaded yet, the user
	// can't have seen any source code either.
	return B_ENTRY_NOT_FOUND;
}
void
BreakpointManager::UninstallUserBreakpoint(UserBreakpoint* userBreakpoint)
{
	AutoLocker<BLocker> installLocker(fLock);
	AutoLocker<Team> teamLocker(fTeam);

	if (!userBreakpoint->IsValid())
		return;

	fTeam->RemoveUserBreakpoint(userBreakpoint);

	userBreakpoint->SetValid(false);
	userBreakpoint->SetEnabled(false);

	teamLocker.Unlock();

	// uninstall the breakpoints as needed
	for (int32 i = 0;
		UserBreakpointInstance* instance = userBreakpoint->InstanceAt(i); i++) {
		if (Breakpoint* breakpoint = instance->GetBreakpoint())
			_UpdateBreakpointInstallation(breakpoint);
	}

	teamLocker.Lock();

	// detach the breakpoints from the user breakpoint instances
	for (int32 i = 0;
		UserBreakpointInstance* instance = userBreakpoint->InstanceAt(i); i++) {
		if (Breakpoint* breakpoint = instance->GetBreakpoint()) {
			instance->SetBreakpoint(NULL);
			breakpoint->RemoveUserBreakpoint(instance);

			if (breakpoint->IsUnused())
				fTeam->RemoveBreakpoint(breakpoint);
		}
	}

	fTeam->NotifyUserBreakpointChanged(userBreakpoint);

	teamLocker.Unlock();
	installLocker.Unlock();

	// release the reference from InstallUserBreakpoint()
	userBreakpoint->ReleaseReference();
}
void
CliStackTraceCommand::Execute(int argc, const char* const* argv,
	CliContext& context)
{
	// get the current thread
	Team* team = context.GetTeam();
	AutoLocker<Team> teamLocker(team);
	Thread* thread = context.CurrentThread();
	if (thread == NULL) {
		printf("no current thread\n");
		return;
	}

	if (thread->State() != THREAD_STATE_STOPPED) {
		printf("Current thread is not stopped. Can't get stack trace.\n");
		return;
	}

	// get its stack trace
	StackTrace* stackTrace = thread->GetStackTrace();
	while (stackTrace == NULL) {
		context.WaitForEvents(CliContext::EVENT_THREAD_STACK_TRACE_CHANGED);
		if (context.IsTerminating())
			return;
		stackTrace = thread->GetStackTrace();
	}
	BReference<StackTrace> stackTraceReference(stackTrace);
		// hold a reference until we're done

	teamLocker.Unlock();

	// print the stack trace
	int32 frameCount = stackTrace->CountFrames();
	for (int32 i = 0; i < frameCount; i++) {
		StackFrame* frame = stackTrace->FrameAt(i);
		printf("%3" B_PRId32 "  %#" B_PRIx64 "  %#" B_PRIx64, i,
			(uint64)frame->FrameAddress(), (uint64)frame->InstructionPointer());

		char functionName[512];
		UiUtils::FunctionNameForFrame(frame, functionName,
			sizeof(functionName));
		printf("  %s\n", functionName);
	}
}
Beispiel #18
0
void
BreakConditionConfigWindow::_UpdateThrownBreakpoints(bool enable)
{
	AutoLocker< ::Team> teamLocker(fTeam);
	for (ImageList::ConstIterator it = fTeam->Images().GetIterator();
		it.HasNext();) {
		Image* image = it.Next();

		ImageDebugInfo* info = image->GetImageDebugInfo();
		target_addr_t address;
		if (_FindExceptionFunction(info, address) != B_OK)
			continue;

		if (enable)
			fListener->SetBreakpointRequested(address, true, true);
		else
			fListener->ClearBreakpointRequested(address);
	}
}
Beispiel #19
0
/*static*/ status_t
LoadImageDebugInfoJob::ScheduleIfNecessary(Worker* worker, Image* image,
        ImageDebugInfo** _imageDebugInfo)
{
    AutoLocker<Team> teamLocker(image->GetTeam());

    // If already loaded, we're done.
    if (image->GetImageDebugInfo() != NULL) {
        if (_imageDebugInfo != NULL) {
            *_imageDebugInfo = image->GetImageDebugInfo();
            (*_imageDebugInfo)->AcquireReference();
        }
        return B_OK;
    }

    // If already loading, the caller has to wait, if desired.
    if (image->ImageDebugInfoState() == IMAGE_DEBUG_INFO_LOADING) {
        if (_imageDebugInfo != NULL)
            *_imageDebugInfo = NULL;
        return B_OK;
    }

    // If an earlier load attempt failed, bail out.
    if (image->ImageDebugInfoState() != IMAGE_DEBUG_INFO_NOT_LOADED)
        return B_ERROR;

    // schedule a job
    LoadImageDebugInfoJob* job = new(std::nothrow) LoadImageDebugInfoJob(image);
    if (job == NULL)
        return B_NO_MEMORY;

    status_t error = worker->ScheduleJob(job);
    if (error != B_OK) {
        image->SetImageDebugInfo(NULL, IMAGE_DEBUG_INFO_UNAVAILABLE);
        return error;
    }

    image->SetImageDebugInfo(NULL, IMAGE_DEBUG_INFO_LOADING);

    if (_imageDebugInfo != NULL)
        *_imageDebugInfo = NULL;
    return B_OK;
}
Beispiel #20
0
void
ThreadSignalEvent::DoDPC(DPCQueue* queue)
{
	fSignal->AcquireReference();
		// one reference is transferred to send_signal_to_team_locked
	InterruptsReadSpinLocker teamLocker(fThread->team_lock);
	SpinLocker locker(fThread->team->signal_lock);
	status_t error = send_signal_to_thread_locked(fThread, fSignal->Number(),
		fSignal, B_DO_NOT_RESCHEDULE);
	locker.Unlock();
	teamLocker.Unlock();

	// There are situations (for certain signals), in which
	// send_signal_to_team_locked() succeeds without queuing the signal.
	if (error != B_OK || !fSignal->IsPending())
		fSignal->SetUnused();

	// We're no longer queued in the DPC queue, so we can be reused.
	atomic_set(&fPendingDPC, 0);
}
Beispiel #21
0
	virtual bool GetValueAt(int32 rowIndex, int32 columnIndex, BVariant& value)
	{
		UserBreakpoint* breakpoint = fBreakpoints.ItemAt(rowIndex);
		if (breakpoint == NULL)
			return false;
		const UserBreakpointLocation& location = breakpoint->Location();

		switch (columnIndex) {
			case 0:
				value.SetTo((int32)breakpoint->IsEnabled());
				return true;
			case 1:
				value.SetTo(location.GetFunctionID()->FunctionName(),
					B_VARIANT_DONT_COPY_DATA);
				return true;
			case 2:
				if (LocatableFile* sourceFile = location.SourceFile()) {
					value.SetTo(sourceFile->Name(), B_VARIANT_DONT_COPY_DATA);
					return true;
				}
				return false;
			case 3:
				if (location.SourceFile() != NULL) {
					value.SetTo(location.GetSourceLocation().Line() + 1);
					return true;
				}
				return false;
			case 4:
				if (location.SourceFile() == NULL) {
					AutoLocker<Team> teamLocker(fTeam);
					if (UserBreakpointInstance* instance
							= breakpoint->InstanceAt(0)) {
						value.SetTo(instance->Address());
						return true;
					}
				}
				return false;
			default:
				return false;
		}
	}
Beispiel #22
0
void
CliContext::WaitForThreadOrUser()
{
	ProcessPendingEvents();

// TODO: Deal with SIGINT as well!
	for (;;) {
		_PrepareToWaitForEvents(
			EVENT_USER_INTERRUPT | EVENT_THREAD_STOPPED);

		// check whether there are any threads stopped already
		Thread* stoppedThread = NULL;
		BReference<Thread> stoppedThreadReference;

		AutoLocker<Team> teamLocker(fTeam);

		for (ThreadList::ConstIterator it = fTeam->Threads().GetIterator();
				Thread* thread = it.Next();) {
			if (thread->State() == THREAD_STATE_STOPPED) {
				stoppedThread = thread;
				stoppedThreadReference.SetTo(thread);
				break;
			}
		}

		teamLocker.Unlock();

		if (stoppedThread != NULL) {
			if (fCurrentThread == NULL)
				SetCurrentThread(stoppedThread);

			_SignalInputLoop(EVENT_THREAD_STOPPED);
		}

		uint32 events = _WaitForEvents();
		if ((events & EVENT_QUIT) != 0 || stoppedThread != NULL) {
			ProcessPendingEvents();
			return;
		}
	}
}
Beispiel #23
0
status_t
GetStackTraceJob::GetImageDebugInfo(Image* image, ImageDebugInfo*& _info)
{
    AutoLocker<Team> teamLocker(fThread->GetTeam());

    while (image->GetImageDebugInfo() == NULL) {
        // schedule a job, if not loaded
        ImageDebugInfo* info;
        status_t error = LoadImageDebugInfoJob::ScheduleIfNecessary(GetWorker(),
                         image, &info);
        if (error != B_OK)
            return error;

        if (info != NULL) {
            _info = info;
            return B_OK;
        }

        teamLocker.Unlock();

        // wait for the job to finish
        switch (WaitFor(SimpleJobKey(image, JOB_TYPE_LOAD_IMAGE_DEBUG_INFO))) {
        case JOB_DEPENDENCY_SUCCEEDED:
        case JOB_DEPENDENCY_NOT_FOUND:
            // "Not found" can happen due to a race condition between
            // unlocking the worker and starting to wait.
            break;
        case JOB_DEPENDENCY_FAILED:
        case JOB_DEPENDENCY_ABORTED:
        default:
            return B_ERROR;
        }

        teamLocker.Lock();
    }

    _info = image->GetImageDebugInfo();
    _info->AcquireReference();

    return B_OK;
}
Beispiel #24
0
InspectorWindow::InspectorWindow(::Team* team, UserInterfaceListener* listener,
	BHandler* target)
	:
	BWindow(BRect(100, 100, 700, 500), "Inspector", B_TITLED_WINDOW,
		B_ASYNCHRONOUS_CONTROLS | B_AUTO_UPDATE_SIZE_LIMITS),
	fListener(listener),
	fAddressInput(NULL),
	fHexMode(NULL),
	fTextMode(NULL),
	fWritableBlockIndicator(NULL),
	fMemoryView(NULL),
	fCurrentBlock(NULL),
	fCurrentAddress(0LL),
	fTeam(team),
	fLanguage(NULL),
	fExpressionInfo(NULL),
	fTarget(target)
{
	AutoLocker< ::Team> teamLocker(fTeam);
	fTeam->AddListener(this);
}
bool
SystemProfiler::_TeamRemoved(Team* team)
{
	// TODO: It is possible that we get remove notifications for teams that
	// had already been removed from the global team list when we did the
	// initial scan, but were still in the process of dying. ATM it is not
	// really possible to identify such a case.

	TeamLocker teamLocker(team);
	InterruptsSpinLocker locker(fLock);

	system_profiler_team_removed* event = (system_profiler_team_removed*)
		_AllocateBuffer(sizeof(system_profiler_team_removed),
			B_SYSTEM_PROFILER_TEAM_REMOVED, 0, 0);
	if (event == NULL)
		return false;

	event->team = team->id;

	fHeader->size = fBufferSize;

	return true;
}
Beispiel #26
0
status_t
delete_port(port_id id)
{
	TRACE(("delete_port(id = %ld)\n", id));

	if (!sPortsActive || id < 0)
		return B_BAD_PORT_ID;

	int32 slot = id % sMaxPorts;

	MutexLocker locker(sPorts[slot].lock);

	if (sPorts[slot].id != id) {
		TRACE(("delete_port: invalid port_id %ld\n", id));
		return B_BAD_PORT_ID;
	}

	T(Delete(sPorts[slot]));

	{
		InterruptsSpinLocker teamLocker(gTeamSpinlock);
		list_remove_link(&sPorts[slot].team_link);
	}

	uninit_port_locked(sPorts[slot]);

	locker.Unlock();

	MutexLocker _(sPortsLock);

	// update the first free slot hint in the array
	if (slot < sFirstFreeSlot)
		sFirstFreeSlot = slot;

	sUsedPorts--;
	return B_OK;
}
bool
SystemProfiler::_TeamExec(Team* team)
{
	TeamLocker teamLocker(team);

	size_t argsLen = strlen(team->Args());

	InterruptsSpinLocker locker(fLock);

	system_profiler_team_exec* event = (system_profiler_team_exec*)
		_AllocateBuffer(sizeof(system_profiler_team_exec) + argsLen,
			B_SYSTEM_PROFILER_TEAM_EXEC, 0, 0);
	if (event == NULL)
		return false;

	event->team = team->id;
	strlcpy(event->thread_name, team->main_thread->name,
		sizeof(event->thread_name));
	strcpy(event->args, team->Args());

	fHeader->size = fBufferSize;

	return true;
}
Beispiel #28
0
void
TeamDebugger::_HandleInspectAddress(target_addr_t address,
	TeamMemoryBlock::Listener* listener)
{
	TRACE_CONTROL("TeamDebugger::_HandleInspectAddress(%" B_PRIx64 ", %p)\n",
		address, listener);

	TeamMemoryBlock* memoryBlock = fMemoryBlockManager
		->GetMemoryBlock(address);

	if (memoryBlock == NULL) {
		_NotifyUser("Inspect Address", "Failed to allocate memory block");
		return;
	}

	if (!memoryBlock->HasListener(listener))
		memoryBlock->AddListener(listener);

	if (!memoryBlock->IsValid()) {
		AutoLocker< ::Team> teamLocker(fTeam);

		TeamMemory* memory = fTeam->GetTeamMemory();
		// schedule the job
		status_t result;
		if ((result = fWorker->ScheduleJob(
			new(std::nothrow) RetrieveMemoryBlockJob(fTeam, memory,
				memoryBlock),
			this)) != B_OK) {
			memoryBlock->ReleaseReference();
			_NotifyUser("Inspect Address", "Failed to retrieve memory data: %s",
				strerror(result));
		}
	} else
		memoryBlock->NotifyDataRetrieved();

}
Beispiel #29
0
status_t
Architecture::CreateStackTrace(Team* team,
                               ImageDebugInfoProvider* imageInfoProvider, CpuState* cpuState,
                               StackTrace*& _stackTrace, int32 maxStackDepth, bool useExistingTrace)
{
    BReference<CpuState> cpuStateReference(cpuState);

    StackTrace* stackTrace = NULL;
    ObjectDeleter<StackTrace> stackTraceDeleter;
    StackFrame* frame = NULL;

    if (useExistingTrace)
        stackTrace = _stackTrace;
    else {
        // create the object
        stackTrace = new(std::nothrow) StackTrace;
        if (stackTrace == NULL)
            return B_NO_MEMORY;
        stackTraceDeleter.SetTo(stackTrace);
    }

    // if we're passed an already existing partial stack trace,
    // attempt to continue building it from where it left off.
    if (stackTrace->CountFrames() > 0) {
        frame = stackTrace->FrameAt(stackTrace->CountFrames() - 1);
        cpuState = frame->GetCpuState();
    }

    while (cpuState != NULL) {
        // get the instruction pointer
        target_addr_t instructionPointer = cpuState->InstructionPointer();
        if (instructionPointer == 0)
            break;

        // get the image for the instruction pointer
        AutoLocker<Team> teamLocker(team);
        Image* image = team->ImageByAddress(instructionPointer);
        BReference<Image> imageReference(image);
        teamLocker.Unlock();

        // get the image debug info
        ImageDebugInfo* imageDebugInfo = NULL;
        if (image != NULL)
            imageInfoProvider->GetImageDebugInfo(image, imageDebugInfo);
        BReference<ImageDebugInfo> imageDebugInfoReference(imageDebugInfo,
                true);

        // get the function
        teamLocker.Lock();
        FunctionInstance* function = NULL;
        FunctionDebugInfo* functionDebugInfo = NULL;
        if (imageDebugInfo != NULL) {
            function = imageDebugInfo->FunctionAtAddress(instructionPointer);
            if (function != NULL)
                functionDebugInfo = function->GetFunctionDebugInfo();
        }
        BReference<FunctionInstance> functionReference(function);
        teamLocker.Unlock();

        // If the CPU state's instruction pointer is actually the return address
        // of the next frame, we let the architecture fix that.
        if (frame != NULL
                && frame->ReturnAddress() == cpuState->InstructionPointer()) {
            UpdateStackFrameCpuState(frame, image,
                                     functionDebugInfo, cpuState);
        }

        // create the frame using the debug info
        StackFrame* previousFrame = NULL;
        CpuState* previousCpuState = NULL;
        if (function != NULL) {
            status_t error = functionDebugInfo->GetSpecificImageDebugInfo()
                             ->CreateFrame(image, function, cpuState, previousFrame,
                                           previousCpuState);
            if (error != B_OK && error != B_UNSUPPORTED)
                break;
        }

        // If we have no frame yet, let the architecture create it.
        if (previousFrame == NULL) {
            status_t error = CreateStackFrame(image, functionDebugInfo,
                                              cpuState, frame == NULL, previousFrame, previousCpuState);
            if (error != B_OK)
                break;
        }

        cpuStateReference.SetTo(previousCpuState, true);

        previousFrame->SetImage(image);
        previousFrame->SetFunction(function);

        if (!stackTrace->AddFrame(previousFrame)) {
            delete previousFrame;
            return B_NO_MEMORY;
        }

        frame = previousFrame;
        cpuState = previousCpuState;
        if (--maxStackDepth == 0)
            break;
    }

    stackTraceDeleter.Detach();
    _stackTrace = stackTrace;
    return B_OK;
}
Beispiel #30
0
port_id
create_port(int32 queueLength, const char* name)
{
	TRACE(("create_port(queueLength = %ld, name = \"%s\")\n", queueLength,
		name));

	if (!sPortsActive) {
		panic("ports used too early!\n");
		return B_BAD_PORT_ID;
	}
	if (queueLength < 1 || queueLength > MAX_QUEUE_LENGTH)
		return B_BAD_VALUE;

	struct team* team = thread_get_current_thread()->team;
	if (team == NULL)
		return B_BAD_TEAM_ID;

	MutexLocker locker(sPortsLock);

	// check early on if there are any free port slots to use
	if (sUsedPorts >= sMaxPorts)
		return B_NO_MORE_PORTS;

	// check & dup name
	char* nameBuffer = strdup(name != NULL ? name : "unnamed port");
	if (nameBuffer == NULL)
		return B_NO_MEMORY;

	sUsedPorts++;

	// find the first empty spot
	for (int32 slot = 0; slot < sMaxPorts; slot++) {
		int32 i = (slot + sFirstFreeSlot) % sMaxPorts;

		if (sPorts[i].id == -1) {
			// make the port_id be a multiple of the slot it's in
			if (i >= sNextPort % sMaxPorts)
				sNextPort += i - sNextPort % sMaxPorts;
			else
				sNextPort += sMaxPorts - (sNextPort % sMaxPorts - i);
			sFirstFreeSlot = slot + 1;

			MutexLocker portLocker(sPorts[i].lock);
			sPorts[i].id = sNextPort++;
			locker.Unlock();

			sPorts[i].capacity = queueLength;
			sPorts[i].owner = team_get_current_team_id();
			sPorts[i].lock.name = nameBuffer;
			sPorts[i].read_count = 0;
			sPorts[i].write_count = queueLength;
			sPorts[i].total_count = 0;
			sPorts[i].select_infos = NULL;

			{
				InterruptsSpinLocker teamLocker(gTeamSpinlock);
				list_add_item(&team->port_list, &sPorts[i].team_link);
			}

			port_id id = sPorts[i].id;

			T(Create(sPorts[i]));
			portLocker.Unlock();

			TRACE(("create_port() done: port created %ld\n", id));

			sNotificationService.Notify(PORT_ADDED, id);
			return id;
		}
	}

	// Still not enough ports... - due to sUsedPorts, this cannot really
	// happen anymore.
	panic("out of ports, but sUsedPorts is broken");
	return B_NO_MORE_PORTS;
}