LocatableFile* _GetFile(const BString& directoryPath, const BString& name) { // if already known return the file LocatableEntry* entry = _LookupEntry(EntryPath(directoryPath, name)); if (entry != NULL) { LocatableFile* file = dynamic_cast<LocatableFile*>(entry); if (file == NULL) return NULL; if (file->AcquireReference() == 0) { fEntries.Remove(file); fDeadEntries.Insert(file); } else return file; } // no such file yet -- create it BString normalizedDirPath; _NormalizePath(directoryPath, normalizedDirPath); LocatableDirectory* directory = _GetDirectory(normalizedDirPath); if (directory == NULL) return NULL; LocatableFile* file = new(std::nothrow) LocatableFile(this, directory, name); if (file == NULL) { directory->ReleaseReference(); return NULL; } directory->AddEntry(file); fEntries.Insert(file); return file; }
void TeamWindow::_UpdateSourcePathState() { LocatableFile* sourceFile = NULL; BString sourceText = "Source file unavailable."; BString truncatedText; if (fActiveSourceCode != NULL) { sourceFile = fActiveFunction->GetFunctionDebugInfo()->SourceFile(); if (sourceFile != NULL && !sourceFile->GetLocatedPath(sourceText)) sourceFile->GetPath(sourceText); if (fActiveFunction->GetFunction()->SourceCodeState() != FUNCTION_SOURCE_NOT_LOADED && fActiveSourceCode->GetSourceFile() == NULL && sourceFile != NULL) { sourceText.Prepend("Click to locate source file '"); sourceText += "'"; truncatedText = sourceText; fSourcePathView->TruncateString(&truncatedText, B_TRUNCATE_MIDDLE, fSourcePathView->Bounds().Width()); } else if (sourceFile != NULL) sourceText.Prepend("File: "); } if (!truncatedText.IsEmpty() && truncatedText != sourceText) { fSourcePathView->SetToolTip(sourceText); fSourcePathView->SetText(truncatedText); } else fSourcePathView->SetText(sourceText); }
LocatableFile* GetFile(const BString& path) { BString directoryPath; BString name; _SplitPath(path, directoryPath, name); LocatableFile* file = _GetFile(directoryPath, name); if (file == NULL) return NULL; // try to auto-locate the file if (LocatableDirectory* directory = file->Parent()) { if (directory->State() == LOCATABLE_ENTRY_UNLOCATED) { // parent not yet located -- try locate with the entry's path BString path; file->GetPath(path); _LocateEntry(file, path, true, true); } else { // parent already located -- locate the entry in the parent BString locatedDirectoryPath; if (directory->GetLocatedPath(locatedDirectoryPath)) _LocateEntryInParentDir(file, locatedDirectoryPath, true); } } return file; }
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; } }
void TeamWindow::_HandleResolveMissingSourceFile(entry_ref& locatedPath) { if (fActiveFunction != NULL) { LocatableFile* sourceFile = fActiveFunction->GetFunctionDebugInfo() ->SourceFile(); if (sourceFile != NULL) { BString sourcePath; BString targetPath; sourceFile->GetPath(sourcePath); BPath path(&locatedPath); targetPath = path.Path(); fListener->SourceEntryLocateRequested(sourcePath, targetPath); fListener->FunctionSourceCodeRequested(fActiveFunction); } } }
void TeamWindow::_HandleSourceCodeChanged() { // If we don't have an active function anymore, the message is obsolete. if (fActiveFunction == NULL) return; // get a reference to the source code AutoLocker< ::Team> locker(fTeam); SourceCode* sourceCode = fActiveFunction->GetFunction()->GetSourceCode(); LocatableFile* sourceFile = NULL; BString sourceText; BString truncatedText; if (sourceCode == NULL) sourceCode = fActiveFunction->GetSourceCode(); if (sourceCode != NULL) sourceFile = fActiveFunction->GetFunctionDebugInfo()->SourceFile(); if (sourceFile != NULL && !sourceFile->GetLocatedPath(sourceText)) sourceFile->GetPath(sourceText); if (sourceCode != NULL && sourceCode->GetSourceFile() == NULL && sourceFile != NULL) { sourceText.Prepend("Click to locate source file '"); sourceText += "'"; truncatedText = sourceText; fSourcePathView->TruncateString(&truncatedText, B_TRUNCATE_MIDDLE, fSourcePathView->Bounds().Width()); if (sourceText != truncatedText) fSourcePathView->SetToolTip(sourceText.String()); fSourcePathView->SetText(truncatedText.String()); } else if (sourceFile != NULL) { sourceText.Prepend("File: "); fSourcePathView->SetText(sourceText.String()); } else fSourcePathView->SetText("Source file unavailable."); BReference<SourceCode> sourceCodeReference(sourceCode); locker.Unlock(); _SetActiveSourceCode(sourceCode); }
void TeamWindow::_HandleResolveMissingSourceFile(entry_ref& locatedPath) { if (fActiveFunction != NULL) { LocatableFile* sourceFile = fActiveFunction->GetFunctionDebugInfo() ->SourceFile(); if (sourceFile != NULL) { BString sourcePath; sourceFile->GetPath(sourcePath); BString sourceFileName(sourcePath); int32 index = sourcePath.FindLast('/'); if (index >= 0) sourceFileName.Remove(0, index + 1); BPath targetFilePath(&locatedPath); if (targetFilePath.InitCheck() != B_OK) return; if (strcmp(sourceFileName.String(), targetFilePath.Leaf()) != 0) { BString message; message.SetToFormat("The names of source file '%s' and located" " file '%s' differ. Use file anyway?", sourceFileName.String(), targetFilePath.Leaf()); BAlert* alert = new(std::nothrow) BAlert( "Source path mismatch", message.String(), "Cancel", "Use"); if (alert == NULL) return; int32 choice = alert->Go(); if (choice <= 0) return; } fListener->SourceEntryLocateRequested(sourcePath, targetFilePath.Path()); fListener->FunctionSourceCodeRequested(fActiveFunction); } } }
status_t DebugReportGenerator::_DumpDebuggedThreadInfo(BFile& _output, ::Thread* thread) { AutoLocker< ::Team> locker; if (thread->State() != THREAD_STATE_STOPPED) return B_OK; status_t error; StackTrace* trace = NULL; for (;;) { trace = thread->GetStackTrace(); if (trace != NULL) break; locker.Unlock(); fTraceWaitingThread = thread; do { error = acquire_sem(fTeamDataSem); } while (error == B_INTERRUPTED); if (error != B_OK) break; locker.Lock(); } BString data("\t\tFrame\t\tIP\t\t\tFunction Name\n"); WRITE_AND_CHECK(_output, data); data = "\t\t-----------------------------------------------\n"; WRITE_AND_CHECK(_output, data); for (int32 i = 0; StackFrame* frame = trace->FrameAt(i); i++) { char functionName[512]; BString sourcePath; target_addr_t ip = frame->InstructionPointer(); FunctionInstance* functionInstance; Statement* statement; if (fTeam->GetStatementAtAddress(ip, functionInstance, statement) == B_OK) { BReference<Statement> statementReference(statement, true); int32 line = statement->StartSourceLocation().Line(); LocatableFile* sourceFile = functionInstance->GetFunction() ->SourceFile(); if (sourceFile != NULL) { sourceFile->GetPath(sourcePath); sourcePath.SetToFormat("(%s:%" B_PRId32 ")", sourcePath.String(), line); } } data.SetToFormat("\t\t%#08" B_PRIx64 "\t%#08" B_PRIx64 "\t%s %s\n", frame->FrameAddress(), ip, UiUtils::FunctionNameForFrame( frame, functionName, sizeof(functionName)), sourcePath.String()); WRITE_AND_CHECK(_output, data); // only dump the topmost frame if (i == 0) { locker.Unlock(); error = _DumpFunctionDisassembly(_output, frame->InstructionPointer()); if (error != B_OK) return error; error = _DumpStackFrameMemory(_output, thread->GetCpuState(), frame->FrameAddress(), thread->GetTeam()->GetArchitecture() ->StackGrowthDirection()); if (error != B_OK) return error; locker.Lock(); } if (frame->CountParameters() == 0 && frame->CountLocalVariables() == 0) continue; data = "\t\t\tVariables:\n"; WRITE_AND_CHECK(_output, data); error = fNodeManager->SetStackFrame(thread, frame); if (error != B_OK) continue; ValueNodeContainer* container = fNodeManager->GetContainer(); AutoLocker<ValueNodeContainer> containerLocker(container); for (int32 i = 0; i < container->CountChildren(); i++) { data.Truncate(0L); ValueNodeChild* child = container->ChildAt(i); containerLocker.Unlock(); _ResolveValueIfNeeded(child->Node(), frame, 1); containerLocker.Lock(); UiUtils::PrintValueNodeGraph(data, child, 3, 1); WRITE_AND_CHECK(_output, data); } data = "\n"; WRITE_AND_CHECK(_output, data); } data = "\n\t\tRegisters:\n"; WRITE_AND_CHECK(_output, data); CpuState* state = thread->GetCpuState(); BVariant value; const Register* reg = NULL; for (int32 i = 0; i < fArchitecture->CountRegisters(); i++) { reg = fArchitecture->Registers() + i; state->GetRegisterValue(reg, value); if (reg->Format() == REGISTER_FORMAT_SIMD) { data.SetToFormat("\t\t\t%5s:\t%s\n", reg->Name(), UiUtils::FormatSIMDValue(value, reg->BitSize(), SIMD_RENDER_FORMAT_INT16, data).String()); } else { char buffer[64]; data.SetToFormat("\t\t\t%5s:\t%s\n", reg->Name(), UiUtils::VariantToString(value, buffer, sizeof(buffer))); } WRITE_AND_CHECK(_output, data); } return B_OK; }