From 07b463722e3e87aaea608981a1020f1b482781ba Mon Sep 17 00:00:00 2001 From: Vadim Savchuk Date: Fri, 23 Apr 2010 17:18:37 +0300 Subject: Fixed bug EXT-6798 (Crash in LLTeleportHistoryStorage). Reason: Attempt to purge empty teleport history resulted in inconsistent history state. There were two consequences: 1) Further teleports would not properly update the history. 2) Subscribers of history changes were notified of the invalid change and that led to the crash. My changes: - added a sanity check to LLTeleportHistoryStorage::onTeleportHistoryChange() to prevent the crash - purging empty teleport history now does nothing, hence the history doesn't become inconsistent - removed a redundant (but harmless) call to onTeleportHistoryChanged() from LLNavigationBar::draw() because it's called by LLTeleportHistory::purgeItems() anyway Reviewed by Mike at https://codereview.productengine.com/secondlife/r/304/ --HG-- branch : product-engine --- indra/newview/llnavigationbar.cpp | 1 - indra/newview/llteleporthistory.cpp | 12 ++++++++++++ indra/newview/llteleporthistorystorage.cpp | 7 +++++++ 3 files changed, 19 insertions(+), 1 deletion(-) (limited to 'indra/newview') diff --git a/indra/newview/llnavigationbar.cpp b/indra/newview/llnavigationbar.cpp index e11df06d86..0341f2c693 100644 --- a/indra/newview/llnavigationbar.cpp +++ b/indra/newview/llnavigationbar.cpp @@ -375,7 +375,6 @@ void LLNavigationBar::draw() if(mPurgeTPHistoryItems) { LLTeleportHistory::getInstance()->purgeItems(); - onTeleportHistoryChanged(); mPurgeTPHistoryItems = false; } diff --git a/indra/newview/llteleporthistory.cpp b/indra/newview/llteleporthistory.cpp index dcc85392f7..15684337f4 100644 --- a/indra/newview/llteleporthistory.cpp +++ b/indra/newview/llteleporthistory.cpp @@ -136,6 +136,7 @@ void LLTeleportHistory::updateCurrentLocation(const LLVector3d& new_pos) if (mCurrentItem < 0 || mCurrentItem >= (int) mItems.size()) // sanity check { llwarns << "Invalid current item. (this should not happen)" << llendl; + llassert(!"Invalid current teleport histiry item"); return; } LLVector3 new_pos_local = gAgent.getPosAgentFromGlobal(new_pos); @@ -166,6 +167,17 @@ void LLTeleportHistory::onHistoryChanged() void LLTeleportHistory::purgeItems() { + if (mItems.size() == 0) // no entries yet (we're called before login) + { + // If we don't return here the history will get into inconsistent state, hence: + // 1) updateCurrentLocation() will malfunction, + // so further teleports will not properly update the history; + // 2) mHistoryChangedSignal subscribers will be notified + // of such an invalid change. (EXT-6798) + // Both should not happen. + return; + } + if (mItems.size() > 0) { mItems.erase(mItems.begin(), mItems.end()-1); diff --git a/indra/newview/llteleporthistorystorage.cpp b/indra/newview/llteleporthistorystorage.cpp index c635f91423..430d62e15e 100644 --- a/indra/newview/llteleporthistorystorage.cpp +++ b/indra/newview/llteleporthistorystorage.cpp @@ -89,6 +89,13 @@ void LLTeleportHistoryStorage::onTeleportHistoryChange() if (!th) return; + // Hacky sanity check. (EXT-6798) + if (th->getItems().size() == 0) + { + llassert(!"Inconsistent teleport history state"); + return; + } + const LLTeleportHistoryItem &item = th->getItems()[th->getCurrentItemIndex()]; addItem(item.mTitle, item.mGlobalPos); -- cgit v1.2.3