static void add_boot_volume_item(Menu* menu, Directory* volume, const char* name) { BReference<PackageVolumeInfo> volumeInfo; PackageVolumeState* selectedState = NULL; if (volume == sBootVolume->RootDirectory()) { volumeInfo.SetTo(sBootVolume->GetPackageVolumeInfo()); selectedState = sBootVolume->GetPackageVolumeState(); } else { volumeInfo.SetTo(new(std::nothrow) PackageVolumeInfo); if (volumeInfo->SetTo(volume, "system/packages") == B_OK) selectedState = volumeInfo->States().Head(); else volumeInfo.Unset(); } BootVolumeMenuItem* item = new(nothrow) BootVolumeMenuItem(name); menu->AddItem(item); Menu* subMenu = NULL; if (volumeInfo != NULL) { subMenu = new(std::nothrow) Menu(CHOICE_MENU, "Select Haiku version"); for (PackageVolumeStateList::ConstIterator it = volumeInfo->States().GetIterator(); PackageVolumeState* state = it.Next();) { PackageVolumeStateMenuItem* stateItem = new(nothrow) PackageVolumeStateMenuItem(state->DisplayName(), volumeInfo, state); subMenu->AddItem(stateItem); stateItem->SetTarget(user_menu_boot_volume_state); stateItem->SetData(volume); if (state == selectedState) { stateItem->SetMarked(true); stateItem->Select(true); item->UpdateStateName(stateItem->VolumeState()); } } } if (subMenu != NULL && subMenu->CountItems() > 1) { item->SetSubmenu(subMenu); } else { delete subMenu; item->SetTarget(user_menu_boot_volume); item->SetData(volume); } if (volume == sBootVolume->RootDirectory()) { item->SetMarked(true); item->Select(true); } }
void TeamWindow::_SetActiveImage(Image* image) { if (image == fActiveImage) return; if (fActiveImage != NULL) fActiveImage->ReleaseReference(); fActiveImage = image; AutoLocker< ::Team> locker(fTeam); ImageDebugInfo* imageDebugInfo = NULL; BReference<ImageDebugInfo> imageDebugInfoReference; if (fActiveImage != NULL) { fActiveImage->AcquireReference(); imageDebugInfo = fActiveImage->GetImageDebugInfo(); imageDebugInfoReference.SetTo(imageDebugInfo); // If the debug info is not loaded yet, request it. if (fActiveImage->ImageDebugInfoState() == IMAGE_DEBUG_INFO_NOT_LOADED) fListener->ImageDebugInfoRequested(fActiveImage); } locker.Unlock(); fImageListView->SetImage(fActiveImage); fImageFunctionsView->SetImageDebugInfo(imageDebugInfo); }
status_t WriterImplBase::InitHeapReader(size_t headerSize) { // allocate the compression/decompression algorithm CompressionAlgorithmOwner* compressionAlgorithm = NULL; BReference<CompressionAlgorithmOwner> compressionAlgorithmReference; DecompressionAlgorithmOwner* decompressionAlgorithm = NULL; BReference<DecompressionAlgorithmOwner> decompressionAlgorithmReference; switch (fParameters.Compression()) { case B_HPKG_COMPRESSION_NONE: break; case B_HPKG_COMPRESSION_ZLIB: compressionAlgorithm = CompressionAlgorithmOwner::Create( new(std::nothrow) BZlibCompressionAlgorithm, new(std::nothrow) BZlibCompressionParameters( fParameters.CompressionLevel())); compressionAlgorithmReference.SetTo(compressionAlgorithm, true); decompressionAlgorithm = DecompressionAlgorithmOwner::Create( new(std::nothrow) BZlibCompressionAlgorithm, new(std::nothrow) BZlibDecompressionParameters); decompressionAlgorithmReference.SetTo(decompressionAlgorithm, true); if (compressionAlgorithm == NULL || compressionAlgorithm->algorithm == NULL || compressionAlgorithm->parameters == NULL || decompressionAlgorithm == NULL || decompressionAlgorithm->algorithm == NULL || decompressionAlgorithm->parameters == NULL) { throw std::bad_alloc(); } break; default: fErrorOutput->PrintError("Error: Invalid heap compression\n"); return B_BAD_VALUE; } // create heap writer fHeapWriter = new PackageFileHeapWriter(fErrorOutput, fFile, headerSize, compressionAlgorithm, decompressionAlgorithm); fHeapWriter->Init(); return B_OK; }
void SATGroup::_SpawnNewGroup(const WindowAreaList& newGroup) { STRACE_SAT("SATGroup::_SpawnNewGroup\n"); SATGroup* group = new (std::nothrow)SATGroup; if (!group) return; BReference<SATGroup> groupRef; groupRef.SetTo(group, true); for (int i = 0; i < newGroup.CountItems(); i++) newGroup.ItemAt(i)->PropagateToGroup(group); _EnsureGroupIsOnScreen(group); }
void InspectorWindow::ExpressionEvaluated(ExpressionInfo* info, status_t result, ExpressionResult* value) { BMessage message(MSG_EXPRESSION_EVALUATED); message.AddInt32("result", result); BReference<ExpressionResult> reference; if (value != NULL) { reference.SetTo(value); message.AddPointer("value", value); } if (PostMessage(&message) == B_OK) reference.Detach(); }
void SATWindow::_InitGroup() { ASSERT(fGroupCookie == &fOwnGroupCookie); ASSERT(fOwnGroupCookie.GetGroup() == NULL); STRACE_SAT("SATWindow::_InitGroup %s\n", fWindow->Title()); SATGroup* group = new (std::nothrow)SATGroup; if (!group) return; BReference<SATGroup> groupRef; groupRef.SetTo(group, true); /* AddWindow also will trigger the window to hold a reference on the new group. */ if (!groupRef->AddWindow(this, NULL, NULL, NULL, NULL)) STRACE_SAT("SATWindow::_InitGroup(): adding window to group failed\n"); }
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; } } }
void TeamWindow::_UpdateCpuState() { // get the CPU state CpuState* cpuState = NULL; BReference<CpuState> cpuStateReference; // hold a reference until the register view has one if (fActiveThread != NULL) { // Get the CPU state from the active stack frame or the thread directly. if (fActiveStackFrame == NULL) { AutoLocker< ::Team> locker(fTeam); cpuState = fActiveThread->GetCpuState(); cpuStateReference.SetTo(cpuState); locker.Unlock(); } else cpuState = fActiveStackFrame->GetCpuState(); } fRegistersView->SetCpuState(cpuState); }
status_t DwarfType::CreateDerivedArrayType(int64 lowerBound, int64 elementCount, bool extendExisting, ArrayType*& _resultType) { DwarfArrayType* resultType = NULL; BReference<DwarfType> baseTypeReference; if (extendExisting) resultType = dynamic_cast<DwarfArrayType*>(this); if (resultType == NULL) { resultType = new(std::nothrow) DwarfArrayType(fTypeContext, fName, NULL, this); baseTypeReference.SetTo(resultType, true); } if (resultType == NULL) return B_NO_MEMORY; DwarfSubrangeType* subrangeType = new(std::nothrow) DwarfSubrangeType( fTypeContext, fName, NULL, resultType, BVariant(lowerBound), BVariant(lowerBound + elementCount - 1)); if (subrangeType == NULL) return B_NO_MEMORY; BReference<DwarfSubrangeType> subrangeReference(subrangeType, true); DwarfArrayDimension* dimension = new(std::nothrow) DwarfArrayDimension( subrangeType); if (dimension == NULL) return B_NO_MEMORY; BReference<DwarfArrayDimension> dimensionReference(dimension, true); if (!resultType->AddDimension(dimension)) return B_NO_MEMORY; baseTypeReference.Detach(); _resultType = resultType; return B_OK; }
status_t DwarfImageDebugInfo::GetType(GlobalTypeCache* cache, const BString& name, const TypeLookupConstraints& constraints, Type*& _type) { int32 registerCount = fArchitecture->CountRegisters(); const Register* registers = fArchitecture->Registers(); // get the DWARF -> architecture register map RegisterMap* fromDwarfMap; status_t error = fArchitecture->GetDwarfRegisterMaps(NULL, &fromDwarfMap); if (error != B_OK) return error; BReference<RegisterMap> fromDwarfMapReference(fromDwarfMap, true); // create the target interface BasicTargetInterface *inputInterface = new(std::nothrow) BasicTargetInterface(registers, registerCount, fromDwarfMap, fArchitecture, fDebuggerInterface); if (inputInterface == NULL) return B_NO_MEMORY; BReference<BasicTargetInterface> inputInterfaceReference(inputInterface, true); // iterate through all compilation units for (int32 i = 0; CompilationUnit* unit = fFile->CompilationUnitAt(i); i++) { DwarfTypeContext* typeContext = NULL; BReference<DwarfTypeContext> typeContextReference; // iterate through all types of the compilation unit for (DebugInfoEntryList::ConstIterator it = unit->UnitEntry()->Types().GetIterator(); DIEType* typeEntry = dynamic_cast<DIEType*>(it.Next());) { if (typeEntry->IsDeclaration()) continue; if (constraints.HasTypeKind()) { if (dwarf_tag_to_type_kind(typeEntry->Tag()) != constraints.TypeKind()) continue; if (!_EvaluateBaseTypeConstraints(typeEntry, constraints)) continue; } if (constraints.HasSubtypeKind() && dwarf_tag_to_subtype_kind(typeEntry->Tag()) != constraints.SubtypeKind()) continue; BString typeEntryName; DwarfUtils::GetFullyQualifiedDIEName(typeEntry, typeEntryName); if (typeEntryName != name) continue; // The name matches and the entry is not just a declaration -- // create the type. First create the type context lazily. if (typeContext == NULL) { typeContext = new(std::nothrow) DwarfTypeContext(fArchitecture, fImageInfo.ImageID(), fFile, unit, NULL, 0, 0, fRelocationDelta, inputInterface, fromDwarfMap); if (typeContext == NULL) return B_NO_MEMORY; typeContextReference.SetTo(typeContext, true); } // create the type DwarfType* type; DwarfTypeFactory typeFactory(typeContext, fTypeLookup, cache); error = typeFactory.CreateType(typeEntry, type); if (error != B_OK) continue; _type = type; return B_OK; } } return B_ENTRY_NOT_FOUND; }
status_t DwarfImageDebugInfo::CreateFrame(Image* image, FunctionInstance* functionInstance, CpuState* cpuState, bool getFullFrameInfo, ReturnValueInfoList* returnValueInfos, StackFrame*& _frame, CpuState*& _previousCpuState) { DwarfFunctionDebugInfo* function = dynamic_cast<DwarfFunctionDebugInfo*>( functionInstance->GetFunctionDebugInfo()); FunctionID* functionID = functionInstance->GetFunctionID(); BReference<FunctionID> functionIDReference; if (functionID != NULL) functionIDReference.SetTo(functionID, true); DIESubprogram* entry = function != NULL ? function->SubprogramEntry() : NULL; TRACE_CFI("DwarfImageDebugInfo::CreateFrame(): subprogram DIE: %p, " "function: %s\n", entry, functionID->FunctionName().String()); int32 registerCount = fArchitecture->CountRegisters(); const Register* registers = fArchitecture->Registers(); // get the DWARF <-> architecture register maps RegisterMap* toDwarfMap; RegisterMap* fromDwarfMap; status_t error = fArchitecture->GetDwarfRegisterMaps(&toDwarfMap, &fromDwarfMap); if (error != B_OK) return error; BReference<RegisterMap> toDwarfMapReference(toDwarfMap, true); BReference<RegisterMap> fromDwarfMapReference(fromDwarfMap, true); // create a clean CPU state for the previous frame CpuState* previousCpuState; error = fArchitecture->CreateCpuState(previousCpuState); if (error != B_OK) return error; BReference<CpuState> previousCpuStateReference(previousCpuState, true); // create the target interfaces UnwindTargetInterface* inputInterface = new(std::nothrow) UnwindTargetInterface(registers, registerCount, fromDwarfMap, toDwarfMap, cpuState, fArchitecture, fDebuggerInterface); if (inputInterface == NULL) return B_NO_MEMORY; BReference<UnwindTargetInterface> inputInterfaceReference(inputInterface, true); UnwindTargetInterface* outputInterface = new(std::nothrow) UnwindTargetInterface(registers, registerCount, fromDwarfMap, toDwarfMap, previousCpuState, fArchitecture, fDebuggerInterface); if (outputInterface == NULL) return B_NO_MEMORY; BReference<UnwindTargetInterface> outputInterfaceReference(outputInterface, true); // do the unwinding target_addr_t instructionPointer = cpuState->InstructionPointer() - fRelocationDelta; target_addr_t framePointer; CompilationUnit* unit = function != NULL ? function->GetCompilationUnit() : NULL; error = fFile->UnwindCallFrame(unit, fArchitecture->AddressSize(), entry, instructionPointer, inputInterface, outputInterface, framePointer); if (error != B_OK) { TRACE_CFI("Failed to unwind call frame: %s\n", strerror(error)); return B_UNSUPPORTED; } TRACE_CFI_ONLY( TRACE_CFI("unwound registers:\n"); for (int32 i = 0; i < registerCount; i++) { const Register* reg = registers + i; BVariant value; if (previousCpuState->GetRegisterValue(reg, value)) { TRACE_CFI(" %3s: %#" B_PRIx64 "\n", reg->Name(), value.ToUInt64()); } else TRACE_CFI(" %3s: undefined\n", reg->Name()); } )
void InspectorWindow::MessageReceived(BMessage* message) { switch (message->what) { case MSG_THREAD_STATE_CHANGED: { ::Thread* thread; if (message->FindPointer("thread", reinterpret_cast<void**>(&thread)) != B_OK) { break; } BReference< ::Thread> threadReference(thread, true); if (thread->State() == THREAD_STATE_STOPPED) { if (fCurrentBlock != NULL) { _SetCurrentBlock(NULL); _SetToAddress(fCurrentAddress); } } break; } case MSG_INSPECT_ADDRESS: { target_addr_t address = 0; if (message->FindUInt64("address", &address) != B_OK) { if (fAddressInput->TextView()->TextLength() == 0) break; fExpressionInfo->SetTo(fAddressInput->Text()); fListener->ExpressionEvaluationRequested(fLanguage, fExpressionInfo); } else _SetToAddress(address); break; } case MSG_EXPRESSION_EVALUATED: { BString errorMessage; BReference<ExpressionResult> reference; ExpressionResult* value = NULL; if (message->FindPointer("value", reinterpret_cast<void**>(&value)) == B_OK) { reference.SetTo(value, true); if (value->Kind() == EXPRESSION_RESULT_KIND_PRIMITIVE) { Value* primitive = value->PrimitiveValue(); BVariant variantValue; primitive->ToVariant(variantValue); if (variantValue.Type() == B_STRING_TYPE) { errorMessage.SetTo(variantValue.ToString()); } else { _SetToAddress(variantValue.ToUInt64()); break; } } } else { status_t result = message->FindInt32("result"); errorMessage.SetToFormat("Failed to evaluate expression: %s", strerror(result)); } BAlert* alert = new(std::nothrow) BAlert("Inspect Address", errorMessage.String(), "Close"); if (alert != NULL) alert->Go(); break; } case MSG_NAVIGATE_PREVIOUS_BLOCK: case MSG_NAVIGATE_NEXT_BLOCK: { if (fCurrentBlock != NULL) { target_addr_t address = fCurrentBlock->BaseAddress(); if (message->what == MSG_NAVIGATE_PREVIOUS_BLOCK) address -= fCurrentBlock->Size(); else address += fCurrentBlock->Size(); BMessage setMessage(MSG_INSPECT_ADDRESS); setMessage.AddUInt64("address", address); PostMessage(&setMessage); } break; } case MSG_MEMORY_BLOCK_RETRIEVED: { TeamMemoryBlock* block = NULL; status_t result; if (message->FindPointer("block", reinterpret_cast<void **>(&block)) != B_OK || message->FindInt32("result", &result) != B_OK) { break; } if (result == B_OK) { _SetCurrentBlock(block); fPreviousBlockButton->SetEnabled(true); fNextBlockButton->SetEnabled(true); } else { BString errorMessage; errorMessage.SetToFormat("Unable to read address 0x%" B_PRIx64 ": %s", block->BaseAddress(), strerror(result)); BAlert* alert = new(std::nothrow) BAlert("Inspect address", errorMessage.String(), "Close"); if (alert == NULL) break; alert->Go(NULL); block->ReleaseReference(); } break; } case MSG_EDIT_CURRENT_BLOCK: { _SetEditMode(true); break; } case MSG_MEMORY_DATA_CHANGED: { if (fCurrentBlock == NULL) break; target_addr_t address; if (message->FindUInt64("address", &address) == B_OK && address >= fCurrentBlock->BaseAddress() && address < fCurrentBlock->BaseAddress() + fCurrentBlock->Size()) { fCurrentBlock->Invalidate(); _SetEditMode(false); fListener->InspectRequested(address, this); } break; } case MSG_COMMIT_MODIFIED_BLOCK: { // TODO: this could conceivably be extended to detect the // individual modified regions and only write those back. // That would require potentially submitting multiple separate // write requests, and thus require tracking all the writes being // waited upon for completion. fListener->MemoryWriteRequested(fCurrentBlock->BaseAddress(), fMemoryView->GetEditedData(), fCurrentBlock->Size()); break; } case MSG_REVERT_MODIFIED_BLOCK: { _SetEditMode(false); break; } default: { BWindow::MessageReceived(message); break; } } }
status_t BListValueNode::CreateChildrenInRange(TeamTypeInformation* info, int32 lowIndex, int32 highIndex) { if (fLocationResolutionState != B_OK) return fLocationResolutionState; if (lowIndex < 0) lowIndex = 0; if (highIndex >= fItemCount) highIndex = fItemCount - 1; if (!fCountChildCreated && fItemCountType != NULL) { BListItemCountNodeChild* countChild = new(std::nothrow) BListItemCountNodeChild(fItemCountLocation, this, fItemCountType); if (countChild == NULL) return B_NO_MEMORY; fCountChildCreated = true; countChild->SetContainer(fContainer); fChildren.AddItem(countChild); } BReference<Type> addressTypeRef; Type* type = NULL; CompoundType* objectType = dynamic_cast<CompoundType*>(fType); if (objectType->CountTemplateParameters() != 0) { AddressType* addressType = NULL; status_t result = objectType->TemplateParameterAt(0)->GetType() ->CreateDerivedAddressType(DERIVED_TYPE_POINTER, addressType); if (result != B_OK) return result; type = addressType; addressTypeRef.SetTo(type, true); } else { BString typeName; TypeLookupConstraints constraints; constraints.SetTypeKind(TYPE_ADDRESS); constraints.SetBaseTypeName("void"); status_t result = info->LookupTypeByName(typeName, constraints, type); if (result != B_OK) return result; } for (int32 i = lowIndex; i <= highIndex; i++) { BListElementNodeChild* child = new(std::nothrow) BListElementNodeChild(this, i, type); if (child == NULL) return B_NO_MEMORY; child->SetContainer(fContainer); fChildren.AddItem(child); } fChildrenCreated = true; if (fContainer != NULL) fContainer->NotifyValueNodeChildrenCreated(this); return B_OK; }
void TeamWindow::_SetActiveFunction(FunctionInstance* functionInstance) { if (functionInstance == fActiveFunction) return; AutoLocker< ::Team> locker(fTeam); if (fActiveFunction != NULL) { fActiveFunction->GetFunction()->RemoveListener(this); fActiveFunction->ReleaseReference(); } // to avoid listener feedback problems, first unset the active function and // set the new image, if any locker.Unlock(); fActiveFunction = NULL; if (functionInstance != NULL) _SetActiveImage(fTeam->ImageByAddress(functionInstance->Address())); fActiveFunction = functionInstance; locker.Lock(); SourceCode* sourceCode = NULL; BReference<SourceCode> sourceCodeReference; if (fActiveFunction != NULL) { fActiveFunction->AcquireReference(); fActiveFunction->GetFunction()->AddListener(this); Function* function = fActiveFunction->GetFunction(); sourceCode = function->GetSourceCode(); if (sourceCode == NULL) sourceCode = fActiveFunction->GetSourceCode(); sourceCodeReference.SetTo(sourceCode); // If the source code is not loaded yet, request it. if (function->SourceCodeState() == FUNCTION_SOURCE_NOT_LOADED) fListener->FunctionSourceCodeRequested(fActiveFunction); } locker.Unlock(); _SetActiveSourceCode(sourceCode); fImageFunctionsView->SetFunction(fActiveFunction); locker.Lock(); // look if our current stack trace has a frame matching the selected // function. If so, set it to match. StackFrame* matchingFrame = NULL; BReference<StackFrame> frameRef; if (fActiveStackTrace != NULL) { for (int32 i = 0; i < fActiveStackTrace->CountFrames(); i++) { StackFrame* frame = fActiveStackTrace->FrameAt(i); if (frame->Function() == fActiveFunction) { matchingFrame = frame; frameRef.SetTo(frame); break; } } } locker.Unlock(); if (matchingFrame != NULL) _SetActiveStackFrame(matchingFrame); }
status_t CLanguageFamily::ParseTypeExpression(const BString& expression, TeamTypeInformation* info, Type*& _resultType) const { status_t result = B_OK; Type* baseType = NULL; BString parsedName = expression; BString baseTypeName; BString arraySpecifier; parsedName.RemoveAll(" "); int32 modifierIndex = -1; modifierIndex = parsedName.FindFirst('*'); if (modifierIndex == -1) modifierIndex = parsedName.FindFirst('&'); if (modifierIndex == -1) modifierIndex = parsedName.FindFirst('['); if (modifierIndex == -1) modifierIndex = parsedName.Length(); parsedName.MoveInto(baseTypeName, 0, modifierIndex); modifierIndex = parsedName.FindFirst('['); if (modifierIndex >= 0) { parsedName.MoveInto(arraySpecifier, modifierIndex, parsedName.Length() - modifierIndex); } result = info->LookupTypeByName(baseTypeName, TypeLookupConstraints(), baseType); if (result != B_OK) return result; BReference<Type> typeRef; typeRef.SetTo(baseType, true); if (!parsedName.IsEmpty()) { AddressType* derivedType = NULL; // walk the list of modifiers trying to add each. for (int32 i = 0; i < parsedName.Length(); i++) { if (!IsModifierValid(parsedName[i])) return B_BAD_VALUE; address_type_kind typeKind; switch (parsedName[i]) { case '*': { typeKind = DERIVED_TYPE_POINTER; break; } case '&': { typeKind = DERIVED_TYPE_REFERENCE; break; } default: { return B_BAD_VALUE; } } if (derivedType == NULL) { result = baseType->CreateDerivedAddressType(typeKind, derivedType); } else { result = derivedType->CreateDerivedAddressType(typeKind, derivedType); } if (result != B_OK) return result; typeRef.SetTo(derivedType, true); } _resultType = derivedType; } else _resultType = baseType; if (!arraySpecifier.IsEmpty()) { ArrayType* arrayType = NULL; int32 startIndex = 1; do { int32 size = strtoul(arraySpecifier.String() + startIndex, NULL, 10); if (size < 0) return B_ERROR; if (arrayType == NULL) { result = _resultType->CreateDerivedArrayType(0, size, true, arrayType); } else { result = arrayType->CreateDerivedArrayType(0, size, true, arrayType); } if (result != B_OK) return result; typeRef.SetTo(arrayType, true); startIndex = arraySpecifier.FindFirst('[', startIndex + 1); } while (startIndex >= 0); // since a C/C++ array is essentially pointer math, // the resulting array has to be wrapped in a pointer to // ensure the element addresses wind up being against the // correct address. AddressType* addressType = NULL; result = arrayType->CreateDerivedAddressType(DERIVED_TYPE_POINTER, addressType); if (result != B_OK) return result; _resultType = addressType; } typeRef.Detach(); return result; }
status_t SATGroup::RestoreGroup(const BMessage& archive, StackAndTile* sat) { // create new group SATGroup* group = new (std::nothrow)SATGroup; if (!group) return B_NO_MEMORY; BReference<SATGroup> groupRef; groupRef.SetTo(group, true); int32 nHTabs, nVTabs; status_t status; status = archive.FindInt32("htab_count", &nHTabs); if (status != B_OK) return status; status = archive.FindInt32("vtab_count", &nVTabs); if (status != B_OK) return status; vector<BReference<Tab> > tempHTabs; for (int i = 0; i < nHTabs; i++) { BReference<Tab> tab = group->_AddHorizontalTab(); if (!tab) return B_NO_MEMORY; tempHTabs.push_back(tab); } vector<BReference<Tab> > tempVTabs; for (int i = 0; i < nVTabs; i++) { BReference<Tab> tab = group->_AddVerticalTab(); if (!tab) return B_NO_MEMORY; tempVTabs.push_back(tab); } BMessage areaArchive; for (int32 i = 0; archive.FindMessage("area", i, &areaArchive) == B_OK; i++) { uint32 leftTab, rightTab, topTab, bottomTab; if (areaArchive.FindInt32("left_tab", (int32*)&leftTab) != B_OK || areaArchive.FindInt32("right_tab", (int32*)&rightTab) != B_OK || areaArchive.FindInt32("top_tab", (int32*)&topTab) != B_OK || areaArchive.FindInt32("bottom_tab", (int32*)&bottomTab) != B_OK) return B_ERROR; if (leftTab >= tempVTabs.size() || rightTab >= tempVTabs.size()) return B_BAD_VALUE; if (topTab >= tempHTabs.size() || bottomTab >= tempHTabs.size()) return B_BAD_VALUE; Tab* left = tempVTabs[leftTab]; Tab* right = tempVTabs[rightTab]; Tab* top = tempHTabs[topTab]; Tab* bottom = tempHTabs[bottomTab]; // adding windows to area uint64 windowId; SATWindow* prevWindow = NULL; for (int32 i = 0; areaArchive.FindInt64("window", i, (int64*)&windowId) == B_OK; i++) { SATWindow* window = sat->FindSATWindow(windowId); if (!window) continue; if (prevWindow == NULL) { if (!group->AddWindow(window, left, top, right, bottom)) continue; prevWindow = window; } else { if (!prevWindow->StackWindow(window)) continue; prevWindow = window; } } } return B_OK; }
ssize_t UnixEndpoint::Send(const iovec *vecs, size_t vecCount, ancillary_data_container *ancillaryData) { TRACE("[%ld] %p->UnixEndpoint::Send(%p, %ld, %p)\n", find_thread(NULL), this, vecs, vecCount, ancillaryData); bigtime_t timeout = absolute_timeout(socket->send.timeout); if (gStackModule->is_restarted_syscall()) timeout = gStackModule->restore_syscall_restart_timeout(); else gStackModule->store_syscall_restart_timeout(timeout); UnixEndpointLocker locker(this); BReference<UnixEndpoint> peerReference; UnixEndpointLocker peerLocker; status_t error = _LockConnectedEndpoints(locker, peerLocker); if (error != B_OK) RETURN_ERROR(error); UnixEndpoint* peerEndpoint = fPeerEndpoint; peerReference.SetTo(peerEndpoint); // lock the peer's FIFO UnixFifo* peerFifo = peerEndpoint->fReceiveFifo; BReference<UnixFifo> _(peerFifo); UnixFifoLocker fifoLocker(peerFifo); // unlock endpoints locker.Unlock(); peerLocker.Unlock(); ssize_t result = peerFifo->Write(vecs, vecCount, ancillaryData, timeout); // Notify select()ing readers, if we successfully wrote anything. size_t readable = peerFifo->Readable(); bool notifyRead = (error == B_OK && readable > 0 && !peerFifo->IsReadShutdown()); // Notify select()ing writers, if we failed to write anything and there's // still room to write. size_t writable = peerFifo->Writable(); bool notifyWrite = (error != B_OK && writable > 0 && !peerFifo->IsWriteShutdown()); // re-lock our endpoint (unlock FIFO to respect locking order) fifoLocker.Unlock(); locker.Lock(); bool peerLocked = (fPeerEndpoint == peerEndpoint && _LockConnectedEndpoints(locker, peerLocker) == B_OK); // send notifications if (peerLocked && notifyRead) gSocketModule->notify(peerEndpoint->socket, B_SELECT_READ, readable); if (notifyWrite) gSocketModule->notify(socket, B_SELECT_WRITE, writable); switch (result) { case UNIX_FIFO_SHUTDOWN: if (fPeerEndpoint == peerEndpoint && fState == UNIX_ENDPOINT_CONNECTED) { // Orderly write shutdown on our side. // Note: Linux and Solaris also send a SIGPIPE, but according // the send() specification that shouldn't be done. result = EPIPE; } else { // The FD has been closed. result = EBADF; } break; case EPIPE: // The peer closed connection or shutdown its read side. Reward // the caller with a SIGPIPE. if (gStackModule->is_syscall()) send_signal(find_thread(NULL), SIGPIPE); break; case B_TIMED_OUT: // Translate non-blocking timeouts to the correct error code. if (timeout == 0) result = B_WOULD_BLOCK; break; } RETURN_ERROR(result); }
bool UpdateBreakpoint(BreakpointProxy* proxy) { if (fTeam == NULL) { for (int32 i = 0; BreakpointProxy* proxy = fBreakpointProxies.ItemAt(i); i++) { proxy->ReleaseReference(); } fBreakpointProxies.MakeEmpty(); return true; } AutoLocker<Team> locker(fTeam); UserBreakpointList::ConstIterator it = fTeam->UserBreakpoints().GetIterator(); int32 watchpointIndex = 0; UserBreakpoint* newBreakpoint = it.Next(); Watchpoint* newWatchpoint = fTeam->WatchpointAt(watchpointIndex); int32 index = 0; bool remove; // remove no longer existing breakpoints while (BreakpointProxy* oldProxy = fBreakpointProxies.ItemAt(index)) { remove = false; switch (oldProxy->Type()) { case BREAKPOINT_PROXY_TYPE_BREAKPOINT: { UserBreakpoint* breakpoint = oldProxy->GetBreakpoint(); if (breakpoint == newBreakpoint) { if (breakpoint == proxy->GetBreakpoint()) NotifyRowsChanged(index, 1); ++index; newBreakpoint = it.Next(); } else remove = true; } break; case BREAKPOINT_PROXY_TYPE_WATCHPOINT: { Watchpoint* watchpoint = oldProxy->GetWatchpoint(); if (watchpoint == newWatchpoint) { if (watchpoint == proxy->GetWatchpoint()) NotifyRowsChanged(index, 1); ++watchpointIndex; ++index; newWatchpoint = fTeam->WatchpointAt(watchpointIndex); } else remove = true; } break; } if (remove) { // TODO: Not particularly efficient! fBreakpointProxies.RemoveItemAt(index); oldProxy->ReleaseReference(); NotifyRowsRemoved(index, 1); } } // add new breakpoints int32 countBefore = fBreakpointProxies.CountItems(); BreakpointProxy* newProxy = NULL; BReference<BreakpointProxy> proxyReference; while (newBreakpoint != NULL) { newProxy = new(std::nothrow) BreakpointProxy(newBreakpoint, NULL); if (newProxy == NULL) return false; proxyReference.SetTo(newProxy, true); if (!fBreakpointProxies.AddItem(newProxy)) return false; proxyReference.Detach(); newBreakpoint = it.Next(); } // add new watchpoints while (newWatchpoint != NULL) { newProxy = new(std::nothrow) BreakpointProxy(NULL, newWatchpoint); if (newProxy == NULL) return false; proxyReference.SetTo(newProxy, true); if (!fBreakpointProxies.AddItem(newProxy)) return false; proxyReference.Detach(); newWatchpoint = fTeam->WatchpointAt(++watchpointIndex); } int32 count = fBreakpointProxies.CountItems(); if (count > countBefore) NotifyRowsAdded(countBefore, count - countBefore); return true; }
status_t Volume::_AddPackageNode(Directory* directory, PackageNode* packageNode, bool notify, Node*& _node) { bool newNode = false; UnpackingNode* unpackingNode; Node* node = directory->FindChild(packageNode->Name()); PackageNode* oldPackageNode = NULL; if (node != NULL) { unpackingNode = dynamic_cast<UnpackingNode*>(node); if (unpackingNode == NULL) { _node = NULL; return B_OK; } oldPackageNode = unpackingNode->GetPackageNode(); } else { status_t error = _CreateUnpackingNode(packageNode->Mode(), directory, packageNode->Name(), unpackingNode); if (error != B_OK) RETURN_ERROR(error); node = unpackingNode->GetNode(); newNode = true; } BReference<Node> nodeReference(node); NodeWriteLocker nodeWriteLocker(node); BReference<Node> newNodeReference; NodeWriteLocker newNodeWriteLocker; Node* oldNode = NULL; if (!newNode && !S_ISDIR(node->Mode()) && oldPackageNode != NULL && unpackingNode->WillBeFirstPackageNode(packageNode)) { // The package node we're going to add will represent the node, // replacing the current head package node. Since the node isn't a // directory, we must make sure that clients having opened or mapped the // node won't be surprised. So we create a new node and remove the // current one. // create a new node and transfer the package nodes to it UnpackingNode* newUnpackingNode; status_t error = unpackingNode->CloneTransferPackageNodes( fNextNodeID++, newUnpackingNode); if (error != B_OK) RETURN_ERROR(error); // remove the old node _NotifyNodeRemoved(node); _RemoveNodeAndVNode(node); oldNode = node; // add the new node unpackingNode = newUnpackingNode; node = unpackingNode->GetNode(); newNodeReference.SetTo(node); newNodeWriteLocker.SetTo(node, false); directory->AddChild(node); fNodes.Insert(node); newNode = true; } status_t error = unpackingNode->AddPackageNode(packageNode); if (error != B_OK) { // Remove the node, if created before. If the node was created to // replace the previous node, send out notifications instead. if (newNode) { if (oldNode != NULL) { _NotifyNodeAdded(node); if (notify) { notify_entry_removed(ID(), directory->ID(), oldNode->Name(), oldNode->ID()); notify_entry_created(ID(), directory->ID(), node->Name(), node->ID()); } } else _RemoveNode(node); } RETURN_ERROR(error); } if (newNode) { _NotifyNodeAdded(node); } else if (packageNode == unpackingNode->GetPackageNode()) { _NotifyNodeChanged(node, kAllStatFields, OldUnpackingNodeAttributes(oldPackageNode)); } if (notify) { if (newNode) { if (oldNode != NULL) { notify_entry_removed(ID(), directory->ID(), oldNode->Name(), oldNode->ID()); } notify_entry_created(ID(), directory->ID(), node->Name(), node->ID()); } else if (packageNode == unpackingNode->GetPackageNode()) { // The new package node has become the one representing the node. // Send stat changed notification for directories and entry // removed + created notifications for files and symlinks. notify_stat_changed(ID(), node->ID(), kAllStatFields); // TODO: Actually the attributes might change, too! } } _node = node; return B_OK; }
status_t CppLanguage::ParseTypeExpression(const BString &expression, TeamTypeInformation* info, Type*& _resultType) const { status_t result = B_OK; Type* baseType = NULL; BString parsedName = expression; BString baseTypeName; parsedName.RemoveAll(" "); int32 modifierIndex = -1; for (int32 i = parsedName.Length() - 1; i >= 0; i--) { if (parsedName[i] == '*' || parsedName[i] == '&') modifierIndex = i; } if (modifierIndex >= 0) { parsedName.CopyInto(baseTypeName, 0, modifierIndex); parsedName.Remove(0, modifierIndex); } else baseTypeName = parsedName; result = info->LookupTypeByName(baseTypeName, TypeLookupConstraints(), baseType); if (result != B_OK) return result; BReference<Type> typeRef; typeRef.SetTo(baseType, true); if (!parsedName.IsEmpty()) { AddressType* derivedType = NULL; // walk the list of modifiers trying to add each. for (int32 i = 0; i < parsedName.Length(); i++) { address_type_kind typeKind; switch (parsedName[i]) { case '*': { typeKind = DERIVED_TYPE_POINTER; break; } case '&': { typeKind = DERIVED_TYPE_REFERENCE; break; } default: { return B_BAD_VALUE; } } if (derivedType == NULL) { result = baseType->CreateDerivedAddressType(typeKind, derivedType); } else { result = derivedType->CreateDerivedAddressType(typeKind, derivedType); } if (result != B_OK) return result; typeRef.SetTo(derivedType, true); } _resultType = derivedType; } else _resultType = baseType; typeRef.Detach(); return result; }
void Volume::_RemovePackageNode(Directory* directory, PackageNode* packageNode, Node* node, bool notify) { UnpackingNode* unpackingNode = dynamic_cast<UnpackingNode*>(node); if (unpackingNode == NULL) return; BReference<Node> nodeReference(node); NodeWriteLocker nodeWriteLocker(node); PackageNode* headPackageNode = unpackingNode->GetPackageNode(); bool nodeRemoved = false; Node* newNode = NULL; BReference<Node> newNodeReference; NodeWriteLocker newNodeWriteLocker; // If this is the last package node of the node, remove it completely. if (unpackingNode->IsOnlyPackageNode(packageNode)) { // Notify before removing the node. Otherwise the indices might not // find the node anymore. _NotifyNodeRemoved(node); unpackingNode->PrepareForRemoval(); _RemoveNodeAndVNode(node); nodeRemoved = true; } else if (packageNode == headPackageNode) { // The node does at least have one more package node, but the one to be // removed is the head. Unless it's a directory, we replace the node // with a completely new one and let the old one die. This is necessary // to avoid surprises for clients that have opened/mapped the node. if (S_ISDIR(packageNode->Mode())) { unpackingNode->RemovePackageNode(packageNode); _NotifyNodeChanged(node, kAllStatFields, OldUnpackingNodeAttributes(headPackageNode)); } else { // create a new node and transfer the package nodes to it UnpackingNode* newUnpackingNode; status_t error = unpackingNode->CloneTransferPackageNodes( fNextNodeID++, newUnpackingNode); if (error == B_OK) { // remove the package node newUnpackingNode->RemovePackageNode(packageNode); // remove the old node _NotifyNodeRemoved(node); _RemoveNodeAndVNode(node); // add the new node newNode = newUnpackingNode->GetNode(); newNodeReference.SetTo(newNode); newNodeWriteLocker.SetTo(newNode, false); directory->AddChild(newNode); fNodes.Insert(newNode); _NotifyNodeAdded(newNode); } else { // There's nothing we can do. Remove the node completely. _NotifyNodeRemoved(node); unpackingNode->PrepareForRemoval(); _RemoveNodeAndVNode(node); nodeRemoved = true; } } } else { // The package node to remove is not the head of the node. This change // doesn't have any visible effect. unpackingNode->RemovePackageNode(packageNode); } if (!notify) return; // send notifications if (nodeRemoved) { notify_entry_removed(ID(), directory->ID(), node->Name(), node->ID()); } else if (packageNode == headPackageNode) { // The removed package node was the one representing the node. // Send stat changed notification for directories and entry // removed + created notifications for files and symlinks. if (S_ISDIR(packageNode->Mode())) { notify_stat_changed(ID(), node->ID(), kAllStatFields); // TODO: Actually the attributes might change, too! } else { notify_entry_removed(ID(), directory->ID(), node->Name(), node->ID()); notify_entry_created(ID(), directory->ID(), newNode->Name(), newNode->ID()); } } }
void TeamDebugger::MessageReceived(BMessage* message) { switch (message->what) { case MSG_THREAD_RUN: case MSG_THREAD_STOP: case MSG_THREAD_STEP_OVER: case MSG_THREAD_STEP_INTO: case MSG_THREAD_STEP_OUT: { int32 threadID; if (message->FindInt32("thread", &threadID) != B_OK) break; if (ThreadHandler* handler = _GetThreadHandler(threadID)) { handler->HandleThreadAction(message->what); handler->ReleaseReference(); } break; } case MSG_SET_BREAKPOINT: case MSG_CLEAR_BREAKPOINT: { UserBreakpoint* breakpoint = NULL; BReference<UserBreakpoint> breakpointReference; uint64 address = 0; if (message->FindPointer("breakpoint", (void**)&breakpoint) == B_OK) breakpointReference.SetTo(breakpoint, true); else if (message->FindUInt64("address", &address) != B_OK) break; if (message->what == MSG_SET_BREAKPOINT) { bool enabled; if (message->FindBool("enabled", &enabled) != B_OK) enabled = true; if (breakpoint != NULL) _HandleSetUserBreakpoint(breakpoint, enabled); else _HandleSetUserBreakpoint(address, enabled); } else { if (breakpoint != NULL) _HandleClearUserBreakpoint(breakpoint); else _HandleClearUserBreakpoint(address); } break; } case MSG_INSPECT_ADDRESS: { TeamMemoryBlock::Listener* listener; if (message->FindPointer("listener", reinterpret_cast<void **>(&listener)) != B_OK) { break; } target_addr_t address; if (message->FindUInt64("address", &address) == B_OK) { _HandleInspectAddress(address, listener); } break; } case MSG_THREAD_STATE_CHANGED: { int32 threadID; if (message->FindInt32("thread", &threadID) != B_OK) break; if (ThreadHandler* handler = _GetThreadHandler(threadID)) { handler->HandleThreadStateChanged(); handler->ReleaseReference(); } break; } case MSG_THREAD_CPU_STATE_CHANGED: { int32 threadID; if (message->FindInt32("thread", &threadID) != B_OK) break; if (ThreadHandler* handler = _GetThreadHandler(threadID)) { handler->HandleCpuStateChanged(); handler->ReleaseReference(); } break; } case MSG_THREAD_STACK_TRACE_CHANGED: { int32 threadID; if (message->FindInt32("thread", &threadID) != B_OK) break; if (ThreadHandler* handler = _GetThreadHandler(threadID)) { handler->HandleStackTraceChanged(); handler->ReleaseReference(); } break; } case MSG_IMAGE_DEBUG_INFO_CHANGED: { int32 imageID; if (message->FindInt32("image", &imageID) != B_OK) break; _HandleImageDebugInfoChanged(imageID); break; } case MSG_IMAGE_FILE_CHANGED: { int32 imageID; if (message->FindInt32("image", &imageID) != B_OK) break; _HandleImageFileChanged(imageID); break; } case MSG_DEBUGGER_EVENT: { DebugEvent* event; if (message->FindPointer("event", (void**)&event) != B_OK) break; _HandleDebuggerMessage(event); delete event; break; } case MSG_LOAD_SETTINGS: _LoadSettings(); Activate(); break; default: BLooper::MessageReceived(message); break; } }