status_t TeamSettings::SetTo(Team* team) { _Unset(); AutoLocker<Team> locker(team); fTeamName = team->Name(); // add breakpoints for (UserBreakpointList::ConstIterator it = team->UserBreakpoints().GetIterator(); UserBreakpoint* breakpoint = it.Next();) { BreakpointSetting* breakpointSetting = new(std::nothrow) BreakpointSetting; if (breakpointSetting == NULL) return B_NO_MEMORY; status_t error = breakpointSetting->SetTo(breakpoint->Location(), breakpoint->IsEnabled(), breakpoint->IsHidden()); if (error == B_OK && !fBreakpoints.AddItem(breakpointSetting)) error = B_NO_MEMORY; if (error != B_OK) { delete breakpointSetting; return error; } } return B_OK; }
bool Update(UserBreakpoint* changedBreakpoint) { if (fTeam == NULL) { for (int32 i = 0; UserBreakpoint* breakpoint = fBreakpoints.ItemAt(i); i++) { breakpoint->ReleaseReference(); } fBreakpoints.MakeEmpty(); return true; } AutoLocker<Team> locker(fTeam); UserBreakpointList::ConstIterator it = fTeam->UserBreakpoints().GetIterator(); UserBreakpoint* newBreakpoint = it.Next(); int32 index = 0; // remove no longer existing breakpoints while (UserBreakpoint* oldBreakpoint = fBreakpoints.ItemAt(index)) { if (oldBreakpoint == newBreakpoint) { if (oldBreakpoint == changedBreakpoint) NotifyRowsChanged(index, 1); index++; newBreakpoint = it.Next(); } else { // TODO: Not particularly efficient! fBreakpoints.RemoveItemAt(index); oldBreakpoint->ReleaseReference(); NotifyRowsRemoved(index, 1); } } // add new breakpoints int32 countBefore = fBreakpoints.CountItems(); while (newBreakpoint != NULL) { if (!fBreakpoints.AddItem(newBreakpoint)) return false; newBreakpoint->AcquireReference(); newBreakpoint = it.Next(); } int32 count = fBreakpoints.CountItems(); if (count > countBefore) NotifyRowsAdded(countBefore, count - countBefore); return true; }
status_t TeamSettings::SetTo(Team* team) { _Unset(); AutoLocker<Team> locker(team); fTeamName = team->Name(); // add breakpoints for (UserBreakpointList::ConstIterator it = team->UserBreakpoints().GetIterator(); UserBreakpoint* breakpoint = it.Next();) { BreakpointSetting* breakpointSetting = new(std::nothrow) BreakpointSetting; if (breakpointSetting == NULL) return B_NO_MEMORY; status_t error = breakpointSetting->SetTo(breakpoint->Location(), breakpoint->IsEnabled(), breakpoint->IsHidden(), breakpoint->Condition()); if (error == B_OK && !fBreakpoints.AddItem(breakpointSetting)) error = B_NO_MEMORY; if (error != B_OK) { delete breakpointSetting; return error; } } // add signal configuration fSignalSettings->SetDefaultSignalDisposition( team->DefaultSignalDisposition()); const SignalDispositionMappings& mappings = team->GetSignalDispositionMappings(); for (SignalDispositionMappings::const_iterator it = mappings.begin(); it != mappings.end(); ++it) { status_t error = fSignalSettings->AddCustomSignalDisposition( it->first, it->second); if (error != B_OK) return error; } return B_OK; }
void BreakpointManager::_UpdateImageBreakpoints(Image* image, bool removeOnly) { AutoLocker<BLocker> installLocker(fLock); AutoLocker<Team> teamLocker(fTeam); // remove obsolete user breakpoint instances BObjectList<Breakpoint> breakpointsToUpdate; for (UserBreakpointList::ConstIterator it = fTeam->UserBreakpoints().GetIterator(); UserBreakpoint* userBreakpoint = it.Next();) { int32 instanceCount = userBreakpoint->CountInstances(); for (int32 i = instanceCount - 1; i >= 0; i--) { UserBreakpointInstance* instance = userBreakpoint->InstanceAt(i); Breakpoint* breakpoint = instance->GetBreakpoint(); if (breakpoint == NULL || breakpoint->GetImage() != image) continue; userBreakpoint->RemoveInstanceAt(i); breakpoint->RemoveUserBreakpoint(instance); if (!breakpointsToUpdate.AddItem(breakpoint)) { _UpdateBreakpointInstallation(breakpoint); if (breakpoint->IsUnused()) fTeam->RemoveBreakpoint(breakpoint); } delete instance; } } // update breakpoints teamLocker.Unlock(); for (int32 i = 0; Breakpoint* breakpoint = breakpointsToUpdate.ItemAt(i); i++) { _UpdateBreakpointInstallation(breakpoint); } teamLocker.Lock(); for (int32 i = 0; Breakpoint* breakpoint = breakpointsToUpdate.ItemAt(i); i++) { if (breakpoint->IsUnused()) fTeam->RemoveBreakpoint(breakpoint); } // add breakpoint instances for function instances in the image (if we have // an image debug info) BObjectList<UserBreakpointInstance> newInstances; ImageDebugInfo* imageDebugInfo = image->GetImageDebugInfo(); if (imageDebugInfo == NULL) return; for (UserBreakpointList::ConstIterator it = fTeam->UserBreakpoints().GetIterator(); UserBreakpoint* userBreakpoint = it.Next();) { // get the function Function* function = fTeam->FunctionByID( userBreakpoint->Location().GetFunctionID()); if (function == NULL) continue; const SourceLocation& sourceLocation = userBreakpoint->Location().GetSourceLocation(); target_addr_t relativeAddress = userBreakpoint->Location().RelativeAddress(); // iterate through the function instances for (FunctionInstanceList::ConstIterator it = function->Instances().GetIterator(); FunctionInstance* functionInstance = it.Next();) { if (functionInstance->GetImageDebugInfo() != imageDebugInfo) continue; // get the breakpoint address for the instance target_addr_t instanceAddress = 0; if (functionInstance->SourceFile() != NULL) { // We have a source file, so get the address for the source // location. Statement* statement = NULL; FunctionDebugInfo* functionDebugInfo = functionInstance->GetFunctionDebugInfo(); functionDebugInfo->GetSpecificImageDebugInfo() ->GetStatementAtSourceLocation(functionDebugInfo, sourceLocation, statement); if (statement != NULL) { instanceAddress = statement->CoveringAddressRange().Start(); // TODO: What about BreakpointAllowed()? statement->ReleaseReference(); // TODO: Make sure we do hit the function in question! } } if (instanceAddress == 0) { // No source file (or we failed getting the statement), so try // to use the same relative address. if (relativeAddress > functionInstance->Size()) continue; instanceAddress = functionInstance->Address() + relativeAddress; // TODO: Make sure it does at least hit an instruction! } // create the user breakpoint instance UserBreakpointInstance* instance = new(std::nothrow) UserBreakpointInstance(userBreakpoint, instanceAddress); if (instance == NULL || !newInstances.AddItem(instance)) { delete instance; continue; } if (!userBreakpoint->AddInstance(instance)) { newInstances.RemoveItemAt(newInstances.CountItems() - 1); delete instance; } // get/create the breakpoint for the address target_addr_t address = instance->Address(); Breakpoint* breakpoint = fTeam->BreakpointAtAddress(address); if (breakpoint == NULL) { breakpoint = new(std::nothrow) Breakpoint(image, address); if (breakpoint == NULL || !fTeam->AddBreakpoint(breakpoint)) { delete breakpoint; break; } } breakpoint->AddUserBreakpoint(instance); instance->SetBreakpoint(breakpoint); } } // install the breakpoints for the new user breakpoint instances teamLocker.Unlock(); for (int32 i = 0; UserBreakpointInstance* instance = newInstances.ItemAt(i); i++) { Breakpoint* breakpoint = instance->GetBreakpoint(); if (breakpoint == NULL || _UpdateBreakpointInstallation(breakpoint) != B_OK) { // something went wrong -- remove the instance teamLocker.Lock(); instance->GetUserBreakpoint()->RemoveInstance(instance); if (breakpoint != NULL) { breakpoint->AddUserBreakpoint(instance); if (breakpoint->IsUnused()) fTeam->RemoveBreakpoint(breakpoint); } teamLocker.Unlock(); } } }
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; }