Merge branch 'DRTVWR-516-maint' of https://bitbucket.org/lindenlab/viewer
commit
db72dc7d0f
|
|
@ -2405,18 +2405,18 @@
|
|||
<key>archive</key>
|
||||
<map>
|
||||
<key>hash</key>
|
||||
<string>c541838a933e0714a954e9ef6c89345d</string>
|
||||
<string>0a6349b11c8e9d34f0c80b8081736e75</string>
|
||||
<key>hash_algorithm</key>
|
||||
<string>md5</string>
|
||||
<key>url</key>
|
||||
<string>https://automated-builds-secondlife-com.s3.amazonaws.com/ct2/73387/708088/llca-202012011600.553112-common-553112.tar.bz2</string>
|
||||
<string>https://automated-builds-secondlife-com.s3.amazonaws.com/ct2/79438/751815/llca-202104010215.557744-common-557744.tar.bz2</string>
|
||||
</map>
|
||||
<key>name</key>
|
||||
<string>common</string>
|
||||
</map>
|
||||
</map>
|
||||
<key>version</key>
|
||||
<string>202012011600.553112</string>
|
||||
<string>202104010215.557744</string>
|
||||
</map>
|
||||
<key>llphysicsextensions_source</key>
|
||||
<map>
|
||||
|
|
|
|||
|
|
@ -265,10 +265,11 @@ Benja Kepler
|
|||
Benjamin Bigdipper
|
||||
Beq Janus
|
||||
BUG-227094
|
||||
Beth Walcher
|
||||
Beq Janus
|
||||
SL-10288
|
||||
SL-13583
|
||||
SL-14766
|
||||
SL-14927
|
||||
Beth Walcher
|
||||
Bezilon Kasei
|
||||
Biancaluce Robbiani
|
||||
CT-225
|
||||
|
|
|
|||
|
|
@ -259,6 +259,10 @@ public:
|
|||
*/
|
||||
LLRunner& getRunner() { return mRunner; }
|
||||
|
||||
#ifdef LL_WINDOWS
|
||||
virtual void reportCrashToBugsplat(void* pExcepInfo /*EXCEPTION_POINTERS*/) { }
|
||||
#endif
|
||||
|
||||
public:
|
||||
typedef std::map<std::string, std::string> string_map;
|
||||
string_map mOptionMap; // Contains all command-line options and arguments in a map
|
||||
|
|
|
|||
|
|
@ -254,8 +254,21 @@ std::string LLCoros::launch(const std::string& prefix, const callable_t& callabl
|
|||
|
||||
static const U32 STATUS_MSC_EXCEPTION = 0xE06D7363; // compiler specific
|
||||
|
||||
U32 exception_filter(U32 code, struct _EXCEPTION_POINTERS *exception_infop)
|
||||
U32 cpp_exception_filter(U32 code, struct _EXCEPTION_POINTERS *exception_infop, const std::string& name)
|
||||
{
|
||||
// C++ exceptions were logged in toplevelTryWrapper, but not SEH
|
||||
// log SEH exceptions here, to make sure it gets into bugsplat's
|
||||
// report and because __try won't allow std::string operations
|
||||
if (code != STATUS_MSC_EXCEPTION)
|
||||
{
|
||||
LL_WARNS() << "SEH crash in " << name << ", code: " << code << LL_ENDL;
|
||||
}
|
||||
// Handle bugsplat here, since GetExceptionInformation() can only be
|
||||
// called from within filter for __except(filter), not from __except's {}
|
||||
// Bugsplat should get all exceptions, C++ and SEH
|
||||
LLApp::instance()->reportCrashToBugsplat(exception_infop);
|
||||
|
||||
// Only convert non C++ exceptions.
|
||||
if (code == STATUS_MSC_EXCEPTION)
|
||||
{
|
||||
// C++ exception, go on
|
||||
|
|
@ -268,29 +281,29 @@ U32 exception_filter(U32 code, struct _EXCEPTION_POINTERS *exception_infop)
|
|||
}
|
||||
}
|
||||
|
||||
void LLCoros::winlevel(const callable_t& callable)
|
||||
void LLCoros::winlevel(const std::string& name, const callable_t& callable)
|
||||
{
|
||||
__try
|
||||
{
|
||||
callable();
|
||||
toplevelTryWrapper(name, callable);
|
||||
}
|
||||
__except (exception_filter(GetExceptionCode(), GetExceptionInformation()))
|
||||
__except (cpp_exception_filter(GetExceptionCode(), GetExceptionInformation(), name))
|
||||
{
|
||||
// convert to C++ styled exception
|
||||
// convert to C++ styled exception for handlers other than bugsplat
|
||||
// Note: it might be better to use _se_set_translator
|
||||
// if you want exception to inherit full callstack
|
||||
char integer_string[32];
|
||||
sprintf(integer_string, "SEH, code: %lu\n", GetExceptionCode());
|
||||
//
|
||||
// in case of bugsplat this will get to exceptionTerminateHandler and
|
||||
// looks like fiber will terminate application after that
|
||||
char integer_string[512];
|
||||
sprintf(integer_string, "SEH crash in %s, code: %lu\n", name.c_str(), GetExceptionCode());
|
||||
throw std::exception(integer_string);
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
// Top-level wrapper around caller's coroutine callable.
|
||||
// Normally we like to pass strings and such by const reference -- but in this
|
||||
// case, we WANT to copy both the name and the callable to our local stack!
|
||||
void LLCoros::toplevel(std::string name, callable_t callable)
|
||||
void LLCoros::toplevelTryWrapper(const std::string& name, const callable_t& callable)
|
||||
{
|
||||
// keep the CoroData on this top-level function's stack frame
|
||||
CoroData corodata(name);
|
||||
|
|
@ -300,18 +313,12 @@ void LLCoros::toplevel(std::string name, callable_t callable)
|
|||
// run the code the caller actually wants in the coroutine
|
||||
try
|
||||
{
|
||||
// <FS:Ansariel> Disable for more meaningful callstacks
|
||||
//#if LL_WINDOWS && LL_RELEASE_FOR_DOWNLOAD
|
||||
// winlevel(callable);
|
||||
//#else
|
||||
callable();
|
||||
//#endif
|
||||
// <FS:Ansariel> Disable for more meaningful callstacks
|
||||
}
|
||||
catch (const Stop& exc)
|
||||
{
|
||||
LL_INFOS("LLCoros") << "coroutine " << name << " terminating because "
|
||||
<< exc.what() << LL_ENDL;
|
||||
<< exc.what() << LL_ENDL;
|
||||
}
|
||||
catch (const LLContinueError&)
|
||||
{
|
||||
|
|
@ -324,10 +331,25 @@ void LLCoros::toplevel(std::string name, callable_t callable)
|
|||
{
|
||||
// Any OTHER kind of uncaught exception will cause the viewer to
|
||||
// crash, hopefully informatively.
|
||||
CRASH_ON_UNHANDLED_EXCEPTION(STRINGIZE("coroutine " << name));
|
||||
LOG_UNHANDLED_EXCEPTION(STRINGIZE("coroutine " << name));
|
||||
// to not modify callstack
|
||||
throw;
|
||||
}
|
||||
}
|
||||
|
||||
// Top-level wrapper around caller's coroutine callable.
|
||||
// Normally we like to pass strings and such by const reference -- but in this
|
||||
// case, we WANT to copy both the name and the callable to our local stack!
|
||||
void LLCoros::toplevel(std::string name, callable_t callable)
|
||||
{
|
||||
#if LL_WINDOWS
|
||||
// Can not use __try in functions that require unwinding, so use one more wrapper
|
||||
winlevel(name, callable);
|
||||
#else
|
||||
toplevelTryWrapper(name, callable);
|
||||
#endif
|
||||
}
|
||||
|
||||
//static
|
||||
void LLCoros::checkStop()
|
||||
{
|
||||
|
|
|
|||
|
|
@ -290,11 +290,12 @@ public:
|
|||
|
||||
private:
|
||||
std::string generateDistinctName(const std::string& prefix) const;
|
||||
#if LL_WINDOWS
|
||||
void winlevel(const std::string& name, const callable_t& callable);
|
||||
#endif
|
||||
void toplevelTryWrapper(const std::string& name, const callable_t& callable);
|
||||
void toplevel(std::string name, callable_t callable);
|
||||
struct CoroData;
|
||||
#if LL_WINDOWS
|
||||
static void winlevel(const callable_t& callable);
|
||||
#endif
|
||||
static CoroData& get_CoroData(const std::string& caller);
|
||||
|
||||
S32 mStackSize;
|
||||
|
|
|
|||
|
|
@ -1723,7 +1723,7 @@ void LLFolderViewFolder::destroyView()
|
|||
|
||||
// extractItem() removes the specified item from the folder, but
|
||||
// doesn't delete it.
|
||||
void LLFolderViewFolder::extractItem( LLFolderViewItem* item )
|
||||
void LLFolderViewFolder::extractItem( LLFolderViewItem* item, bool deparent_model )
|
||||
{
|
||||
if (item->isSelected())
|
||||
getRoot()->clearSelection();
|
||||
|
|
@ -1746,7 +1746,11 @@ void LLFolderViewFolder::extractItem( LLFolderViewItem* item )
|
|||
mItems.erase(it);
|
||||
}
|
||||
//item has been removed, need to update filter
|
||||
getViewModelItem()->removeChild(item->getViewModelItem());
|
||||
if (deparent_model)
|
||||
{
|
||||
// in some cases model does not belong to parent view, is shared between views
|
||||
getViewModelItem()->removeChild(item->getViewModelItem());
|
||||
}
|
||||
//because an item is going away regardless of filter status, force rearrange
|
||||
requestArrange();
|
||||
removeChild(item);
|
||||
|
|
|
|||
|
|
@ -402,7 +402,7 @@ public:
|
|||
|
||||
// extractItem() removes the specified item from the folder, but
|
||||
// doesn't delete it.
|
||||
virtual void extractItem( LLFolderViewItem* item );
|
||||
virtual void extractItem( LLFolderViewItem* item, bool deparent_model = true);
|
||||
|
||||
// This function is called by a child that needs to be resorted.
|
||||
void resort(LLFolderViewItem* item);
|
||||
|
|
|
|||
|
|
@ -1039,25 +1039,14 @@ boost::signals2::connection LLAgent::addParcelChangedCallback(parcel_changed_cal
|
|||
}
|
||||
|
||||
// static
|
||||
// <FS:Beq> FIRE-30774 displayname capability is targetting previous region
|
||||
// void LLAgent::capabilityReceivedCallback(const LLUUID ®ion_id)
|
||||
// {
|
||||
// LLViewerRegion* region = gAgent.getRegion();
|
||||
// if (region && region->getRegionID() == region_id)
|
||||
// {
|
||||
// region->requestSimulatorFeatures();
|
||||
// LLAppViewer::instance()->updateNameLookupUrl();
|
||||
// }
|
||||
// }
|
||||
void LLAgent::capabilityReceivedCallback(LLViewerRegion* regionp)
|
||||
void LLAgent::capabilityReceivedCallback(const LLUUID ®ion_id, LLViewerRegion *regionp)
|
||||
{
|
||||
if (regionp)
|
||||
if (regionp && regionp->getRegionID() == region_id)
|
||||
{
|
||||
regionp->requestSimulatorFeatures();
|
||||
LLAppViewer::instance()->updateNameLookupUrl(regionp);
|
||||
}
|
||||
}
|
||||
// </FS:Beq>
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// setRegion()
|
||||
|
|
@ -1109,17 +1098,11 @@ void LLAgent::setRegion(LLViewerRegion *regionp)
|
|||
if (regionp->capabilitiesReceived())
|
||||
{
|
||||
regionp->requestSimulatorFeatures();
|
||||
// <FS:Beq> FIRE-30774 displayname capability is targetting previous region
|
||||
// LLAppViewer::instance()->updateNameLookupUrl();
|
||||
LLAppViewer::instance()->updateNameLookupUrl(regionp);
|
||||
// </FS:Beq>
|
||||
}
|
||||
else
|
||||
{
|
||||
// <FS:Beq> FIRE-30774 displayname capability is targetting previous region
|
||||
// regionp->setCapabilitiesReceivedCallback(LLAgent::capabilityReceivedCallback);
|
||||
regionp->setCapabilitiesReceivedCallback(boost::bind(&LLAgent::capabilityReceivedCallback, regionp));
|
||||
// </FS:Beq>
|
||||
regionp->setCapabilitiesReceivedCallback(LLAgent::capabilityReceivedCallback);
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -1141,17 +1124,11 @@ void LLAgent::setRegion(LLViewerRegion *regionp)
|
|||
|
||||
if (regionp->capabilitiesReceived())
|
||||
{
|
||||
// <FS:Beq> FIRE-30774 displayname capability is targetting previous region
|
||||
// LLAppViewer::instance()->updateNameLookupUrl();
|
||||
LLAppViewer::instance()->updateNameLookupUrl(regionp);
|
||||
// </FS:Beq>
|
||||
}
|
||||
else
|
||||
{
|
||||
// <FS:Beq> FIRE-30774 displayname capability is targetting previous region
|
||||
// regionp->setCapabilitiesReceivedCallback([regionp](const LLUUID ®ion_id) {LLAppViewer::instance()->updateNameLookupUrl(); });
|
||||
regionp->setCapabilitiesReceivedCallback([regionp](const LLUUID ®ion_id) { LLAppViewer::instance()->updateNameLookupUrl(regionp); });
|
||||
// </FS:Beq>
|
||||
regionp->setCapabilitiesReceivedCallback([](const LLUUID ®ion_id, LLViewerRegion* regionp) {LLAppViewer::instance()->updateNameLookupUrl(regionp); });
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -258,10 +258,7 @@ public:
|
|||
boost::signals2::connection addParcelChangedCallback(parcel_changed_callback_t);
|
||||
|
||||
private:
|
||||
// <FS:Beq> FIRE-30774 displayname capability is targetting previous region
|
||||
// static void capabilityReceivedCallback(const LLUUID ®ion_id);
|
||||
static void capabilityReceivedCallback(LLViewerRegion* regionp);
|
||||
// </FS:Beq>
|
||||
static void capabilityReceivedCallback(const LLUUID ®ion_id, LLViewerRegion *regionp);
|
||||
|
||||
typedef boost::signals2::signal<void()> parcel_changed_signal_t;
|
||||
parcel_changed_signal_t mParcelChangedSignal;
|
||||
|
|
|
|||
|
|
@ -6042,13 +6042,9 @@ void LLAppViewer::sendLogoutRequest()
|
|||
}
|
||||
}
|
||||
|
||||
// <FS:Beq> FIRE-30774 displayname capability is targetting previous region
|
||||
// void LLAppViewer::updateNameLookupUrl()
|
||||
void LLAppViewer::updateNameLookupUrl(const LLViewerRegion * region)
|
||||
// </FS:Beq>
|
||||
void LLAppViewer::updateNameLookupUrl(const LLViewerRegion * regionp)
|
||||
{
|
||||
// LLViewerRegion* region = gAgent.getRegion(); <FS:Beq/>
|
||||
if (!region || !region->capabilitiesReceived())
|
||||
if (!regionp || !regionp->capabilitiesReceived())
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
|
@ -6057,7 +6053,7 @@ void LLAppViewer::updateNameLookupUrl(const LLViewerRegion * region)
|
|||
bool had_capability = name_cache->hasNameLookupURL();
|
||||
std::string name_lookup_url;
|
||||
name_lookup_url.reserve(128); // avoid a memory allocation below
|
||||
name_lookup_url = region->getCapability("GetDisplayNames");
|
||||
name_lookup_url = regionp->getCapability("GetDisplayNames");
|
||||
bool have_capability = !name_lookup_url.empty();
|
||||
if (have_capability)
|
||||
{
|
||||
|
|
@ -6405,6 +6401,33 @@ void LLAppViewer::forceErrorDriverCrash()
|
|||
glDeleteTextures(1, NULL);
|
||||
}
|
||||
|
||||
void LLAppViewer::forceErrorCoroutineCrash()
|
||||
{
|
||||
LL_WARNS() << "Forcing a crash in LLCoros" << LL_ENDL;
|
||||
LLCoros::instance().launch("LLAppViewer::crashyCoro", [] {throw LLException("A deliberate crash from LLCoros"); });
|
||||
}
|
||||
|
||||
void LLAppViewer::forceErrorThreadCrash()
|
||||
{
|
||||
class LLCrashTestThread : public LLThread
|
||||
{
|
||||
public:
|
||||
|
||||
LLCrashTestThread() : LLThread("Crash logging test thread")
|
||||
{
|
||||
}
|
||||
|
||||
void run()
|
||||
{
|
||||
LL_ERRS() << "This is a deliberate llerror in thread" << LL_ENDL;
|
||||
}
|
||||
};
|
||||
|
||||
LL_WARNS() << "This is a deliberate crash in a thread" << LL_ENDL;
|
||||
LLCrashTestThread *thread = new LLCrashTestThread();
|
||||
thread->start();
|
||||
}
|
||||
|
||||
// <FS:ND> Change from std::string to char const*, saving a lot of object construction/destruction per frame
|
||||
//void LLAppViewer::initMainloopTimeout(const std::string& state, F32 secs)
|
||||
void LLAppViewer::initMainloopTimeout( char const* state, F32 secs)
|
||||
|
|
|
|||
|
|
@ -58,7 +58,7 @@ class LLImageDecodeThread;
|
|||
class LLTextureFetch;
|
||||
class LLWatchdogTimeout;
|
||||
class LLViewerJoystick;
|
||||
class LLViewerRegion; // <FS:Beq/>
|
||||
class LLViewerRegion;
|
||||
|
||||
extern LLTrace::BlockTimerStatHandle FTM_FRAME;
|
||||
|
||||
|
|
@ -149,6 +149,8 @@ public:
|
|||
virtual void forceErrorInfiniteLoop();
|
||||
virtual void forceErrorSoftwareException();
|
||||
virtual void forceErrorDriverCrash();
|
||||
virtual void forceErrorCoroutineCrash();
|
||||
virtual void forceErrorThreadCrash();
|
||||
|
||||
// The list is found in app_settings/settings_files.xml
|
||||
// but since they are used explicitly in code,
|
||||
|
|
@ -223,10 +225,7 @@ public:
|
|||
// llcorehttp init/shutdown/config information.
|
||||
LLAppCoreHttp & getAppCoreHttp() { return mAppCoreHttp; }
|
||||
|
||||
// <FS:Beq> FIRE-30774 displayname capability is targetting previous region
|
||||
// void updateNameLookupUrl();
|
||||
void updateNameLookupUrl( const LLViewerRegion * region );
|
||||
// </FS:Beq>
|
||||
void updateNameLookupUrl(const LLViewerRegion* regionp);
|
||||
|
||||
protected:
|
||||
virtual bool initWindow(); // Initialize the viewer's window.
|
||||
|
|
|
|||
|
|
@ -784,6 +784,13 @@ bool LLAppViewerWin32::init()
|
|||
#else // LL_BUGSPLAT
|
||||
#pragma message("Building with BugSplat")
|
||||
// <FS:ND> Pre BugSplat dance, make sure settings are valid, query crash behavior and then set up Bugsplat accordingly"
|
||||
//if (!isSecondInstance())
|
||||
//{
|
||||
// // Cleanup previous session
|
||||
// std::string log_file = gDirUtilp->getExpandedFilename(LL_PATH_LOGS, "bugsplat.log");
|
||||
// LLFile::remove(log_file, ENOENT);
|
||||
//}
|
||||
|
||||
success = LLAppViewer::init();
|
||||
if (!success)
|
||||
return false;
|
||||
|
|
@ -812,7 +819,7 @@ bool LLAppViewerWin32::init()
|
|||
llifstream inf(build_data_fname.c_str());
|
||||
if (! inf.is_open())
|
||||
{
|
||||
LL_WARNS() << "Can't initialize BugSplat, can't read '" << build_data_fname
|
||||
LL_WARNS("BUGSPLAT") << "Can't initialize BugSplat, can't read '" << build_data_fname
|
||||
<< "'" << LL_ENDL;
|
||||
}
|
||||
else
|
||||
|
|
@ -822,7 +829,7 @@ bool LLAppViewerWin32::init()
|
|||
if (! reader.parse(inf, build_data, false)) // don't collect comments
|
||||
{
|
||||
// gah, the typo is baked into Json::Reader API
|
||||
LL_WARNS() << "Can't initialize BugSplat, can't parse '" << build_data_fname
|
||||
LL_WARNS("BUGSPLAT") << "Can't initialize BugSplat, can't parse '" << build_data_fname
|
||||
<< "': " << reader.getFormatedErrorMessages() << LL_ENDL;
|
||||
}
|
||||
else
|
||||
|
|
@ -830,7 +837,7 @@ bool LLAppViewerWin32::init()
|
|||
Json::Value BugSplat_DB = build_data["BugSplat DB"];
|
||||
if (! BugSplat_DB)
|
||||
{
|
||||
LL_WARNS() << "Can't initialize BugSplat, no 'BugSplat DB' entry in '"
|
||||
LL_WARNS("BUGSPLAT") << "Can't initialize BugSplat, no 'BugSplat DB' entry in '"
|
||||
<< build_data_fname << "'" << LL_ENDL;
|
||||
}
|
||||
else
|
||||
|
|
@ -841,31 +848,40 @@ bool LLAppViewerWin32::init()
|
|||
LL_VIEWER_VERSION_PATCH << '.' <<
|
||||
LL_VIEWER_VERSION_BUILD));
|
||||
|
||||
// have to convert normal wide strings to strings of __wchar_t
|
||||
|
||||
// <FS:ND> Set up Bugsplat to ask or always send
|
||||
//DWORD dwFlags = MDSF_NONINTERACTIVE | // automatically submit report without prompting
|
||||
// MDSF_PREVENTHIJACKING; // disallow swiping Exception filter
|
||||
DWORD dwFlags = dwAsk |
|
||||
MDSF_PREVENTHIJACKING; // disallow swiping Exception filter
|
||||
// </FS:ND>
|
||||
|
||||
// sBugSplatSender = new MiniDmpSender(
|
||||
// WCSTR(BugSplat_DB.asString()),
|
||||
// WCSTR(LL_TO_WSTRING(LL_VIEWER_CHANNEL)),
|
||||
// WCSTR(version_string),
|
||||
// nullptr, // szAppIdentifier -- set later
|
||||
// MDSF_NONINTERACTIVE | // automatically submit report without prompting
|
||||
// MDSF_PREVENTHIJACKING); // disallow swiping Exception filter
|
||||
|
||||
//bool needs_log_file = !isSecondInstance() && debugLoggingEnabled("BUGSPLAT");
|
||||
//if (needs_log_file)
|
||||
//{
|
||||
// // Startup only!
|
||||
// LL_INFOS("BUGSPLAT") << "Engaged BugSplat logging to bugsplat.log" << LL_ENDL;
|
||||
// dwFlags |= MDSF_LOGFILE | MDSF_LOG_VERBOSE;
|
||||
//}
|
||||
|
||||
// have to convert normal wide strings to strings of __wchar_t
|
||||
sBugSplatSender = new MiniDmpSender(
|
||||
WCSTR(BugSplat_DB.asString()),
|
||||
WCSTR(LL_TO_WSTRING(LL_VIEWER_CHANNEL)),
|
||||
WCSTR(version_string),
|
||||
nullptr, // szAppIdentifier -- set later
|
||||
dwAsk |
|
||||
MDSF_PREVENTHIJACKING); // disallow swiping Exception filter
|
||||
// </FS:ND>
|
||||
dwFlags);
|
||||
|
||||
sBugSplatSender->setCallback(bugsplatSendLog);
|
||||
|
||||
//if (needs_log_file)
|
||||
//{
|
||||
// // Log file will be created in %TEMP%, but it will be moved into logs folder in case of crash
|
||||
// std::string log_file = gDirUtilp->getExpandedFilename(LL_PATH_LOGS, "bugsplat.log");
|
||||
// sBugSplatSender->setLogFilePath(WCSTR(log_file));
|
||||
//}
|
||||
|
||||
// engage stringize() overload that converts from wstring
|
||||
LL_INFOS() << "Engaged BugSplat(" << LL_TO_STRING(LL_VIEWER_CHANNEL)
|
||||
LL_INFOS("BUGSPLAT") << "Engaged BugSplat(" << LL_TO_STRING(LL_VIEWER_CHANNEL)
|
||||
<< ' ' << stringize(version_string) << ')' << LL_ENDL;
|
||||
} // got BugSplat_DB
|
||||
} // parsed build_data.json
|
||||
|
|
@ -899,6 +915,16 @@ bool LLAppViewerWin32::cleanup()
|
|||
return result;
|
||||
}
|
||||
|
||||
void LLAppViewerWin32::reportCrashToBugsplat(void* pExcepInfo)
|
||||
{
|
||||
#if defined(LL_BUGSPLAT)
|
||||
if (sBugSplatSender)
|
||||
{
|
||||
sBugSplatSender->createReport((EXCEPTION_POINTERS*)pExcepInfo);
|
||||
}
|
||||
#endif // LL_BUGSPLAT
|
||||
}
|
||||
|
||||
void LLAppViewerWin32::initLoggingAndGetLastDuration()
|
||||
{
|
||||
LLAppViewer::initLoggingAndGetLastDuration();
|
||||
|
|
|
|||
|
|
@ -40,20 +40,22 @@ public:
|
|||
//
|
||||
// Main application logic
|
||||
//
|
||||
virtual bool init(); // Override to do application initialization
|
||||
virtual bool cleanup();
|
||||
bool init() override; // Override to do application initialization
|
||||
bool cleanup() override;
|
||||
|
||||
void reportCrashToBugsplat(void* pExcepInfo) override;
|
||||
|
||||
protected:
|
||||
virtual void initLoggingAndGetLastDuration(); // Override to clean stack_trace info.
|
||||
virtual void initConsole(); // Initialize OS level debugging console.
|
||||
virtual bool initHardwareTest(); // Win32 uses DX9 to test hardware.
|
||||
virtual bool initParseCommandLine(LLCommandLineParser& clp);
|
||||
void initLoggingAndGetLastDuration() override; // Override to clean stack_trace info.
|
||||
void initConsole() override; // Initialize OS level debugging console.
|
||||
bool initHardwareTest() override; // Win32 uses DX9 to test hardware.
|
||||
bool initParseCommandLine(LLCommandLineParser& clp) override;
|
||||
|
||||
virtual bool beingDebugged();
|
||||
virtual bool restoreErrorTrap();
|
||||
virtual void initCrashReporting(bool reportFreeze);
|
||||
bool beingDebugged() override;
|
||||
bool restoreErrorTrap() override;
|
||||
void initCrashReporting(bool reportFreeze) override;
|
||||
|
||||
virtual bool sendURLToOtherInstance(const std::string& url);
|
||||
bool sendURLToOtherInstance(const std::string& url) override;
|
||||
|
||||
std::string generateSerialNumber();
|
||||
|
||||
|
|
|
|||
|
|
@ -357,7 +357,7 @@ LLConversationItemParticipant* LLConversationItemSession::findParticipant(const
|
|||
for (iter = mChildren.begin(); iter != mChildren.end(); iter++)
|
||||
{
|
||||
participant = dynamic_cast<LLConversationItemParticipant*>(*iter);
|
||||
if (participant->hasSameValue(participant_id))
|
||||
if (participant && participant->hasSameValue(participant_id))
|
||||
{
|
||||
break;
|
||||
}
|
||||
|
|
@ -468,7 +468,7 @@ const bool LLConversationItemSession::getTime(F64& time) const
|
|||
{
|
||||
participant = dynamic_cast<LLConversationItemParticipant*>(*iter);
|
||||
F64 participant_time;
|
||||
if (participant->getTime(participant_time))
|
||||
if (participant && participant->getTime(participant_time))
|
||||
{
|
||||
has_time = true;
|
||||
most_recent_time = llmax(most_recent_time,participant_time);
|
||||
|
|
|
|||
|
|
@ -619,10 +619,13 @@ void LLConversationViewParticipant::refresh()
|
|||
{
|
||||
// Refresh the participant view from its model data
|
||||
LLConversationItemParticipant* participant_model = dynamic_cast<LLConversationItemParticipant*>(getViewModelItem());
|
||||
participant_model->resetRefresh();
|
||||
|
||||
// *TODO: We should also do something with vmi->isModerator() to echo that state in the UI somewhat
|
||||
mSpeakingIndicator->setIsModeratorMuted(participant_model->isModeratorMuted());
|
||||
if (participant_model)
|
||||
{
|
||||
participant_model->resetRefresh();
|
||||
|
||||
// *TODO: We should also do something with vmi->isModerator() to echo that state in the UI somewhat
|
||||
mSpeakingIndicator->setIsModeratorMuted(participant_model->isModeratorMuted());
|
||||
}
|
||||
|
||||
// Do the regular upstream refresh
|
||||
LLFolderViewItem::refresh();
|
||||
|
|
|
|||
|
|
@ -1110,7 +1110,7 @@ void LLEnvironment::onRegionChange()
|
|||
}
|
||||
if (!cur_region->capabilitiesReceived())
|
||||
{
|
||||
cur_region->setCapabilitiesReceivedCallback([](const LLUUID ®ion_id) { LLEnvironment::instance().requestRegion(); });
|
||||
cur_region->setCapabilitiesReceivedCallback([](const LLUUID ®ion_id, LLViewerRegion* regionp) { LLEnvironment::instance().requestRegion(); });
|
||||
return;
|
||||
}
|
||||
requestRegion();
|
||||
|
|
|
|||
|
|
@ -63,7 +63,9 @@
|
|||
#include "boost/foreach.hpp"
|
||||
|
||||
|
||||
const S32 EVENTS_PER_IDLE_LOOP = 100;
|
||||
const S32 EVENTS_PER_IDLE_LOOP_CURRENT_SESSION = 80;
|
||||
const S32 EVENTS_PER_IDLE_LOOP_BACKGROUND = 40;
|
||||
const F32 EVENTS_PER_IDLE_LOOP_MIN_PERCENTAGE = 0.01f; // process a minimum of 1% of total events per frame
|
||||
|
||||
//
|
||||
// LLFloaterIMContainer
|
||||
|
|
@ -420,8 +422,11 @@ void LLFloaterIMContainer::processParticipantsStyleUpdate()
|
|||
while (current_participant_model != end_participant_model)
|
||||
{
|
||||
LLConversationItemParticipant* participant_model = dynamic_cast<LLConversationItemParticipant*>(*current_participant_model);
|
||||
// Get the avatar name for this participant id from the cache and update the model
|
||||
participant_model->updateName();
|
||||
if (participant_model)
|
||||
{
|
||||
// Get the avatar name for this participant id from the cache and update the model
|
||||
participant_model->updateName();
|
||||
}
|
||||
// Next participant
|
||||
current_participant_model++;
|
||||
}
|
||||
|
|
@ -468,8 +473,11 @@ void LLFloaterIMContainer::idleUpdate()
|
|||
while (current_participant_model != end_participant_model)
|
||||
{
|
||||
LLConversationItemParticipant* participant_model = dynamic_cast<LLConversationItemParticipant*>(*current_participant_model);
|
||||
participant_model->setModeratorOptionsVisible(is_moderator);
|
||||
participant_model->setGroupBanVisible(can_ban && participant_model->getUUID() != gAgentID);
|
||||
if (participant_model)
|
||||
{
|
||||
participant_model->setModeratorOptionsVisible(is_moderator);
|
||||
participant_model->setGroupBanVisible(can_ban && participant_model->getUUID() != gAgentID);
|
||||
}
|
||||
|
||||
current_participant_model++;
|
||||
}
|
||||
|
|
@ -502,20 +510,49 @@ void LLFloaterIMContainer::idleUpdate()
|
|||
|
||||
void LLFloaterIMContainer::idleProcessEvents()
|
||||
{
|
||||
if (!mConversationEventQueue.empty())
|
||||
{
|
||||
S32 events_to_handle = llmin((S32)mConversationEventQueue.size(), EVENTS_PER_IDLE_LOOP);
|
||||
for (S32 i = 0; i < events_to_handle; i++)
|
||||
{
|
||||
handleConversationModelEvent(mConversationEventQueue.back());
|
||||
mConversationEventQueue.pop_back();
|
||||
}
|
||||
}
|
||||
LLUUID current_session_id = getSelectedSession();
|
||||
conversations_items_deque::iterator iter = mConversationEventQueue.begin();
|
||||
conversations_items_deque::iterator end = mConversationEventQueue.end();
|
||||
while (iter != end)
|
||||
{
|
||||
std::deque<LLSD> &events = iter->second;
|
||||
if (!events.empty())
|
||||
{
|
||||
S32 events_to_handle;
|
||||
S32 query_size = (S32)events.size();
|
||||
if (current_session_id == iter->first)
|
||||
{
|
||||
events_to_handle = EVENTS_PER_IDLE_LOOP_CURRENT_SESSION;
|
||||
}
|
||||
else
|
||||
{
|
||||
events_to_handle = EVENTS_PER_IDLE_LOOP_BACKGROUND;
|
||||
}
|
||||
|
||||
if (events_to_handle <= query_size)
|
||||
{
|
||||
// Some groups can be very large and can generate huge amount of updates, scale processing up to keep up
|
||||
events_to_handle = llmax(events_to_handle, (S32)(query_size * EVENTS_PER_IDLE_LOOP_MIN_PERCENTAGE));
|
||||
}
|
||||
else
|
||||
{
|
||||
events_to_handle = query_size;
|
||||
}
|
||||
|
||||
for (S32 i = 0; i < events_to_handle; i++)
|
||||
{
|
||||
handleConversationModelEvent(events.back());
|
||||
events.pop_back();
|
||||
}
|
||||
}
|
||||
iter++;
|
||||
}
|
||||
}
|
||||
|
||||
bool LLFloaterIMContainer::onConversationModelEvent(const LLSD& event)
|
||||
{
|
||||
mConversationEventQueue.push_front(event);
|
||||
LLUUID id = event.get("session_uuid").asUUID();
|
||||
mConversationEventQueue[id].push_front(event);
|
||||
return true;
|
||||
}
|
||||
|
||||
|
|
@ -1835,6 +1872,8 @@ bool LLFloaterIMContainer::removeConversationListItem(const LLUUID& uuid, bool c
|
|||
// Suppress the conversation items and widgets from their respective maps
|
||||
mConversationsItems.erase(uuid);
|
||||
mConversationsWidgets.erase(uuid);
|
||||
// Clear event query (otherwise reopening session in some way can bombard session with stale data)
|
||||
mConversationEventQueue.erase(uuid);
|
||||
|
||||
// Don't let the focus fall IW, select and refocus on the first conversation in the list
|
||||
if (change_focus)
|
||||
|
|
|
|||
|
|
@ -231,9 +231,10 @@ private:
|
|||
conversations_widgets_map mConversationsWidgets;
|
||||
LLConversationViewModel mConversationViewModel;
|
||||
LLFolderView* mConversationsRoot;
|
||||
LLEventStream mConversationsEventStream;
|
||||
LLEventStream mConversationsEventStream;
|
||||
|
||||
std::deque<LLSD> mConversationEventQueue;
|
||||
typedef std::map<LLUUID, std::deque<LLSD> > conversations_items_deque;
|
||||
conversations_items_deque mConversationEventQueue;
|
||||
|
||||
LLTimer mParticipantRefreshTimer;
|
||||
};
|
||||
|
|
|
|||
|
|
@ -494,7 +494,10 @@ void LLFloaterIMSessionTab::buildConversationViewParticipant()
|
|||
while (current_participant_model != end_participant_model)
|
||||
{
|
||||
LLConversationItem* participant_model = dynamic_cast<LLConversationItem*>(*current_participant_model);
|
||||
addConversationViewParticipant(participant_model);
|
||||
if (participant_model)
|
||||
{
|
||||
addConversationViewParticipant(participant_model);
|
||||
}
|
||||
current_participant_model++;
|
||||
}
|
||||
}
|
||||
|
|
@ -531,7 +534,7 @@ void LLFloaterIMSessionTab::removeConversationViewParticipant(const LLUUID& part
|
|||
LLFolderViewItem* widget = get_ptr_in_map(mConversationsWidgets,participant_id);
|
||||
if (widget)
|
||||
{
|
||||
mConversationsRoot->extractItem(widget);
|
||||
mConversationsRoot->extractItem(widget, false);
|
||||
delete widget;
|
||||
}
|
||||
mConversationsWidgets.erase(participant_id);
|
||||
|
|
|
|||
|
|
@ -1261,6 +1261,7 @@ void LLViewerMedia::getOpenIDCookieCoro(std::string url)
|
|||
|
||||
httpOpts->setFollowRedirects(true);
|
||||
httpOpts->setWantHeaders(true);
|
||||
httpOpts->setSSLVerifyPeer(false); // viewer's cert bundle doesn't appear to agree with web certs from "https://my.secondlife.com/"
|
||||
|
||||
LLURL hostUrl(url.c_str());
|
||||
std::string hostAuth = hostUrl.getAuthority();
|
||||
|
|
|
|||
|
|
@ -347,6 +347,8 @@ void force_error_bad_memory_access(void *);
|
|||
void force_error_infinite_loop(void *);
|
||||
void force_error_software_exception(void *);
|
||||
void force_error_driver_crash(void *);
|
||||
void force_error_coroutine_crash(void *);
|
||||
void force_error_thread_crash(void *);
|
||||
|
||||
void handle_force_delete(void*);
|
||||
void print_object_info(void*);
|
||||
|
|
@ -2658,6 +2660,24 @@ class LLAdvancedForceErrorDriverCrash : public view_listener_t
|
|||
}
|
||||
};
|
||||
|
||||
class LLAdvancedForceErrorCoroutineCrash : public view_listener_t
|
||||
{
|
||||
bool handleEvent(const LLSD& userdata)
|
||||
{
|
||||
force_error_coroutine_crash(NULL);
|
||||
return true;
|
||||
}
|
||||
};
|
||||
|
||||
class LLAdvancedForceErrorThreadCrash : public view_listener_t
|
||||
{
|
||||
bool handleEvent(const LLSD& userdata)
|
||||
{
|
||||
force_error_thread_crash(NULL);
|
||||
return true;
|
||||
}
|
||||
};
|
||||
|
||||
class LLAdvancedForceErrorDisconnectViewer : public view_listener_t
|
||||
{
|
||||
bool handleEvent(const LLSD& userdata)
|
||||
|
|
@ -10257,6 +10277,16 @@ void force_error_driver_crash(void *)
|
|||
LLAppViewer::instance()->forceErrorDriverCrash();
|
||||
}
|
||||
|
||||
void force_error_coroutine_crash(void *)
|
||||
{
|
||||
LLAppViewer::instance()->forceErrorCoroutineCrash();
|
||||
}
|
||||
|
||||
void force_error_thread_crash(void *)
|
||||
{
|
||||
LLAppViewer::instance()->forceErrorThreadCrash();
|
||||
}
|
||||
|
||||
class LLToolsUseSelectionForGrid : public view_listener_t
|
||||
{
|
||||
bool handleEvent(const LLSD& userdata)
|
||||
|
|
@ -11840,6 +11870,8 @@ void initialize_menus()
|
|||
view_listener_t::addMenu(new LLAdvancedForceErrorInfiniteLoop(), "Advanced.ForceErrorInfiniteLoop");
|
||||
view_listener_t::addMenu(new LLAdvancedForceErrorSoftwareException(), "Advanced.ForceErrorSoftwareException");
|
||||
view_listener_t::addMenu(new LLAdvancedForceErrorDriverCrash(), "Advanced.ForceErrorDriverCrash");
|
||||
view_listener_t::addMenu(new LLAdvancedForceErrorCoroutineCrash(), "Advanced.ForceErrorCoroutineCrash");
|
||||
view_listener_t::addMenu(new LLAdvancedForceErrorThreadCrash(), "Advanced.ForceErrorThreadCrash");
|
||||
view_listener_t::addMenu(new LLAdvancedForceErrorDisconnectViewer(), "Advanced.ForceErrorDisconnectViewer");
|
||||
|
||||
// Advanced (toplevel)
|
||||
|
|
|
|||
|
|
@ -2407,7 +2407,7 @@ void LLViewerRegion::setSimulatorFeaturesReceived(bool received)
|
|||
mSimulatorFeaturesReceived = received;
|
||||
if (received)
|
||||
{
|
||||
mSimulatorFeaturesReceivedSignal(getRegionID());
|
||||
mSimulatorFeaturesReceivedSignal(getRegionID(), this);
|
||||
mSimulatorFeaturesReceivedSignal.disconnect_all_slots();
|
||||
}
|
||||
}
|
||||
|
|
@ -3421,7 +3421,7 @@ void LLViewerRegion::setCapabilitiesReceived(bool received)
|
|||
// so that they can safely use getCapability().
|
||||
if (received)
|
||||
{
|
||||
mCapabilitiesReceivedSignal(getRegionID());
|
||||
mCapabilitiesReceivedSignal(getRegionID(), this);
|
||||
|
||||
LLFloaterPermsDefault::sendInitialPerms();
|
||||
|
||||
|
|
|
|||
|
|
@ -97,7 +97,7 @@ public:
|
|||
NUM_PARTITIONS
|
||||
} eObjectPartitions;
|
||||
|
||||
typedef boost::signals2::signal<void(const LLUUID& region_id)> caps_received_signal_t;
|
||||
typedef boost::signals2::signal<void(const LLUUID& region_id, LLViewerRegion* regionp)> caps_received_signal_t;
|
||||
|
||||
LLViewerRegion(const U64 &handle,
|
||||
const LLHost &host,
|
||||
|
|
|
|||
|
|
@ -113,6 +113,7 @@ void LLWebProfile::uploadImageCoro(LLPointer<LLImageFormatted> image, std::strin
|
|||
|
||||
httpOpts->setWantHeaders(true);
|
||||
httpOpts->setFollowRedirects(false);
|
||||
httpOpts->setSSLVerifyPeer(false); ; // viewer's cert bundle doesn't appear to agree with web certs from "https://my.secondlife.com/"
|
||||
|
||||
// Get upload configuration data.
|
||||
std::string configUrl(getProfileURL(std::string()) + "snapshots/s3_upload_config");
|
||||
|
|
|
|||
|
|
@ -51,7 +51,7 @@ bool LLEnvironmentRequest::initiate(LLEnvironment::environment_apply_fn cb)
|
|||
if (!cur_region->capabilitiesReceived())
|
||||
{
|
||||
LL_INFOS("WindlightCaps") << "Deferring windlight settings request until we've got region caps" << LL_ENDL;
|
||||
cur_region->setCapabilitiesReceivedCallback([cb](const LLUUID ®ion_id) { LLEnvironmentRequest::onRegionCapsReceived(region_id, cb); });
|
||||
cur_region->setCapabilitiesReceivedCallback([cb](const LLUUID ®ion_id, LLViewerRegion* regionp) { LLEnvironmentRequest::onRegionCapsReceived(region_id, cb); });
|
||||
return false;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -3642,6 +3642,18 @@
|
|||
<menu_item_call.on_click
|
||||
function="Advanced.ForceErrorSoftwareException" />
|
||||
</menu_item_call>
|
||||
<menu_item_call
|
||||
label="Force a Crash in a Coroutine"
|
||||
name="Force a Crash in a Coroutine">
|
||||
<menu_item_call.on_click
|
||||
function="Advanced.ForceErrorCoroutineCrash" />
|
||||
</menu_item_call>
|
||||
<menu_item_call
|
||||
label="Force a Crash in a Thread"
|
||||
name="Force a Crash in a Thread">
|
||||
<menu_item_call.on_click
|
||||
function="Advanced.ForceErrorThreadCrash" />
|
||||
</menu_item_call>
|
||||
<menu_item_call
|
||||
label="Force Disconnect Viewer"
|
||||
name="Force Disconnect Viewer">
|
||||
|
|
|
|||
Loading…
Reference in New Issue