Exemplo n.º 1
0
status_t
LoadSourceCodeJob::Do()
{
	// if requested, try loading the source code for the function
	Function* function = fFunctionInstance->GetFunction();
	if (fLoadForFunction) {
		FileSourceCode* sourceCode;
		status_t error = fTeam->DebugInfo()->LoadSourceCode(
			function->SourceFile(), sourceCode);

		AutoLocker<Team> locker(fTeam);

		if (error == B_OK) {
			function->SetSourceCode(sourceCode, FUNCTION_SOURCE_LOADED);
			sourceCode->ReleaseReference();
			return B_OK;
		}

		function->SetSourceCode(NULL, FUNCTION_SOURCE_UNAVAILABLE);
	}

	// Only try to load the function instance code, if it's not overridden yet.
	AutoLocker<Team> locker(fTeam);
	if (fFunctionInstance->SourceCodeState() != FUNCTION_SOURCE_LOADING)
		return B_OK;
	locker.Unlock();

	// disassemble the function
	DisassembledCode* sourceCode = NULL;
	status_t error = fTeam->DebugInfo()->DisassembleFunction(fFunctionInstance,
		sourceCode);

	// set the result
	locker.Lock();
	if (error == B_OK) {
		if (fFunctionInstance->SourceCodeState() == FUNCTION_SOURCE_LOADING) {
			// various parts of the debugger expect functions to have only
			// one of source or disassembly available. As such, if the current
			// function had source code previously active, unset it when
			// explicitly asked for disassembly. This needs to be done first
			// since Function will clear the disassembled code states of all
			// its child instances.
			if (function->SourceCodeState() == FUNCTION_SOURCE_LOADED) {
				FileSourceCode* sourceCode = function->GetSourceCode();
				function->SetSourceCode(sourceCode,
					FUNCTION_SOURCE_NOT_LOADED);
			}

			fFunctionInstance->SetSourceCode(sourceCode,
				FUNCTION_SOURCE_LOADED);
			sourceCode->ReleaseReference();
		}
	} else
		fFunctionInstance->SetSourceCode(NULL, FUNCTION_SOURCE_UNAVAILABLE);

	return error;
}
Exemplo n.º 2
0
status_t
LoadSourceCodeJob::Do()
{
	// if requested, try loading the source code for the function
	Function* function = fFunctionInstance->GetFunction();
	if (fLoadForFunction) {
		FileSourceCode* sourceCode;
		status_t error = fTeam->DebugInfo()->LoadSourceCode(
			function->SourceFile(), sourceCode);

		AutoLocker<Team> locker(fTeam);

		if (error == B_OK) {
			function->SetSourceCode(sourceCode, FUNCTION_SOURCE_LOADED);
			sourceCode->ReleaseReference();
			return B_OK;
		}

		function->SetSourceCode(NULL, FUNCTION_SOURCE_UNAVAILABLE);
	}

	// Only try to load the function instance code, if it's not overridden yet.
	AutoLocker<Team> locker(fTeam);
	if (fFunctionInstance->SourceCodeState() != FUNCTION_SOURCE_LOADING)
		return B_OK;
	locker.Unlock();

	// disassemble the function
	DisassembledCode* sourceCode = NULL;
	status_t error = fTeam->DebugInfo()->DisassembleFunction(fFunctionInstance,
		sourceCode);

	// set the result
	locker.Lock();
	if (error == B_OK) {
		if (fFunctionInstance->SourceCodeState() == FUNCTION_SOURCE_LOADING) {
			fFunctionInstance->SetSourceCode(sourceCode,
				FUNCTION_SOURCE_LOADED);
			sourceCode->ReleaseReference();
		}
	} else
		fFunctionInstance->SetSourceCode(NULL, FUNCTION_SOURCE_UNAVAILABLE);

	return error;
}
Exemplo n.º 3
0
status_t
TeamDebugInfo::AddImageDebugInfo(ImageDebugInfo* imageDebugInfo)
{
	AutoLocker<BLocker> locker(fLock);
		// We have both locks now, so that for read-only access either lock
		// suffices.

	if (!fImages.AddItem(imageDebugInfo))
		return B_NO_MEMORY;

	// Match all of the image debug info's functions instances with functions.
	BObjectList<SourceFileEntry> sourceFileEntries;
	for (int32 i = 0;
		FunctionInstance* instance = imageDebugInfo->FunctionAt(i); i++) {
		// lookup the function or create it, if it doesn't exist yet
		Function* function = fFunctions->Lookup(instance);
		if (function != NULL) {
// TODO: Also update possible user breakpoints in this function!
			function->AddInstance(instance);
			instance->SetFunction(function);

			// The new image debug info might have additional information about
			// the source file of the function, so remember the source file
			// entry.
			if (LocatableFile* sourceFile = function->SourceFile()) {
				SourceFileEntry* entry = fSourceFiles->Lookup(sourceFile);
				if (entry != NULL && entry->GetSourceCode() != NULL)
					sourceFileEntries.AddItem(entry);
			}
		} else {
			function = new(std::nothrow) Function;
			if (function == NULL) {
				RemoveImageDebugInfo(imageDebugInfo);
				return B_NO_MEMORY;
			}
			function->AddInstance(instance);
			instance->SetFunction(function);

			status_t error = _AddFunction(function);
				// Insert after adding the instance. Otherwise the function
				// wouldn't be hashable/comparable.
			if (error != B_OK) {
				function->RemoveInstance(instance);
				instance->SetFunction(NULL);
				RemoveImageDebugInfo(imageDebugInfo);
				return error;
			}
		}
	}

	// update the source files the image debug info knows about
	for (int32 i = 0; SourceFileEntry* entry = sourceFileEntries.ItemAt(i);
			i++) {
		FileSourceCode* sourceCode = entry->GetSourceCode();
		sourceCode->Lock();
		if (imageDebugInfo->AddSourceCodeInfo(entry->SourceFile(),
				sourceCode) == B_OK) {
			// TODO: Notify interesting parties! Iterate through all functions
			// for this source file?
		}
		sourceCode->Unlock();
	}

	return B_OK;
}
Exemplo n.º 4
0
status_t
TeamDebugInfo::LoadSourceCode(LocatableFile* file, FileSourceCode*& _sourceCode)
{
	AutoLocker<BLocker> locker(fLock);

	// If we don't know the source file, there's nothing we can do.
	SourceFileEntry* entry = fSourceFiles->Lookup(file);
	if (entry == NULL)
		return B_ENTRY_NOT_FOUND;

	// the source might already be loaded
	FileSourceCode* sourceCode = entry->GetSourceCode();
	if (sourceCode != NULL) {
		sourceCode->AcquireReference();
		_sourceCode = sourceCode;
		return B_OK;
	}

	// get the source language from some function's image debug info
	Function* function = entry->FunctionAt(0);
	if (function == NULL)
		return B_ENTRY_NOT_FOUND;

	FunctionDebugInfo* functionDebugInfo
		= function->FirstInstance()->GetFunctionDebugInfo();
	SourceLanguage* language;
	status_t error = functionDebugInfo->GetSpecificImageDebugInfo()
		->GetSourceLanguage(functionDebugInfo, language);
	if (error != B_OK)
		return error;
	BReference<SourceLanguage> languageReference(language, true);

	// no source code yet
//	locker.Unlock();
	// TODO: It would be nice to unlock here, but we need to iterate through
	// the images below. We could clone the list, acquire references, and
	// unlock. Then we have to compare the list with the then current list when
	// we're done loading.

	// load the source file
	SourceFile* sourceFile;
	error = fFileManager->LoadSourceFile(file, sourceFile);
	if (error != B_OK)
		return error;

	// create the source code
	sourceCode = new(std::nothrow) FileSourceCode(file, sourceFile, language);
	sourceFile->ReleaseReference();
	if (sourceCode == NULL)
		return B_NO_MEMORY;
	BReference<FileSourceCode> sourceCodeReference(sourceCode, true);

	error = sourceCode->Init();
	if (error != B_OK)
		return error;

	// Iterate through all images that know the source file and ask them to add
	// information.
	bool anyInfo = false;
	for (int32 i = 0; ImageDebugInfo* imageDebugInfo = fImages.ItemAt(i); i++)
		anyInfo |= imageDebugInfo->AddSourceCodeInfo(file, sourceCode) == B_OK;

	if (!anyInfo)
		return B_ENTRY_NOT_FOUND;

	entry->SetSourceCode(sourceCode);

	_sourceCode = sourceCodeReference.Detach();
	return B_OK;
}