From d3448fa204a648d61d07f12ecc982841160380d2 Mon Sep 17 00:00:00 2001 From: Andrey Kleshchev Date: Tue, 30 Jan 2024 01:50:15 +0200 Subject: BugSplat Crash #1409959 onTopLost onTopLost crashed 1. It contradicts callstack, but clearPopups() definetely has an issue due to not checking the pointer prior to calling onTopLost 2. According to callstack, crash happened around ~LLFolderViewFolder and while it does call removePopup for itself, it isn't a popup, the only one in the list would be the renamer, which calls back to parent, so made sure to secure it. 3. mFlashTimer was never deleted 4. Some explicit cleanup for TopLost --- indra/newview/llpopupview.cpp | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) (limited to 'indra/newview/llpopupview.cpp') diff --git a/indra/newview/llpopupview.cpp b/indra/newview/llpopupview.cpp index d1a9ca229f..49645eec11 100644 --- a/indra/newview/llpopupview.cpp +++ b/indra/newview/llpopupview.cpp @@ -260,12 +260,12 @@ void LLPopupView::clearPopups() popup_it != mPopups.end();) { LLView* popup = popup_it->get(); + if (popup) + { + popup->onTopLost(); + } - popup_list_t::iterator cur_popup_it = popup_it; - ++popup_it; - - mPopups.erase(cur_popup_it); - popup->onTopLost(); + popup_it = mPopups.erase(popup_it); } } -- cgit v1.2.3 From d47c6536820d1ed6e373147678dd0fab90e80ab8 Mon Sep 17 00:00:00 2001 From: Andrey Kleshchev Date: Thu, 29 Feb 2024 23:00:08 +0200 Subject: triage#105 clearPopups() crash onTopLost can result in popup being removed or potentially removing more than one popup. --- indra/newview/llpopupview.cpp | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) (limited to 'indra/newview/llpopupview.cpp') diff --git a/indra/newview/llpopupview.cpp b/indra/newview/llpopupview.cpp index 49645eec11..aadef9a308 100644 --- a/indra/newview/llpopupview.cpp +++ b/indra/newview/llpopupview.cpp @@ -256,16 +256,16 @@ void LLPopupView::removePopup(LLView* popup) void LLPopupView::clearPopups() { - for (popup_list_t::iterator popup_it = mPopups.begin(); - popup_it != mPopups.end();) + while (!mPopups.empty()) { - LLView* popup = popup_it->get(); + popup_list_t::iterator popup_it = mPopups.begin(); + LLView* popup = popup_it->get(); + // Remove before notifying in case it will cause removePopup + mPopups.erase(popup_it); if (popup) { popup->onTopLost(); } - - popup_it = mPopups.erase(popup_it); } } -- cgit v1.2.3