From bc34217979c0a692b17de7ffcb524ed2418da967 Mon Sep 17 00:00:00 2001 From: Nicky Date: Wed, 26 Sep 2012 20:02:32 +0200 Subject: Add virtual destructor to LLGLFence. --- indra/llrender/llgl.h | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/indra/llrender/llgl.h b/indra/llrender/llgl.h index 964495a3ab..d70e764769 100644 --- a/indra/llrender/llgl.h +++ b/indra/llrender/llgl.h @@ -424,6 +424,10 @@ const U32 FENCE_WAIT_TIME_NANOSECONDS = 1000; //1 ms class LLGLFence { public: + virtual ~LLGLFence() + { + } + virtual void placeFence() = 0; virtual bool isCompleted() = 0; virtual void wait() = 0; -- cgit v1.2.3 From 1282cd91d18fe74016b58474b7d3afbc99c29aac Mon Sep 17 00:00:00 2001 From: Ansariel Date: Thu, 20 Sep 2012 20:23:54 +0200 Subject: Crash fix for non finite target in editing motion --- indra/llcharacter/lleditingmotion.cpp | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/indra/llcharacter/lleditingmotion.cpp b/indra/llcharacter/lleditingmotion.cpp index 66b3c2bd25..0d0b85ba60 100644 --- a/indra/llcharacter/lleditingmotion.cpp +++ b/indra/llcharacter/lleditingmotion.cpp @@ -214,8 +214,10 @@ BOOL LLEditingMotion::onUpdate(F32 time, U8* joint_mask) target = target * target_dist; if (!target.isFinite()) { - llerrs << "Non finite target in editing motion with target distance of " << target_dist << + // Don't error out here, set a fail-safe target vector + llwarns << "Non finite target in editing motion with target distance of " << target_dist << " and focus point " << focus_pt << llendl; + target.setVec(1.f, 1.f, 1.f); } mTarget.setPosition( target + mParentJoint.getPosition()); -- cgit v1.2.3 From 510e1b9e0ec14e98793041b9560694454a9aec2b Mon Sep 17 00:00:00 2001 From: Ansariel Date: Wed, 12 Sep 2012 19:44:53 +0200 Subject: Possible crash fix in LLAgent::doTeleportViaLocation --- indra/newview/llagent.cpp | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/indra/newview/llagent.cpp b/indra/newview/llagent.cpp index 447836910d..11fa50b51a 100755 --- a/indra/newview/llagent.cpp +++ b/indra/newview/llagent.cpp @@ -4045,6 +4045,12 @@ void LLAgent::teleportViaLocation(const LLVector3d& pos_global) void LLAgent::doTeleportViaLocation(const LLVector3d& pos_global) { LLViewerRegion* regionp = getRegion(); + + if (!regionp) + { + return; + } + U64 handle = to_region_handle(pos_global); LLSimInfo* info = LLWorldMap::getInstance()->simInfoFromHandle(handle); if(regionp && info) -- cgit v1.2.3 From 86e84ae75ef86417be32cff9a22a48fd7853758c Mon Sep 17 00:00:00 2001 From: Nicky Date: Sat, 1 Sep 2012 15:24:54 +0200 Subject: Crashfix; handle errors in release builds more gracefully. --- indra/llrender/llrendertarget.cpp | 15 ++++++++++++--- 1 file changed, 12 insertions(+), 3 deletions(-) diff --git a/indra/llrender/llrendertarget.cpp b/indra/llrender/llrendertarget.cpp index cc5c232380..846311a8d0 100644 --- a/indra/llrender/llrendertarget.cpp +++ b/indra/llrender/llrendertarget.cpp @@ -163,10 +163,19 @@ bool LLRenderTarget::addColorAttachment(U32 color_fmt) } U32 offset = mTex.size(); - if (offset >= 4 || - (offset > 0 && (mFBO == 0 || !gGLManager.mHasDrawBuffers))) + + if( offset >= 4 ) { - llerrs << "Too many color attachments!" << llendl; + llwarns << "Too many color attachments" << llendl; + llassert( offset < 4 ); + return false; + } + if( offset > 0 && (mFBO == 0 || !gGLManager.mHasDrawBuffers) ) + { + llwarns << "FBO not used or no drawbuffers available; mFBO=" << (U32)mFBO << " gGLManager.mHasDrawBuffers=" << (U32)gGLManager.mHasDrawBuffers << llendl; + llassert( mFBO != 0 ); + llassert( gGLManager.mHasDrawBuffers ); + return false; } U32 tex; -- cgit v1.2.3 From 48631db986f4f16ba6810c4f91844066407d430d Mon Sep 17 00:00:00 2001 From: Nicky Date: Tue, 28 Aug 2012 23:53:16 +0200 Subject: Crashfix; During TP, or shortly after, gAgent.getRegion can be invalid. Handle that instead of crashing. --- indra/newview/llwlhandlers.cpp | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/indra/newview/llwlhandlers.cpp b/indra/newview/llwlhandlers.cpp index 2425b96678..be3e3ff30e 100644 --- a/indra/newview/llwlhandlers.cpp +++ b/indra/newview/llwlhandlers.cpp @@ -105,10 +105,16 @@ LLEnvironmentRequestResponder::LLEnvironmentRequestResponder() return; } - if (unvalidated_content[0]["regionID"].asUUID() != gAgent.getRegion()->getRegionID()) + LLUUID regionId; + if( gAgent.getRegion() ) + { + regionId = gAgent.getRegion()->getRegionID(); + } + + if (unvalidated_content[0]["regionID"].asUUID() != regionId ) { LL_WARNS("WindlightCaps") << "Not in the region from where this data was received (wanting " - << gAgent.getRegion()->getRegionID() << " but got " << unvalidated_content[0]["regionID"].asUUID() + << regionId << " but got " << unvalidated_content[0]["regionID"].asUUID() << ") - ignoring..." << LL_ENDL; return; } -- cgit v1.2.3 From 33263bb5e7dad106ef82c62f789ae430bad63d60 Mon Sep 17 00:00:00 2001 From: Nicky Date: Tue, 28 Aug 2012 23:52:30 +0200 Subject: Don't crash if star_brightness misses in a WL-Param set. Instead warn to log and exit the fuction gracefully. --- indra/newview/lldrawpoolwlsky.cpp | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/indra/newview/lldrawpoolwlsky.cpp b/indra/newview/lldrawpoolwlsky.cpp index caf15fe1cb..b5faff7968 100644 --- a/indra/newview/lldrawpoolwlsky.cpp +++ b/indra/newview/lldrawpoolwlsky.cpp @@ -192,14 +192,18 @@ void LLDrawPoolWLSky::renderStars(void) const bool error; LLColor4 star_alpha(LLColor4::black); star_alpha.mV[3] = LLWLParamManager::getInstance()->mCurParams.getFloat("star_brightness", error) / 2.f; - llassert_always(!error); + + // If start_brightness is not set, exit + if( error ) + { + llwarns << "star_brightness missing in mCurParams" << llendl; + return; + } gGL.getTexUnit(0)->bind(gSky.mVOSkyp->getBloomTex()); gGL.pushMatrix(); gGL.rotatef(gFrameTimeSeconds*0.01f, 0.f, 0.f, 1.f); - // gl_FragColor.rgb = gl_Color.rgb; - // gl_FragColor.a = gl_Color.a * star_alpha.a; if (LLGLSLShader::sNoFixedFunction) { gCustomAlphaProgram.bind(); -- cgit v1.2.3 From dec4f9b4be6936ad4b342eb6030c740359713f06 Mon Sep 17 00:00:00 2001 From: Nicky Date: Sun, 26 Aug 2012 12:56:13 +0200 Subject: Gracefully handle 'Started' status. Ignore it and continue login. --- indra/viewer_components/login/lllogin.cpp | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/indra/viewer_components/login/lllogin.cpp b/indra/viewer_components/login/lllogin.cpp index d480b63094..bdcb068200 100644 --- a/indra/viewer_components/login/lllogin.cpp +++ b/indra/viewer_components/login/lllogin.cpp @@ -271,6 +271,16 @@ void LLLogin::Impl::login_(LLCoros::self& self, std::string uri, LLSD login_para } return; // Done! } + + /* Sometimes we end with "Started" here. Slightly slow server? + * Seems to be ok to just skip it. Otherwise we'd error out and crash in the if below. + */ + if( status == "Started") + { + LL_DEBUGS("LLLogin") << mAuthResponse << LL_ENDL; + continue; + } + // If we don't recognize status at all, trouble if (! (status == "CURLError" || status == "XMLRPCError" -- cgit v1.2.3 From 57d36df3bc3c601d87dcf35a4e6692e1ae4d65ff Mon Sep 17 00:00:00 2001 From: Nicky Date: Tue, 21 Aug 2012 19:47:16 +0200 Subject: Make sure mWearableItem/mNameEditor are valid before dereferencing them. --- indra/newview/llpaneleditwearable.cpp | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/indra/newview/llpaneleditwearable.cpp b/indra/newview/llpaneleditwearable.cpp index d58d6d536c..d42056ef9d 100644 --- a/indra/newview/llpaneleditwearable.cpp +++ b/indra/newview/llpaneleditwearable.cpp @@ -835,11 +835,11 @@ BOOL LLPanelEditWearable::isDirty() const BOOL isDirty = FALSE; if (mWearablePtr) { - if (mWearablePtr->isDirty() || - mWearableItem->getName().compare(mNameEditor->getText()) != 0) - { - isDirty = TRUE; - } + if (mWearablePtr->isDirty() || + ( mWearableItem && mNameEditor && mWearableItem->getName().compare(mNameEditor->getText()) != 0 )) + { + isDirty = TRUE; + } } return isDirty; } -- cgit v1.2.3 From f9c9a894442c7ff51255451663110a553c4c35c9 Mon Sep 17 00:00:00 2001 From: Nicky Date: Tue, 21 Aug 2012 19:45:45 +0200 Subject: Crashfix in animation preview floater. --- indra/newview/llfloaterbvhpreview.cpp | 21 +++++++++++++-------- 1 file changed, 13 insertions(+), 8 deletions(-) diff --git a/indra/newview/llfloaterbvhpreview.cpp b/indra/newview/llfloaterbvhpreview.cpp index fa0ad20fdb..62848586cd 100644 --- a/indra/newview/llfloaterbvhpreview.cpp +++ b/indra/newview/llfloaterbvhpreview.cpp @@ -422,13 +422,14 @@ void LLFloaterBvhPreview::resetMotion() LLVOAvatar* avatarp = mAnimPreview->getDummyAvatar(); BOOL paused = avatarp->areAnimationsPaused(); - // *TODO: Fix awful casting hack - LLKeyframeMotion* motionp = (LLKeyframeMotion*)avatarp->findMotion(mMotionID); - - // Set emotion - std::string emote = getChild("emote_combo")->getValue().asString(); - motionp->setEmote(mIDList[emote]); - + LLKeyframeMotion* motionp = dynamic_cast(avatarp->findMotion(mMotionID)); + if( motionp ) + { + // Set emotion + std::string emote = getChild("emote_combo")->getValue().asString(); + motionp->setEmote(mIDList[emote]); + } + LLUUID base_id = mIDList[getChild("preview_base_anim")->getValue().asString()]; avatarp->deactivateAllMotions(); avatarp->startMotion(mMotionID, 0.0f); @@ -438,8 +439,12 @@ void LLFloaterBvhPreview::resetMotion() // Set pose std::string handpose = getChild("hand_pose_combo")->getValue().asString(); avatarp->startMotion( ANIM_AGENT_HAND_MOTION, 0.0f ); - motionp->setHandPose(LLHandMotion::getHandPose(handpose)); + if( motionp ) + { + motionp->setHandPose(LLHandMotion::getHandPose(handpose)); + } + if (paused) { mPauseRequest = avatarp->requestPause(); -- cgit v1.2.3 From 944469b84f226cd96a62a9a1bb6302781000c497 Mon Sep 17 00:00:00 2001 From: Nicky Date: Tue, 14 Aug 2012 19:57:43 +0200 Subject: Make sure only one thread access mPendingLOD at a time. --- indra/newview/llmeshrepository.cpp | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/indra/newview/llmeshrepository.cpp b/indra/newview/llmeshrepository.cpp index bc7f522848..52077c620f 100755 --- a/indra/newview/llmeshrepository.cpp +++ b/indra/newview/llmeshrepository.cpp @@ -1097,11 +1097,13 @@ bool LLMeshRepoThread::headerReceived(const LLVolumeParams& mesh_params, U8* dat mMeshHeader[mesh_id] = header; } + + LLMutexLock lock(mMutex); // make sure only one thread access mPendingLOD at the same time. + //check for pending requests pending_lod_map::iterator iter = mPendingLOD.find(mesh_params); if (iter != mPendingLOD.end()) { - LLMutexLock lock(mMutex); for (U32 i = 0; i < iter->second.size(); ++i) { LODRequest req(mesh_params, iter->second[i]); -- cgit v1.2.3 From c8ba971e84b6dba31636dbfba20b2d9ca219f67f Mon Sep 17 00:00:00 2001 From: Nicky Date: Tue, 24 Jul 2012 17:22:18 +0200 Subject: Crashfix; don't crash in LLRightClickInventoryFetchDescendentsObserver::execute when there's a 0 pointer for item_array or cat_array. --- indra/newview/llinventorybridge.cpp | 19 ++++++++++++++----- 1 file changed, 14 insertions(+), 5 deletions(-) diff --git a/indra/newview/llinventorybridge.cpp b/indra/newview/llinventorybridge.cpp index fce0b7c9c9..14a228df1c 100644 --- a/indra/newview/llinventorybridge.cpp +++ b/indra/newview/llinventorybridge.cpp @@ -2577,14 +2577,23 @@ void LLRightClickInventoryFetchDescendentsObserver::execute(bool clear_observer) LLInventoryModel::item_array_t* item_array; gInventory.getDirectDescendentsOf(*current_folder, cat_array, item_array); - S32 item_count = item_array->count(); - S32 cat_count = cat_array->count(); - + S32 item_count(0); + if( item_array ) + { + item_count = item_array->count(); + } + + S32 cat_count(0); + if( cat_array ) + { + cat_count = cat_array->count(); + } + // Move to next if current folder empty if ((item_count == 0) && (cat_count == 0)) - { + { continue; - } + } uuid_vec_t ids; LLRightClickInventoryFetchObserver* outfit = NULL; -- cgit v1.2.3 From fdb0218bfc156842a70661e339ba4592e02dc9c4 Mon Sep 17 00:00:00 2001 From: Nicky Date: Mon, 22 Oct 2012 15:40:18 -0400 Subject: Crashfix; Guard against 0 pointer textures. --- indra/newview/llface.cpp | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/indra/newview/llface.cpp b/indra/newview/llface.cpp index 188f943f13..605cb81c10 100755 --- a/indra/newview/llface.cpp +++ b/indra/newview/llface.cpp @@ -1062,7 +1062,11 @@ bool LLFace::canRenderAsMask() } const LLTextureEntry* te = getTextureEntry(); - + if( !te || !getViewerObject() || !getTexture() ) + { + return false; + } + if ((te->getColor().mV[3] == 1.0f) && // can't treat as mask if we have face alpha (te->getGlow() == 0.f) && // glowing masks are hard to implement - don't mask getTexture()->getIsAlphaMask()) // texture actually qualifies for masking (lazily recalculated but expensive) -- cgit v1.2.3 From e0b334c6154e87729addfb01a52bd5b4c085bf44 Mon Sep 17 00:00:00 2001 From: Nicky Date: Sat, 21 Jul 2012 14:18:10 +0200 Subject: Crashfix; Change llassert_always to llassert + llwarns. This way users don't get disruptive crashes. --- indra/llrender/llvertexbuffer.cpp | 17 +++++++++++++++-- 1 file changed, 15 insertions(+), 2 deletions(-) diff --git a/indra/llrender/llvertexbuffer.cpp b/indra/llrender/llvertexbuffer.cpp index eadef93c89..2fe0aa0b72 100644 --- a/indra/llrender/llvertexbuffer.cpp +++ b/indra/llrender/llvertexbuffer.cpp @@ -555,8 +555,21 @@ void LLVertexBuffer::drawArrays(U32 mode, const std::vector& pos, con gGL.syncMatrices(); U32 count = pos.size(); - llassert_always(norm.size() >= pos.size()); - llassert_always(count > 0); + + llassert(norm.size() >= pos.size()); + llassert(count > 0); + + if( count == 0 ) + { + llwarns << "Called drawArrays with 0 vertices" << llendl; + return; + } + + if( norm.size() < pos.size() ) + { + llwarns << "Called drawArrays with #" << norm.size() << " normals and #" << pos.size() << " vertices" << llendl; + return; + } unbind(); -- cgit v1.2.3 From bef60207e309db96d1aace39c24906903ed3bdc1 Mon Sep 17 00:00:00 2001 From: Nicky Date: Sat, 21 Jul 2012 13:35:14 +0200 Subject: Crashfix; Guard against 0 pointer in LLRiggedVolume::update. --- indra/newview/llvovolume.cpp | 2 ++ 1 file changed, 2 insertions(+) diff --git a/indra/newview/llvovolume.cpp b/indra/newview/llvovolume.cpp index e99898a83c..afe62bbb2e 100644 --- a/indra/newview/llvovolume.cpp +++ b/indra/newview/llvovolume.cpp @@ -4880,6 +4880,7 @@ void LLVolumeGeometryManager::genDrawInfo(LLSpatialGroup* group, U32 mask, std:: std::vector texture_list; + if( pos && weight && dst_face.mExtents ) { LLFastTimer t(FTM_GEN_DRAW_INFO_FACE_SIZE); if (batch_textures) @@ -4976,6 +4977,7 @@ void LLVolumeGeometryManager::genDrawInfo(LLSpatialGroup* group, U32 mask, std:: //create vertex buffer LLVertexBuffer* buffer = NULL; + if( dst_face.mExtents ) { LLFastTimer t(FTM_GEN_DRAW_INFO_ALLOCATE); buffer = createVertexBuffer(mask, buffer_usage); -- cgit v1.2.3 From 6fab95060fe2793e1206a5329f81877e3980f0cd Mon Sep 17 00:00:00 2001 From: Nicky Date: Thu, 19 Jul 2012 22:54:17 +0200 Subject: Crashfix; Make sure getImage returns a valid result. --- indra/newview/llvoavatar.cpp | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/indra/newview/llvoavatar.cpp b/indra/newview/llvoavatar.cpp index 366b6004be..2c1291c954 100755 --- a/indra/newview/llvoavatar.cpp +++ b/indra/newview/llvoavatar.cpp @@ -4421,7 +4421,9 @@ U32 LLVOAvatar::renderTransparent(BOOL first_pass) } // Can't test for baked hair being defined, since that won't always be the case (not all viewers send baked hair) // TODO: 1.25 will be able to switch this logic back to calling isTextureVisible(); - if (getImage(TEX_HAIR_BAKED, 0)->getID() != IMG_INVISIBLE || LLDrawPoolAlpha::sShowDebugAlpha) + + if ( getImage(TEX_HAIR_BAKED, 0) + && getImage(TEX_HAIR_BAKED, 0)->getID() != IMG_INVISIBLE || LLDrawPoolAlpha::sShowDebugAlpha) { num_indices += mMeshLOD[MESH_ID_HAIR]->render(mAdjustedPixelArea, first_pass, mIsDummy); first_pass = FALSE; -- cgit v1.2.3 From 9b856a124ac11f976c7913d1ce2af8d57ab0464c Mon Sep 17 00:00:00 2001 From: Nicky Date: Sat, 14 Jul 2012 03:10:24 +0200 Subject: Crashfix: showToastsTop/Bottom, don't iterate over mToastList. The member can change during recursive calls, invalidating iterators. --- indra/newview/llscreenchannel.cpp | 40 +++++++++++++++++++++++++-------------- 1 file changed, 26 insertions(+), 14 deletions(-) diff --git a/indra/newview/llscreenchannel.cpp b/indra/newview/llscreenchannel.cpp index d340b304ca..d2280ea089 100644 --- a/indra/newview/llscreenchannel.cpp +++ b/indra/newview/llscreenchannel.cpp @@ -571,9 +571,13 @@ void LLScreenChannel::showToastsBottom() LLDockableFloater* floater = dynamic_cast(LLDockableFloater::getInstanceHandle().get()); - for(it = mToastList.rbegin(); it != mToastList.rend(); ++it) + // Use a local variable instead of mToastList. + // mToastList can be modified during recursive calls and then all iteratos will be invalidated. + std::vector vToastList( mToastList ); + + for(it = vToastList.rbegin(); it != vToastList.rend(); ++it) { - if(it != mToastList.rbegin()) + if(it != vToastList.rbegin()) { LLToast* toast = (it-1)->getToast(); if (!toast) @@ -601,7 +605,7 @@ void LLScreenChannel::showToastsBottom() if(floater && floater->overlapsScreenChannel()) { - if(it == mToastList.rbegin()) + if(it == vToastList.rbegin()) { // move first toast above docked floater S32 shift = floater->getRect().getHeight(); @@ -624,7 +628,7 @@ void LLScreenChannel::showToastsBottom() if(!stop_showing_toasts) { - if( it != mToastList.rend()-1) + if( it != vToastList.rend()-1) { S32 toast_top = toast->getRect().mTop + gSavedSettings.getS32("ToastGap"); stop_showing_toasts = toast_top > getRect().mTop; @@ -632,7 +636,8 @@ void LLScreenChannel::showToastsBottom() } // at least one toast should be visible - if(it == mToastList.rbegin()) + + if(it == vToastList.rbegin()) { stop_showing_toasts = false; } @@ -655,10 +660,11 @@ void LLScreenChannel::showToastsBottom() } // Dismiss toasts we don't have space for (STORM-391). - if(it != mToastList.rend()) + if(it != vToastList.rend()) { mHiddenToastsNum = 0; - for(; it != mToastList.rend(); it++) + + for(; it != vToastList.rend(); it++) { LLToast* toast = it->getToast(); if (toast) @@ -714,9 +720,13 @@ void LLScreenChannel::showToastsTop() LLDockableFloater* floater = dynamic_cast(LLDockableFloater::getInstanceHandle().get()); - for(it = mToastList.rbegin(); it != mToastList.rend(); ++it) + // Use a local variable instead of mToastList. + // mToastList can be modified during recursive calls and then all iteratos will be invalidated. + std::vector vToastList( mToastList ); + + for(it = vToastList.rbegin(); it != vToastList.rend(); ++it) { - if(it != mToastList.rbegin()) + if(it != vToastList.rbegin()) { LLToast* toast = (it-1)->getToast(); if (!toast) @@ -744,7 +754,7 @@ void LLScreenChannel::showToastsTop() if(floater && floater->overlapsScreenChannel()) { - if(it == mToastList.rbegin()) + if(it == vToastList.rbegin()) { // move first toast above docked floater S32 shift = -floater->getRect().getHeight(); @@ -767,7 +777,7 @@ void LLScreenChannel::showToastsTop() if(!stop_showing_toasts) { - if( it != mToastList.rend()-1) + if( it != vToastList.rend()-1) { S32 toast_bottom = toast->getRect().mBottom - gSavedSettings.getS32("ToastGap"); stop_showing_toasts = toast_bottom < channel_rect.mBottom; @@ -775,7 +785,7 @@ void LLScreenChannel::showToastsTop() } // at least one toast should be visible - if(it == mToastList.rbegin()) + if(it == vToastList.rbegin()) { stop_showing_toasts = false; } @@ -799,10 +809,12 @@ void LLScreenChannel::showToastsTop() // Dismiss toasts we don't have space for (STORM-391). std::vector toasts_to_hide; - if(it != mToastList.rend()) + + if(it != vToastList.rend()) { mHiddenToastsNum = 0; - for(; it != mToastList.rend(); it++) + + for(; it != vToastList.rend(); it++) { LLToast* toast = it->getToast(); if (toast) -- cgit v1.2.3 From c0e8656477e41fffa26be9a23bef1c5bb1357330 Mon Sep 17 00:00:00 2001 From: Nicky Date: Fri, 13 Jul 2012 14:04:45 +0200 Subject: Crashfix: Stop notifications when we're about to exit. --- indra/newview/llnotificationmanager.cpp | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/indra/newview/llnotificationmanager.cpp b/indra/newview/llnotificationmanager.cpp index f792f53ac5..3d8150eed3 100644 --- a/indra/newview/llnotificationmanager.cpp +++ b/indra/newview/llnotificationmanager.cpp @@ -97,6 +97,13 @@ bool LLNotificationManager::onNotification(const LLSD& notify) { LLSysHandler* handle = NULL; + // Don't bother if we're going down. + // Otherwise we might crash when trying to use handlers that are already dead. + if( LLApp::isExiting() ) + { + return false; + } + if (LLNotifications::destroyed()) return false; -- cgit v1.2.3 From 85025ffc7be40c0953ca8905f149701b4b8f568f Mon Sep 17 00:00:00 2001 From: Nicky Date: Fri, 13 Jul 2012 13:46:38 +0200 Subject: Crashfix: LLVOVolume::calcLOD make sure avatar and avatar->mDrawable are valid. --- indra/newview/llvovolume.cpp | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/indra/newview/llvovolume.cpp b/indra/newview/llvovolume.cpp index afe62bbb2e..49513eb206 100644 --- a/indra/newview/llvovolume.cpp +++ b/indra/newview/llvovolume.cpp @@ -1227,6 +1227,13 @@ BOOL LLVOVolume::calcLOD() if (mDrawable->isState(LLDrawable::RIGGED)) { LLVOAvatar* avatar = getAvatar(); + + // Not sure how this can really happen, but alas it does. Better exit here than crashing. + if( !avatar || !avatar->mDrawable ) + { + return FALSE; + } + distance = avatar->mDrawable->mDistanceWRTCamera; radius = avatar->getBinRadius(); } -- cgit v1.2.3 From 60393abdad98c61d9cb01d004e3d69bd8d34bfda Mon Sep 17 00:00:00 2001 From: Nicky Date: Fri, 13 Jul 2012 13:37:18 +0200 Subject: Crashfix: In LLAttachmentsMgr::onIdle make sure we've a valid region before dereferencing it. --- indra/newview/llattachmentsmgr.cpp | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/indra/newview/llattachmentsmgr.cpp b/indra/newview/llattachmentsmgr.cpp index c9543988a6..ea0b8f00a4 100644 --- a/indra/newview/llattachmentsmgr.cpp +++ b/indra/newview/llattachmentsmgr.cpp @@ -62,6 +62,12 @@ void LLAttachmentsMgr::onIdle(void *) void LLAttachmentsMgr::onIdle() { + // Make sure we got a region before trying anything else + if( !gAgent.getRegion() ) + { + return; + } + S32 obj_count = mPendingAttachments.size(); if (obj_count == 0) { -- cgit v1.2.3 From 2005b4fed4dcfc17ec46d21ce093dbc6a368083b Mon Sep 17 00:00:00 2001 From: Nicky Date: Thu, 12 Jul 2012 18:04:53 +0200 Subject: Crashfix: in ll_safe_string not only guard against 0 pointer, but against illegal length of buffer too. --- indra/llcommon/llstring.cpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/indra/llcommon/llstring.cpp b/indra/llcommon/llstring.cpp index fa0eb9f72c..0c32679744 100644 --- a/indra/llcommon/llstring.cpp +++ b/indra/llcommon/llstring.cpp @@ -47,7 +47,8 @@ std::string ll_safe_string(const char* in) std::string ll_safe_string(const char* in, S32 maxlen) { - if(in) return std::string(in, maxlen); + if(in && maxlen > 0 ) return std::string(in, maxlen); + return std::string(); } -- cgit v1.2.3 From 8902f4c6c0fed60ae6d8b7596e61c7b8387079c1 Mon Sep 17 00:00:00 2001 From: Nicky Date: Tue, 10 Jul 2012 20:12:31 +0200 Subject: Crashfix: Don't blindly trust getImage() returns a valid pointer. --- indra/newview/llvoavatar.cpp | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/indra/newview/llvoavatar.cpp b/indra/newview/llvoavatar.cpp index 2c1291c954..39222c25fd 100755 --- a/indra/newview/llvoavatar.cpp +++ b/indra/newview/llvoavatar.cpp @@ -8707,6 +8707,12 @@ BOOL LLVOAvatar::isTextureDefined(LLVOAvatarDefines::ETextureIndex te, U32 index return FALSE; } + if( !getImage( te, index ) ) + { + llwarns << "getImage( " << te << ", " << index << " ) returned 0" << llendl; + return FALSE; + } + return (getImage(te, index)->getID() != IMG_DEFAULT_AVATAR && getImage(te, index)->getID() != IMG_DEFAULT); } -- cgit v1.2.3 From 82c51c8d29d7c9a59373f45fa794bbc0729c97d5 Mon Sep 17 00:00:00 2001 From: Nicky Date: Mon, 9 Jul 2012 13:37:21 +0200 Subject: Crashfix: LLVOAvatar::updateTextures in some odd cases getTE can return 0. Safeguard against that. --- indra/newview/llvoavatar.cpp | 15 ++++++++++++++- 1 file changed, 14 insertions(+), 1 deletion(-) diff --git a/indra/newview/llvoavatar.cpp b/indra/newview/llvoavatar.cpp index 39222c25fd..627238b0f5 100755 --- a/indra/newview/llvoavatar.cpp +++ b/indra/newview/llvoavatar.cpp @@ -4567,7 +4567,20 @@ void LLVOAvatar::updateTextures() LLWearableType::EType wearable_type = LLVOAvatarDictionary::getTEWearableType((ETextureIndex)texture_index); U32 num_wearables = gAgentWearables.getWearableCount(wearable_type); const LLTextureEntry *te = getTE(texture_index); - const F32 texel_area_ratio = fabs(te->mScaleS * te->mScaleT); + + // getTE can return 0. + // Not sure yet why it does, but of course it crashes when te->mScale? gets used. + // Put safeguard in place so this corner case get better handling and does not result in a crash. + F32 texel_area_ratio = 1.0f; + if( te ) + { + texel_area_ratio = fabs(te->mScaleS * te->mScaleT); + } + else + { + llwarns << "getTE( " << texture_index << " ) returned 0" < Date: Sun, 8 Jul 2012 12:48:43 +0200 Subject: Crashfix: Make sure drawable exists before calling any method on it. --- indra/newview/llviewertexture.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/indra/newview/llviewertexture.cpp b/indra/newview/llviewertexture.cpp index 8eb8717de2..32cf8cc1b3 100644 --- a/indra/newview/llviewertexture.cpp +++ b/indra/newview/llviewertexture.cpp @@ -1904,7 +1904,7 @@ void LLViewerFetchedTexture::updateVirtualSize() for(U32 i = 0 ; i < mNumFaces ; i++) { LLFace* facep = mFaceList[i] ; - if(facep->getDrawable()->isRecentlyVisible()) + if( facep && facep->getDrawable() && facep->getDrawable()->isRecentlyVisible()) { addTextureStats(facep->getVirtualSize()) ; setAdditionalDecodePriority(facep->getImportanceToCamera()) ; -- cgit v1.2.3 From d1e924a71ef8ce41ba43bba1fbc1e1825401625c Mon Sep 17 00:00:00 2001 From: Nicky Date: Sat, 7 Jul 2012 22:10:43 +0200 Subject: Crashfix: During cleanup gAgentAvatarp can already be 0. --- indra/newview/llappearancemgr.cpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/indra/newview/llappearancemgr.cpp b/indra/newview/llappearancemgr.cpp index 6d67e098a6..06a9892c7e 100755 --- a/indra/newview/llappearancemgr.cpp +++ b/indra/newview/llappearancemgr.cpp @@ -52,7 +52,8 @@ std::string self_av_string() { - return gAgentAvatarp->avString(); + // On logout gAgentAvatarp can already be invalid + return isAgentAvatarValid() ? gAgentAvatarp->avString() : ""; } // RAII thingy to guarantee that a variable gets reset when the Setter -- cgit v1.2.3 From d40a620483729d87bb7bca5de42d338f32ab09dc Mon Sep 17 00:00:00 2001 From: Nicky Date: Sun, 17 Jun 2012 18:20:30 +0200 Subject: Don't reference any LLFace via LLDrawable::getFace whose index is out of bounds. --- indra/newview/llvovolume.cpp | 20 +++++++++++++++++--- 1 file changed, 17 insertions(+), 3 deletions(-) diff --git a/indra/newview/llvovolume.cpp b/indra/newview/llvovolume.cpp index 49513eb206..8465a9dadd 100644 --- a/indra/newview/llvovolume.cpp +++ b/indra/newview/llvovolume.cpp @@ -1342,7 +1342,8 @@ BOOL LLVOVolume::setDrawableParent(LLDrawable* parentp) void LLVOVolume::updateFaceFlags() { - for (S32 i = 0; i < getVolume()->getNumFaces(); i++) + // There's no guarantee that getVolume()->getNumFaces() == mDrawable->getNumFaces() + for (S32 i = 0; i < getVolume()->getNumFaces() && i < mDrawable->getNumFaces(); i++) { LLFace *face = mDrawable->getFace(i); if (face) @@ -1443,7 +1444,10 @@ BOOL LLVOVolume::genBBoxes(BOOL force_global) volume = getVolume(); } - for (S32 i = 0; i < getVolume()->getNumVolumeFaces(); i++) + // There's no guarantee that getVolume()->getNumFaces() == mDrawable->getNumFaces() + for (S32 i = 0; + i < getVolume()->getNumVolumeFaces() && i < mDrawable->getNumFaces() && i < getNumTEs(); + i++) { LLFace *face = mDrawable->getFace(i); if (!face) @@ -1744,6 +1748,11 @@ BOOL LLVOVolume::updateGeometry(LLDrawable *drawable) void LLVOVolume::updateFaceSize(S32 idx) { + if( mDrawable->getNumFaces() <= idx ) + { + return; + } + LLFace* facep = mDrawable->getFace(idx); if (facep) { @@ -2434,7 +2443,12 @@ void LLVOVolume::addMediaImpl(LLViewerMediaImpl* media_impl, S32 texture_index) //add the face to show the media if it is in playing if(mDrawable) { - LLFace* facep = mDrawable->getFace(texture_index) ; + LLFace* facep(NULL); + if( texture_index < mDrawable->getNumFaces() ) + { + facep = mDrawable->getFace(texture_index) ; + } + if(facep) { LLViewerMediaTexture* media_tex = LLViewerTextureManager::findMediaTexture(mMediaImplList[texture_index]->getMediaTextureID()) ; -- cgit v1.2.3 From e963cefea596e41922e91f794356ff2533594587 Mon Sep 17 00:00:00 2001 From: Nicky Date: Fri, 1 Jun 2012 19:37:10 +0200 Subject: check mesh repo thread before actively using it. --- indra/newview/llmeshrepository.cpp | 30 +++++++++++++++++++++++++++++- 1 file changed, 29 insertions(+), 1 deletion(-) diff --git a/indra/newview/llmeshrepository.cpp b/indra/newview/llmeshrepository.cpp index 52077c620f..ba0a590910 100755 --- a/indra/newview/llmeshrepository.cpp +++ b/indra/newview/llmeshrepository.cpp @@ -1798,7 +1798,12 @@ void LLMeshLODResponder::completedRaw(U32 status, const std::string& reason, const LLChannelDescriptors& channels, const LLIOPipe::buffer_ptr_t& buffer) { - + // thread could have already be destroyed during logout + if( !gMeshRepo.mThread ) + { + return; + } + S32 data_size = buffer->countAfter(channels.in(), NULL); if (status < 200 || status > 400) @@ -1853,6 +1858,12 @@ void LLMeshSkinInfoResponder::completedRaw(U32 status, const std::string& reason const LLChannelDescriptors& channels, const LLIOPipe::buffer_ptr_t& buffer) { + // thread could have already be destroyed during logout + if( !gMeshRepo.mThread ) + { + return; + } + S32 data_size = buffer->countAfter(channels.in(), NULL); if (status < 200 || status > 400) @@ -1907,6 +1918,11 @@ void LLMeshDecompositionResponder::completedRaw(U32 status, const std::string& r const LLChannelDescriptors& channels, const LLIOPipe::buffer_ptr_t& buffer) { + if( !gMeshRepo.mThread ) + { + return; + } + S32 data_size = buffer->countAfter(channels.in(), NULL); if (status < 200 || status > 400) @@ -1961,6 +1977,12 @@ void LLMeshPhysicsShapeResponder::completedRaw(U32 status, const std::string& re const LLChannelDescriptors& channels, const LLIOPipe::buffer_ptr_t& buffer) { + // thread could have already be destroyed during logout + if( !gMeshRepo.mThread ) + { + return; + } + S32 data_size = buffer->countAfter(channels.in(), NULL); if (status < 200 || status > 400) @@ -2015,6 +2037,12 @@ void LLMeshHeaderResponder::completedRaw(U32 status, const std::string& reason, const LLChannelDescriptors& channels, const LLIOPipe::buffer_ptr_t& buffer) { + // thread could have already be destroyed during logout + if( !gMeshRepo.mThread ) + { + return; + } + if (status < 200 || status > 400) { //llwarns -- cgit v1.2.3 From e8bebc5b3c17cbb3c3d1021104be2de99dcc3efe Mon Sep 17 00:00:00 2001 From: Nicky Date: Wed, 30 May 2012 23:46:41 +0200 Subject: Make sure to not use floaters of different type than LLPreview as LLPreview instance. --- indra/newview/llpreview.cpp | 17 +++++++++++++---- 1 file changed, 13 insertions(+), 4 deletions(-) diff --git a/indra/newview/llpreview.cpp b/indra/newview/llpreview.cpp index 18626e3273..04934b13f1 100644 --- a/indra/newview/llpreview.cpp +++ b/indra/newview/llpreview.cpp @@ -464,7 +464,9 @@ LLMultiPreview::LLMultiPreview() void LLMultiPreview::onOpen(const LLSD& key) { - LLPreview* frontmost_preview = (LLPreview*)mTabContainer->getCurrentPanel(); + // Floater could be something else than LLPreview, eg LLFloaterProfile. + LLPreview* frontmost_preview = dynamic_cast(mTabContainer->getCurrentPanel()); + if (frontmost_preview && frontmost_preview->getAssetStatus() == LLPreview::PREVIEW_ASSET_UNLOADED) { frontmost_preview->loadAsset(); @@ -477,8 +479,13 @@ void LLMultiPreview::handleReshape(const LLRect& new_rect, bool by_user) { if(new_rect.getWidth() != getRect().getWidth() || new_rect.getHeight() != getRect().getHeight()) { - LLPreview* frontmost_preview = (LLPreview*)mTabContainer->getCurrentPanel(); - if (frontmost_preview) frontmost_preview->userResized(); + // Floater could be something else than LLPreview, eg LLFloaterProfile. + LLPreview* frontmost_preview = dynamic_cast(mTabContainer->getCurrentPanel()); + + if (frontmost_preview) + { + frontmost_preview->userResized(); + } } LLFloater::handleReshape(new_rect, by_user); } @@ -486,7 +493,9 @@ void LLMultiPreview::handleReshape(const LLRect& new_rect, bool by_user) void LLMultiPreview::tabOpen(LLFloater* opened_floater, bool from_click) { - LLPreview* opened_preview = (LLPreview*)opened_floater; + // Floater could be something else than LLPreview, eg LLFloaterProfile. + LLPreview* opened_preview = dynamic_cast(opened_floater); + if (opened_preview && opened_preview->getAssetStatus() == LLPreview::PREVIEW_ASSET_UNLOADED) { opened_preview->loadAsset(); -- cgit v1.2.3 From a5e2ef6042c9c3fe69acd9daafebc7694151a21f Mon Sep 17 00:00:00 2001 From: Oz Linden Date: Tue, 23 Oct 2012 16:34:04 -0400 Subject: correct faulty merge --- indra/newview/llvovolume.cpp | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/indra/newview/llvovolume.cpp b/indra/newview/llvovolume.cpp index 8465a9dadd..5d1c335078 100644 --- a/indra/newview/llvovolume.cpp +++ b/indra/newview/llvovolume.cpp @@ -3847,6 +3847,7 @@ void LLRiggedVolume::update(const LLMeshSkinInfo* skin, LLVOAvatar* avatar, cons LLVector4a* pos = dst_face.mPositions; + if( pos && weight && dst_face.mExtents ) { LLFastTimer t(FTM_SKIN_RIGGED); @@ -4901,7 +4902,6 @@ void LLVolumeGeometryManager::genDrawInfo(LLSpatialGroup* group, U32 mask, std:: std::vector texture_list; - if( pos && weight && dst_face.mExtents ) { LLFastTimer t(FTM_GEN_DRAW_INFO_FACE_SIZE); if (batch_textures) @@ -4998,7 +4998,6 @@ void LLVolumeGeometryManager::genDrawInfo(LLSpatialGroup* group, U32 mask, std:: //create vertex buffer LLVertexBuffer* buffer = NULL; - if( dst_face.mExtents ) { LLFastTimer t(FTM_GEN_DRAW_INFO_ALLOCATE); buffer = createVertexBuffer(mask, buffer_usage); -- cgit v1.2.3 From 07410567c087a877ac8af25cd85c0100123d4a63 Mon Sep 17 00:00:00 2001 From: Nicky Date: Mon, 22 Oct 2012 21:39:48 +0200 Subject: LLDrawable::destroy: Illegal deletion of LLDrawable! --- indra/newview/pipeline.cpp | 2 ++ indra/newview/pipeline.h | 2 ++ 2 files changed, 4 insertions(+) diff --git a/indra/newview/pipeline.cpp b/indra/newview/pipeline.cpp index 678898797f..91dd441319 100644 --- a/indra/newview/pipeline.cpp +++ b/indra/newview/pipeline.cpp @@ -2011,6 +2011,7 @@ void LLPipeline::grabReferences(LLCullResult& result) void LLPipeline::clearReferences() { sCull = NULL; + mGroupSaveQ1.clear(); } void check_references(LLSpatialGroup* group, LLDrawable* drawable) @@ -2619,6 +2620,7 @@ void LLPipeline::rebuildPriorityGroups() group->clearState(LLSpatialGroup::IN_BUILD_Q1); } + mGroupSaveQ1 = mGroupQ1; mGroupQ1.clear(); mGroupQ1Locked = false; diff --git a/indra/newview/pipeline.h b/indra/newview/pipeline.h index fd2a1e06cd..7a0ca86231 100644 --- a/indra/newview/pipeline.h +++ b/indra/newview/pipeline.h @@ -668,6 +668,8 @@ protected: LLSpatialGroup::sg_vector_t mGroupQ1; //priority LLSpatialGroup::sg_vector_t mGroupQ2; // non-priority + LLSpatialGroup::sg_vector_t mGroupSaveQ1; // a place to save mGroupQ1 until it is safe to unref + LLSpatialGroup::sg_vector_t mMeshDirtyGroup; //groups that need rebuildMesh called U32 mMeshDirtyQueryObject; -- cgit v1.2.3 From d8f081cf1b18ddb5f0412b21f4d36bfce6abae19 Mon Sep 17 00:00:00 2001 From: Oz Linden Date: Tue, 13 Nov 2012 11:57:09 -0500 Subject: tag merge of DRTVWR-238 --- .hgtags | 1 + 1 file changed, 1 insertion(+) diff --git a/.hgtags b/.hgtags index 965770d483..2f86db822c 100755 --- a/.hgtags +++ b/.hgtags @@ -346,3 +346,4 @@ de3be913f68813a9bac7d1c671fef96d1159bcd6 DRTVWR-202 b61afe175b829c149d369524a4e974dfda99facf DRTVWR-219 32896d5e920ca9a29256ff3b747c2e99752aa5ae DRTVWR-217 704bbae7b182a1f2811a47a054e680522966f54a 3.4.2-beta1 +f7bedce18ad52283e6072814db23318907261487 DRTVWR-238 -- cgit v1.2.3