From 803b75a718833ccf236f00b425faff4eaf0f29cb Mon Sep 17 00:00:00 2001 From: callum_linden Date: Wed, 18 Oct 2017 18:36:10 -0700 Subject: First version that builds with a dummy BugSplay call in llapp.cpp --- indra/llcommon/CMakeLists.txt | 3 +++ indra/llcommon/llapp.cpp | 12 ++++++++++++ 2 files changed, 15 insertions(+) (limited to 'indra/llcommon') diff --git a/indra/llcommon/CMakeLists.txt b/indra/llcommon/CMakeLists.txt index d9eb13d65a..50e262ae7a 100644 --- a/indra/llcommon/CMakeLists.txt +++ b/indra/llcommon/CMakeLists.txt @@ -13,6 +13,7 @@ include(GoogleBreakpad) include(Copy3rdPartyLibs) include(ZLIB) include(URIPARSER) +include(BUGSPLAT) include_directories( ${EXPAT_INCLUDE_DIRS} @@ -21,6 +22,7 @@ include_directories( ${ZLIB_INCLUDE_DIRS} ${BREAKPAD_INCLUDE_DIRECTORIES} ${URIPARSER_INCLUDE_DIRS} + ${BUGSPLAT_INCLUDE_DIR} ) # add_executable(lltreeiterators lltreeiterators.cpp) @@ -291,6 +293,7 @@ target_link_libraries( ${BOOST_SYSTEM_LIBRARY} ${GOOGLE_PERFTOOLS_LIBRARIES} ${URIPARSER_LIBRARIES} + ${BUGSPLAT_LIBRARIES} ) if (DARWIN) diff --git a/indra/llcommon/llapp.cpp b/indra/llcommon/llapp.cpp index 6cc9e804d4..9dd9fc3c70 100644 --- a/indra/llcommon/llapp.cpp +++ b/indra/llcommon/llapp.cpp @@ -50,6 +50,10 @@ #include "stringize.h" #include "llcleanup.h" +#include "BugSplat.h" + +MiniDmpSender *mpSender; + // // Signal handling // @@ -151,6 +155,14 @@ void LLApp::commonCtor() // (this is used to avoid allocating memory in the crash handler) memset(mMinidumpPath, 0, MAX_MINDUMP_PATH_LENGTH); mCrashReportPipeStr = L"\\\\.\\pipe\\LLCrashReporterPipe"; + + + static const wchar_t *bugdb_name = L"second_life_callum_test"; + static const wchar_t *app_name = L"SecondLifeViewer"; + static const wchar_t *app_version = L"1.0.0"; + mpSender = new MiniDmpSender((const __wchar_t *)bugdb_name, (const __wchar_t *)app_name, (const __wchar_t *)app_version, NULL); + + } LLApp::LLApp(LLErrorThread *error_thread) : -- cgit v1.3 From e75b16f3584b76df706a470395383abf680eb87f Mon Sep 17 00:00:00 2001 From: callum_linden Date: Thu, 19 Oct 2017 11:34:36 -0700 Subject: First pass at adding BugSplat code to viewer and turning off existing (Google Breakpad) exception handling --- indra/llcommon/llapp.cpp | 76 +++++++++++++++++++++++++++++++++++++++--------- indra/llcommon/llapp.h | 10 ++++++- 2 files changed, 72 insertions(+), 14 deletions(-) (limited to 'indra/llcommon') diff --git a/indra/llcommon/llapp.cpp b/indra/llcommon/llapp.cpp index 9dd9fc3c70..ea4a0fb59c 100644 --- a/indra/llcommon/llapp.cpp +++ b/indra/llcommon/llapp.cpp @@ -49,10 +49,20 @@ #include "google_breakpad/exception_handler.h" #include "stringize.h" #include "llcleanup.h" - #include "BugSplat.h" -MiniDmpSender *mpSender; +// TESTING ONLY - REMOVE FOR PRODUCTION +// (Want to only invoke BugSplat crash reporting in the same way we did for Breakpad - for Release viewers +// but need to test here in a ReleaseWithDebugInfo environment) +#if BUGSPLAT_ENABLED +#define LL_SEND_CRASH_REPORTS 1 +#endif + +// BugSplat crash reporting tool - http://bugsplat.com +#if BUGSPLAT_ENABLED +bool BugSplatExceptionCallback(unsigned int nCode, void* lpVal1, void* lpVal2); +MiniDmpSender *gBugSplatSender; +#endif // // Signal handling @@ -155,14 +165,6 @@ void LLApp::commonCtor() // (this is used to avoid allocating memory in the crash handler) memset(mMinidumpPath, 0, MAX_MINDUMP_PATH_LENGTH); mCrashReportPipeStr = L"\\\\.\\pipe\\LLCrashReporterPipe"; - - - static const wchar_t *bugdb_name = L"second_life_callum_test"; - static const wchar_t *app_name = L"SecondLifeViewer"; - static const wchar_t *app_version = L"1.0.0"; - mpSender = new MiniDmpSender((const __wchar_t *)bugdb_name, (const __wchar_t *)app_name, (const __wchar_t *)app_version, NULL); - - } LLApp::LLApp(LLErrorThread *error_thread) : @@ -397,6 +399,42 @@ void EnableCrashingOnCrashes() } #endif +#if BUGSPLAT_ENABLED +bool BugSplatExceptionCallback(unsigned int nCode, void* lpVal1, void* lpVal2) +{ + switch (nCode) + { + case MDSCB_EXCEPTIONCODE: + { + EXCEPTION_RECORD *p = (EXCEPTION_RECORD *)lpVal1; + DWORD code = p ? p->ExceptionCode : 0; + + // create some files in the %temp% directory and attach them + wchar_t cmdString[2 * MAX_PATH]; + wchar_t filePath[MAX_PATH]; + wchar_t tempPath[MAX_PATH]; + GetTempPathW(MAX_PATH, tempPath); + + wsprintf(filePath, L"%sfile1.txt", tempPath); + wsprintf(cmdString, L"echo Exception Code = 0x%08x > %s", code, filePath); + _wsystem(cmdString); + gBugSplatSender->sendAdditionalFile((const __wchar_t *)filePath); + + wsprintf(filePath, L"%sfile2.txt", tempPath); + wchar_t buf[_MAX_PATH]; + gBugSplatSender->getMinidumpPath((__wchar_t *)buf, _MAX_PATH); + + wsprintf(cmdString, L"echo Crash reporting is so clutch! minidump path = %s > %s", buf, filePath); + _wsystem(cmdString); + gBugSplatSender->sendAdditionalFile((const __wchar_t *)filePath); + } + break; + } + + return false; +} +#endif + void LLApp::setupErrorHandling(bool second_instance) { // Error handling is done by starting up an error handling thread, which just sleeps and @@ -405,6 +443,17 @@ void LLApp::setupErrorHandling(bool second_instance) #if LL_WINDOWS #if LL_SEND_CRASH_REPORTS + +#if BUGSPLAT_ENABLED + // TODOCP: populate these fields correctly + static const wchar_t *bugdb_name = L"second_life_callum_test"; + static const wchar_t *app_name = L"SecondLifeViewer"; + static const wchar_t *app_version = L"1.0.0"; + gBugSplatSender = new MiniDmpSender((const __wchar_t *)bugdb_name, (const __wchar_t *)app_name, (const __wchar_t *)app_version, NULL); + + gBugSplatSender->setCallback(BugSplatExceptionCallback); +#else + EnableCrashingOnCrashes(); // This sets a callback to handle w32 signals to the console window. @@ -466,8 +515,9 @@ void LLApp::setupErrorHandling(bool second_instance) mExceptionHandler->set_handle_debug_exceptions(true); } } -#endif -#else +#endif // BUGSPLAT_ENABLED +#endif // LL_SEND_CRASH_REPORTS +#else // not LL_WINDOWS // // Start up signal handling. // @@ -528,7 +578,7 @@ void LLApp::setupErrorHandling(bool second_instance) } #endif -#endif +#endif // LL_WINDOWS startErrorThread(); } diff --git a/indra/llcommon/llapp.h b/indra/llcommon/llapp.h index acd829d864..5a4b7f13df 100644 --- a/indra/llcommon/llapp.h +++ b/indra/llcommon/llapp.h @@ -30,6 +30,7 @@ #include #include "llrun.h" #include "llsd.h" + // Forward declarations template class LLAtomic32; typedef LLAtomic32 LLAtomicU32; @@ -39,6 +40,14 @@ class LLLiveFile; #include #endif +// first version of Bugsplat (http://bugsplat.com) crash reporting tool +// is only supported on Windows - macOS to follow. +#define BUGSPLAT_ENABLED LL_WINDOWS + +#if BUGSPLAT_ENABLED +class __declspec(dllexport) MiniDmpSender; +#endif + typedef void (*LLAppErrorHandler)(); #if !LL_WINDOWS @@ -316,7 +325,6 @@ private: google_breakpad::ExceptionHandler * mExceptionHandler; - #if !LL_WINDOWS friend void default_unix_signal_handler(int signum, siginfo_t *info, void *); #endif -- cgit v1.3 From d359dca06518d778c0f115afec8c759ca026de47 Mon Sep 17 00:00:00 2001 From: callum_linden Date: Tue, 24 Oct 2017 14:28:43 -0700 Subject: painfully add in the path to the second life log file that we also send - painful because of string <--> wstring issues --- indra/llcommon/llapp.cpp | 26 +++++--------------------- 1 file changed, 5 insertions(+), 21 deletions(-) (limited to 'indra/llcommon') diff --git a/indra/llcommon/llapp.cpp b/indra/llcommon/llapp.cpp index ea4a0fb59c..6ea1700ea8 100644 --- a/indra/llcommon/llapp.cpp +++ b/indra/llcommon/llapp.cpp @@ -406,27 +406,11 @@ bool BugSplatExceptionCallback(unsigned int nCode, void* lpVal1, void* lpVal2) { case MDSCB_EXCEPTIONCODE: { - EXCEPTION_RECORD *p = (EXCEPTION_RECORD *)lpVal1; - DWORD code = p ? p->ExceptionCode : 0; - - // create some files in the %temp% directory and attach them - wchar_t cmdString[2 * MAX_PATH]; - wchar_t filePath[MAX_PATH]; - wchar_t tempPath[MAX_PATH]; - GetTempPathW(MAX_PATH, tempPath); - - wsprintf(filePath, L"%sfile1.txt", tempPath); - wsprintf(cmdString, L"echo Exception Code = 0x%08x > %s", code, filePath); - _wsystem(cmdString); - gBugSplatSender->sendAdditionalFile((const __wchar_t *)filePath); - - wsprintf(filePath, L"%sfile2.txt", tempPath); - wchar_t buf[_MAX_PATH]; - gBugSplatSender->getMinidumpPath((__wchar_t *)buf, _MAX_PATH); - - wsprintf(cmdString, L"echo Crash reporting is so clutch! minidump path = %s > %s", buf, filePath); - _wsystem(cmdString); - gBugSplatSender->sendAdditionalFile((const __wchar_t *)filePath); + // send the main viewer log file (Clearly a temporary hack since we don't have access to the gDir*** set of functions in newview + const std::string appdata = std::string(getenv("APPDATA")); + const std::string logfile = appdata + "\\SecondLife\\logs\\Secondlife.log"; + const std::wstring wide_logfile(logfile.begin(), logfile.end()); + gBugSplatSender->sendAdditionalFile((const __wchar_t *)wide_logfile.c_str()); } break; } -- cgit v1.3 From 2e3c5ac88a434ee437bc3e68b321d5bd0bcd7cc9 Mon Sep 17 00:00:00 2001 From: callum_linden Date: Tue, 24 Oct 2017 16:13:23 -0700 Subject: Add in real SL viewer name and version --- indra/llcommon/CMakeLists.txt | 10 +++++++++- indra/llcommon/llapp.cpp | 14 +++++++++++--- 2 files changed, 20 insertions(+), 4 deletions(-) (limited to 'indra/llcommon') diff --git a/indra/llcommon/CMakeLists.txt b/indra/llcommon/CMakeLists.txt index 50e262ae7a..9c5481a977 100644 --- a/indra/llcommon/CMakeLists.txt +++ b/indra/llcommon/CMakeLists.txt @@ -14,6 +14,7 @@ include(Copy3rdPartyLibs) include(ZLIB) include(URIPARSER) include(BUGSPLAT) +include(BuildVersion) include_directories( ${EXPAT_INCLUDE_DIRS} @@ -255,7 +256,14 @@ set(llcommon_HEADER_FILES ) set_source_files_properties(${llcommon_HEADER_FILES} - PROPERTIES HEADER_FILE_ONLY TRUE) + PROPERTIES HEADER_FILE_ONLY TRUE + ) + +# bring in version information for BugSplat crash reporting +set_source_files_properties(${llcommon_SOURCE_FILES} + PROPERTIES + COMPILE_DEFINITIONS "${VIEWER_CHANNEL_VERSION_DEFINES}" # see BuildVersion.cmake + ) list(APPEND llcommon_SOURCE_FILES ${llcommon_HEADER_FILES}) diff --git a/indra/llcommon/llapp.cpp b/indra/llcommon/llapp.cpp index 6ea1700ea8..3e652dbdb5 100644 --- a/indra/llcommon/llapp.cpp +++ b/indra/llcommon/llapp.cpp @@ -431,9 +431,17 @@ void LLApp::setupErrorHandling(bool second_instance) #if BUGSPLAT_ENABLED // TODOCP: populate these fields correctly static const wchar_t *bugdb_name = L"second_life_callum_test"; - static const wchar_t *app_name = L"SecondLifeViewer"; - static const wchar_t *app_version = L"1.0.0"; - gBugSplatSender = new MiniDmpSender((const __wchar_t *)bugdb_name, (const __wchar_t *)app_name, (const __wchar_t *)app_version, NULL); + + // build (painfully) the app/channel name + #define stringize_inner(x) L#x + #define stringize_outer(x) stringize_inner(x) + std::wstring app_name(stringize_outer(LL_VIEWER_CHANNEL)); + + // build in real app version now we leveraged CMake to build in BuildVersion.cmake into LLCommon + wchar_t version_string[MAX_STRING]; + wsprintf(version_string, L"%d.%d.%d.%d", LL_VIEWER_VERSION_MAJOR, LL_VIEWER_VERSION_MINOR, LL_VIEWER_VERSION_PATCH, LL_VIEWER_VERSION_BUILD); + + gBugSplatSender = new MiniDmpSender((const __wchar_t *)bugdb_name, (const __wchar_t *)app_name.c_str(), (const __wchar_t *)version_string, NULL); gBugSplatSender->setCallback(BugSplatExceptionCallback); #else -- cgit v1.3 From 508e754eb4501b9c3fbfbfde52ca7ae8ed0f06b7 Mon Sep 17 00:00:00 2001 From: Oz Linden Date: Thu, 14 Dec 2017 18:12:22 -0500 Subject: fix tab character coding style violation --- indra/llcommon/CMakeLists.txt | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'indra/llcommon') diff --git a/indra/llcommon/CMakeLists.txt b/indra/llcommon/CMakeLists.txt index 9c5481a977..c8e44d7ba4 100644 --- a/indra/llcommon/CMakeLists.txt +++ b/indra/llcommon/CMakeLists.txt @@ -257,13 +257,13 @@ set(llcommon_HEADER_FILES set_source_files_properties(${llcommon_HEADER_FILES} PROPERTIES HEADER_FILE_ONLY TRUE - ) + ) # bring in version information for BugSplat crash reporting set_source_files_properties(${llcommon_SOURCE_FILES} PROPERTIES - COMPILE_DEFINITIONS "${VIEWER_CHANNEL_VERSION_DEFINES}" # see BuildVersion.cmake - ) + COMPILE_DEFINITIONS "${VIEWER_CHANNEL_VERSION_DEFINES}" # see BuildVersion.cmake + ) list(APPEND llcommon_SOURCE_FILES ${llcommon_HEADER_FILES}) -- cgit v1.3 From 3de5bab17459ed5bf0494d7bd2a531c473e20b7e Mon Sep 17 00:00:00 2001 From: Nat Goodspeed Date: Fri, 11 May 2018 16:00:20 -0400 Subject: SL-821: Move BugSplat includes/libs from llcommon to newview. No C++ source in llcommon references any of the BugSplat code. --- indra/llcommon/CMakeLists.txt | 3 --- indra/newview/CMakeLists.txt | 3 +++ 2 files changed, 3 insertions(+), 3 deletions(-) (limited to 'indra/llcommon') diff --git a/indra/llcommon/CMakeLists.txt b/indra/llcommon/CMakeLists.txt index c8e44d7ba4..4eba1d5451 100644 --- a/indra/llcommon/CMakeLists.txt +++ b/indra/llcommon/CMakeLists.txt @@ -13,7 +13,6 @@ include(GoogleBreakpad) include(Copy3rdPartyLibs) include(ZLIB) include(URIPARSER) -include(BUGSPLAT) include(BuildVersion) include_directories( @@ -23,7 +22,6 @@ include_directories( ${ZLIB_INCLUDE_DIRS} ${BREAKPAD_INCLUDE_DIRECTORIES} ${URIPARSER_INCLUDE_DIRS} - ${BUGSPLAT_INCLUDE_DIR} ) # add_executable(lltreeiterators lltreeiterators.cpp) @@ -301,7 +299,6 @@ target_link_libraries( ${BOOST_SYSTEM_LIBRARY} ${GOOGLE_PERFTOOLS_LIBRARIES} ${URIPARSER_LIBRARIES} - ${BUGSPLAT_LIBRARIES} ) if (DARWIN) diff --git a/indra/newview/CMakeLists.txt b/indra/newview/CMakeLists.txt index 6b16713add..1fd0af0558 100644 --- a/indra/newview/CMakeLists.txt +++ b/indra/newview/CMakeLists.txt @@ -4,6 +4,7 @@ project(viewer) include(00-Common) include(Boost) +include(bugsplat) include(BuildPackagesInfo) include(BuildVersion) include(CMakeCopyIfDifferent) @@ -91,6 +92,7 @@ include_directories( ${LIBS_PREBUILT_DIR}/include/collada/1.4 ${LLAPPEARANCE_INCLUDE_DIRS} ${CMAKE_CURRENT_SOURCE_DIR} + ${BUGSPLAT_INCLUDE_DIR} ) include_directories(SYSTEM @@ -1976,6 +1978,7 @@ target_link_libraries(${VIEWER_BINARY_NAME} ${LLPHYSICS_LIBRARIES} ${LLPHYSICSEXTENSIONS_LIBRARIES} ${LLAPPEARANCE_LIBRARIES} + ${BUGSPLAT_LIBRARIES} ) set(ARTWORK_DIR ${CMAKE_CURRENT_SOURCE_DIR} CACHE PATH -- cgit v1.3 From ed891c60de4169fa8ef4cc19e953e389cc4df60e Mon Sep 17 00:00:00 2001 From: Nat Goodspeed Date: Thu, 17 May 2018 05:33:14 -0400 Subject: SL-821: Add LL_TO_WSTRING() macro to llpreprocessor.h. Also use existing LL_TO_STRING() macro to stringize LL_VIEWER_CHANNEL in llversioninfo.cpp and its tests. --- indra/llcommon/llpreprocessor.h | 2 ++ indra/newview/llversioninfo.cpp | 7 ++----- indra/newview/tests/llversioninfo_test.cpp | 6 ++---- 3 files changed, 6 insertions(+), 9 deletions(-) (limited to 'indra/llcommon') diff --git a/indra/llcommon/llpreprocessor.h b/indra/llcommon/llpreprocessor.h index 2879038c36..ef015fdce4 100644 --- a/indra/llcommon/llpreprocessor.h +++ b/indra/llcommon/llpreprocessor.h @@ -198,6 +198,8 @@ #define LL_TO_STRING_HELPER(x) #x #define LL_TO_STRING(x) LL_TO_STRING_HELPER(x) +#define LL_TO_WSTRING_HELPER(x) L#x +#define LL_TO_WSTRING(x) LL_TO_WSTRING_HELPER(x) #define LL_FILE_LINENO_MSG(msg) __FILE__ "(" LL_TO_STRING(__LINE__) ") : " msg #define LL_GLUE_IMPL(x, y) x##y #define LL_GLUE_TOKENS(x, y) LL_GLUE_IMPL(x, y) diff --git a/indra/newview/llversioninfo.cpp b/indra/newview/llversioninfo.cpp index 375dce485d..4e07223784 100644 --- a/indra/newview/llversioninfo.cpp +++ b/indra/newview/llversioninfo.cpp @@ -101,14 +101,11 @@ namespace { // LL_VIEWER_CHANNEL is a macro defined on the compiler command line. The // macro expands to the string name of the channel, but without quotes. We - // need to turn it into a quoted string. This macro trick does that. -#define stringize_inner(x) #x -#define stringize_outer(x) stringize_inner(x) - + // need to turn it into a quoted string. LL_TO_STRING() does that. /// Storage of the channel name the viewer is using. // The channel name is set by hardcoded constant, // or by calling LLVersionInfo::resetChannel() - std::string sWorkingChannelName(stringize_outer(LL_VIEWER_CHANNEL)); + std::string sWorkingChannelName(LL_TO_STRING(LL_VIEWER_CHANNEL)); // Storage for the "version and channel" string. // This will get reset too. diff --git a/indra/newview/tests/llversioninfo_test.cpp b/indra/newview/tests/llversioninfo_test.cpp index 2f7a4e9601..58f0469552 100644 --- a/indra/newview/tests/llversioninfo_test.cpp +++ b/indra/newview/tests/llversioninfo_test.cpp @@ -33,10 +33,8 @@ // LL_VIEWER_CHANNEL is a macro defined on the compiler command line. The // macro expands to the string name of the channel, but without quotes. We -// need to turn it into a quoted string. This macro trick does that. -#define stringize_inner(x) #x -#define stringize_outer(x) stringize_inner(x) -#define ll_viewer_channel stringize_outer(LL_VIEWER_CHANNEL) +// need to turn it into a quoted string. LL_TO_STRING() does that. +#define ll_viewer_channel LL_TO_STRING(LL_VIEWER_CHANNEL) namespace tut { -- cgit v1.3 From c09d9c12e79fde83a87b2394c88b32e568271eda Mon Sep 17 00:00:00 2001 From: Nat Goodspeed Date: Thu, 17 May 2018 05:45:36 -0400 Subject: SL-821: Add WSTRINGIZE() and DEWSTRINGIZE() macros for wide strings. Streamline convenience overload stringize(std::wstring); make convenience overload wstringize(std::string) symmetrically convert from UTF-8 string. Also eliminate STRINGIZE() et al. dependency on Boost.Phoenix: use lambdas instead. Using lambdas instead of template expansion necessitates reordering some code in wrapllerrs.h. --- indra/llcommon/stringize.h | 52 ++++++++++++++++++++++----------------- indra/llcommon/tests/wrapllerrs.h | 14 +++++------ 2 files changed, 36 insertions(+), 30 deletions(-) (limited to 'indra/llcommon') diff --git a/indra/llcommon/stringize.h b/indra/llcommon/stringize.h index a5a90d7297..38dd198ad3 100644 --- a/indra/llcommon/stringize.h +++ b/indra/llcommon/stringize.h @@ -30,7 +30,6 @@ #define LL_STRINGIZE_H #include -#include #include /** @@ -53,12 +52,7 @@ std::basic_string gstringize(const T& item) */ inline std::string stringize(const std::wstring& item) { - LL_WARNS() << "WARNING: Possible narrowing" << LL_ENDL; - - std::string s; - - s = wstring_to_utf8str(item); - return gstringize(s); + return wstring_to_utf8str(item); } /** @@ -76,7 +70,10 @@ std::string stringize(const T& item) */ inline std::wstring wstringize(const std::string& item) { - return gstringize(item.c_str()); + // utf8str_to_wstring() returns LLWString, which isn't necessarily the + // same as std::wstring + LLWString s(utf8str_to_wstring(item)); + return std::wstring(s.begin(), s.end()); } /** @@ -91,10 +88,10 @@ std::wstring wstringize(const T& item) /** * stringize_f(functor) */ -template -std::string stringize_f(Functor const & f) +template +std::basic_string stringize_f(Functor const & f) { - std::ostringstream out; + std::basic_ostringstream out; f(out); return out.str(); } @@ -108,31 +105,37 @@ std::string stringize_f(Functor const & f) * return out.str(); * @endcode */ -#define STRINGIZE(EXPRESSION) (stringize_f(boost::phoenix::placeholders::arg1 << EXPRESSION)) +#define STRINGIZE(EXPRESSION) (stringize_f([&](std::ostream& out){ out << EXPRESSION; })) +/** + * WSTRINGIZE() is the wstring equivalent of STRINGIZE() + */ +#define WSTRINGIZE(EXPRESSION) (stringize_f([&](std::wostream& out){ out << EXPRESSION; })) /** * destringize(str) * defined for symmetry with stringize - * *NOTE - this has distinct behavior from boost::lexical_cast regarding + * @NOTE - this has distinct behavior from boost::lexical_cast regarding * leading/trailing whitespace and handling of bad_lexical_cast exceptions + * @NOTE - no need for dewstringize(), since passing std::wstring will Do The + * Right Thing */ -template -T destringize(std::string const & str) +template +T destringize(std::basic_string const & str) { - T val; - std::istringstream in(str); - in >> val; + T val; + std::basic_istringstream in(str); + in >> val; return val; } /** * destringize_f(str, functor) */ -template -void destringize_f(std::string const & str, Functor const & f) +template +void destringize_f(std::basic_string const & str, Functor const & f) { - std::istringstream in(str); + std::basic_istringstream in(str); f(in); } @@ -143,8 +146,11 @@ void destringize_f(std::string const & str, Functor const & f) * std::istringstream in(str); * in >> item1 >> item2 >> item3 ... ; * @endcode + * @NOTE - once we get generic lambdas, we shouldn't need DEWSTRINGIZE() any + * more since DESTRINGIZE() should do the right thing with a std::wstring. But + * until then, the lambda we pass must accept the right std::basic_istream. */ -#define DESTRINGIZE(STR, EXPRESSION) (destringize_f((STR), (boost::phoenix::placeholders::arg1 >> EXPRESSION))) - +#define DESTRINGIZE(STR, EXPRESSION) (destringize_f((STR), [&](std::istream& in){in >> EXPRESSION;})) +#define DEWSTRINGIZE(STR, EXPRESSION) (destringize_f((STR), [&](std::wistream& in){in >> EXPRESSION;})) #endif /* ! defined(LL_STRINGIZE_H) */ diff --git a/indra/llcommon/tests/wrapllerrs.h b/indra/llcommon/tests/wrapllerrs.h index 9a4bbbd630..08fbf19b1c 100644 --- a/indra/llcommon/tests/wrapllerrs.h +++ b/indra/llcommon/tests/wrapllerrs.h @@ -109,6 +109,12 @@ public: mMessages.push_back(message); } + friend inline + std::ostream& operator<<(std::ostream& out, const CaptureLogRecorder& log) + { + return log.streamto(out); + } + /// Don't assume the message we want is necessarily the LAST log message /// emitted by the underlying code; search backwards through all messages /// for the sought string. @@ -126,7 +132,7 @@ public: throw tut::failure(STRINGIZE("failed to find '" << search << "' in captured log messages:\n" - << boost::ref(*this))); + << *this)); } std::ostream& streamto(std::ostream& out) const @@ -200,10 +206,4 @@ private: LLError::RecorderPtr mRecorder; }; -inline -std::ostream& operator<<(std::ostream& out, const CaptureLogRecorder& log) -{ - return log.streamto(out); -} - #endif /* ! defined(LL_WRAPLLERRS_H) */ -- cgit v1.3 From c5f618d096f05bdff91a5d384c46e26840f5a771 Mon Sep 17 00:00:00 2001 From: Nat Goodspeed Date: Thu, 17 May 2018 06:53:42 -0400 Subject: SL-821: Move Windows BugSplat engagement from llcommon to newview. Use WSTRINGIZE(), LL_TO_WSTRING(), wstringize() to produce required wide strings. Use a lambda for callback that sends log file; use LLDir, if set, to find the log file. Introduce BUGSPLAT CMake variable to allow suppressing BugSplat. Make BUGSPLAT CMake variable set LL_BUGSPLAT for C++ compilations. Set viewer version macros on llappviewerwin32.cpp, llappviewerlinux.cpp and llappdelegate-objc.mm -- because BugSplat needs the viewer version data, and because the macOS BugSplat hook is engaged in an Objective-C++ function we override in the app delegate. --- indra/cmake/CMakeLists.txt | 1 + indra/cmake/bugsplat.cmake | 46 +++++++++++++++++------------ indra/llcommon/CMakeLists.txt | 10 +------ indra/llcommon/llapp.cpp | 60 ++------------------------------------ indra/llcommon/llapp.h | 10 +------ indra/newview/CMakeLists.txt | 23 ++++++++++++++- indra/newview/llappviewerwin32.cpp | 49 ++++++++++++++++++++++++++++--- 7 files changed, 101 insertions(+), 98 deletions(-) (limited to 'indra/llcommon') diff --git a/indra/cmake/CMakeLists.txt b/indra/cmake/CMakeLists.txt index 4a3ebe4835..84e1c5d6fd 100644 --- a/indra/cmake/CMakeLists.txt +++ b/indra/cmake/CMakeLists.txt @@ -12,6 +12,7 @@ set(cmake_SOURCE_FILES Audio.cmake BerkeleyDB.cmake Boost.cmake + bugsplat.cmake BuildVersion.cmake CEFPlugin.cmake CEFPlugin.cmake diff --git a/indra/cmake/bugsplat.cmake b/indra/cmake/bugsplat.cmake index e993979902..a7f4194905 100644 --- a/indra/cmake/bugsplat.cmake +++ b/indra/cmake/bugsplat.cmake @@ -1,20 +1,30 @@ -include(Prebuilt) +# BUGSPLAT can be set when launching the make using the argument -DBUGSPLAT:BOOL=ON +# When building using proprietary binaries though (i.e. having access to LL private servers), +# we always build with BUGSPLAT. +# Open source devs should use the -DBUGSPLAT:BOOL=ON then if they want to +# build with BugSplat, whether they are using USESYSTEMLIBS or not. +if (INSTALL_PROPRIETARY) + set(BUGSPLAT ON CACHE BOOL "Using BugSplat crash reporting library.") +endif (INSTALL_PROPRIETARY) -set(BUGSPLAT_FIND_QUIETLY ON) -set(BUGSPLAT_FIND_REQUIRED ON) +if (BUGSPLAT) + if (USESYSTEMLIBS) + set(BUGSPLAT_FIND_QUIETLY ON) + set(BUGSPLAT_FIND_REQUIRED ON) + include(FindBUGSPLAT) + else (USESYSTEMLIBS) + include(Prebuilt) + use_prebuilt_binary(bugsplat) + if (WINDOWS) + set(BUGSPLAT_LIBRARIES + ${ARCH_PREBUILT_DIRS_RELEASE}/bugsplat.lib + ) + elseif (DARWIN) + find_library(BUGSPLAT_LIBRARIES BugsplatMac + PATHS "${ARCH_PREBUILT_DIRS_RELEASE}") + else (WINDOWS) -if (USESYSTEMLIBS) - include(FindBUGSPLAT) -else (USESYSTEMLIBS) - use_prebuilt_binary(bugsplat) - if (WINDOWS) - set(BUGSPLAT_LIBRARIES - ${ARCH_PREBUILT_DIRS_RELEASE}/bugsplat.lib - ) - elseif (DARWIN) - - else (WINDOWS) - - endif (WINDOWS) - set(BUGSPLAT_INCLUDE_DIR ${LIBS_PREBUILT_DIR}/include/bugsplat) -endif (USESYSTEMLIBS) + endif (WINDOWS) + set(BUGSPLAT_INCLUDE_DIR ${LIBS_PREBUILT_DIR}/include/bugsplat) + endif (USESYSTEMLIBS) +endif (BUGSPLAT) diff --git a/indra/llcommon/CMakeLists.txt b/indra/llcommon/CMakeLists.txt index 4eba1d5451..d9eb13d65a 100644 --- a/indra/llcommon/CMakeLists.txt +++ b/indra/llcommon/CMakeLists.txt @@ -13,7 +13,6 @@ include(GoogleBreakpad) include(Copy3rdPartyLibs) include(ZLIB) include(URIPARSER) -include(BuildVersion) include_directories( ${EXPAT_INCLUDE_DIRS} @@ -254,14 +253,7 @@ set(llcommon_HEADER_FILES ) set_source_files_properties(${llcommon_HEADER_FILES} - PROPERTIES HEADER_FILE_ONLY TRUE - ) - -# bring in version information for BugSplat crash reporting -set_source_files_properties(${llcommon_SOURCE_FILES} - PROPERTIES - COMPILE_DEFINITIONS "${VIEWER_CHANNEL_VERSION_DEFINES}" # see BuildVersion.cmake - ) + PROPERTIES HEADER_FILE_ONLY TRUE) list(APPEND llcommon_SOURCE_FILES ${llcommon_HEADER_FILES}) diff --git a/indra/llcommon/llapp.cpp b/indra/llcommon/llapp.cpp index 3e652dbdb5..6cc9e804d4 100644 --- a/indra/llcommon/llapp.cpp +++ b/indra/llcommon/llapp.cpp @@ -49,20 +49,6 @@ #include "google_breakpad/exception_handler.h" #include "stringize.h" #include "llcleanup.h" -#include "BugSplat.h" - -// TESTING ONLY - REMOVE FOR PRODUCTION -// (Want to only invoke BugSplat crash reporting in the same way we did for Breakpad - for Release viewers -// but need to test here in a ReleaseWithDebugInfo environment) -#if BUGSPLAT_ENABLED -#define LL_SEND_CRASH_REPORTS 1 -#endif - -// BugSplat crash reporting tool - http://bugsplat.com -#if BUGSPLAT_ENABLED -bool BugSplatExceptionCallback(unsigned int nCode, void* lpVal1, void* lpVal2); -MiniDmpSender *gBugSplatSender; -#endif // // Signal handling @@ -399,26 +385,6 @@ void EnableCrashingOnCrashes() } #endif -#if BUGSPLAT_ENABLED -bool BugSplatExceptionCallback(unsigned int nCode, void* lpVal1, void* lpVal2) -{ - switch (nCode) - { - case MDSCB_EXCEPTIONCODE: - { - // send the main viewer log file (Clearly a temporary hack since we don't have access to the gDir*** set of functions in newview - const std::string appdata = std::string(getenv("APPDATA")); - const std::string logfile = appdata + "\\SecondLife\\logs\\Secondlife.log"; - const std::wstring wide_logfile(logfile.begin(), logfile.end()); - gBugSplatSender->sendAdditionalFile((const __wchar_t *)wide_logfile.c_str()); - } - break; - } - - return false; -} -#endif - void LLApp::setupErrorHandling(bool second_instance) { // Error handling is done by starting up an error handling thread, which just sleeps and @@ -427,25 +393,6 @@ void LLApp::setupErrorHandling(bool second_instance) #if LL_WINDOWS #if LL_SEND_CRASH_REPORTS - -#if BUGSPLAT_ENABLED - // TODOCP: populate these fields correctly - static const wchar_t *bugdb_name = L"second_life_callum_test"; - - // build (painfully) the app/channel name - #define stringize_inner(x) L#x - #define stringize_outer(x) stringize_inner(x) - std::wstring app_name(stringize_outer(LL_VIEWER_CHANNEL)); - - // build in real app version now we leveraged CMake to build in BuildVersion.cmake into LLCommon - wchar_t version_string[MAX_STRING]; - wsprintf(version_string, L"%d.%d.%d.%d", LL_VIEWER_VERSION_MAJOR, LL_VIEWER_VERSION_MINOR, LL_VIEWER_VERSION_PATCH, LL_VIEWER_VERSION_BUILD); - - gBugSplatSender = new MiniDmpSender((const __wchar_t *)bugdb_name, (const __wchar_t *)app_name.c_str(), (const __wchar_t *)version_string, NULL); - - gBugSplatSender->setCallback(BugSplatExceptionCallback); -#else - EnableCrashingOnCrashes(); // This sets a callback to handle w32 signals to the console window. @@ -507,9 +454,8 @@ void LLApp::setupErrorHandling(bool second_instance) mExceptionHandler->set_handle_debug_exceptions(true); } } -#endif // BUGSPLAT_ENABLED -#endif // LL_SEND_CRASH_REPORTS -#else // not LL_WINDOWS +#endif +#else // // Start up signal handling. // @@ -570,7 +516,7 @@ void LLApp::setupErrorHandling(bool second_instance) } #endif -#endif // LL_WINDOWS +#endif startErrorThread(); } diff --git a/indra/llcommon/llapp.h b/indra/llcommon/llapp.h index 5a4b7f13df..acd829d864 100644 --- a/indra/llcommon/llapp.h +++ b/indra/llcommon/llapp.h @@ -30,7 +30,6 @@ #include #include "llrun.h" #include "llsd.h" - // Forward declarations template class LLAtomic32; typedef LLAtomic32 LLAtomicU32; @@ -40,14 +39,6 @@ class LLLiveFile; #include #endif -// first version of Bugsplat (http://bugsplat.com) crash reporting tool -// is only supported on Windows - macOS to follow. -#define BUGSPLAT_ENABLED LL_WINDOWS - -#if BUGSPLAT_ENABLED -class __declspec(dllexport) MiniDmpSender; -#endif - typedef void (*LLAppErrorHandler)(); #if !LL_WINDOWS @@ -325,6 +316,7 @@ private: google_breakpad::ExceptionHandler * mExceptionHandler; + #if !LL_WINDOWS friend void default_unix_signal_handler(int signum, siginfo_t *info, void *); #endif diff --git a/indra/newview/CMakeLists.txt b/indra/newview/CMakeLists.txt index 1fd0af0558..2592b532c4 100644 --- a/indra/newview/CMakeLists.txt +++ b/indra/newview/CMakeLists.txt @@ -1354,6 +1354,11 @@ if (DARWIN) # This should be compiled with the viewer. LIST(APPEND viewer_SOURCE_FILES llappdelegate-objc.mm) + set_source_files_properties( + llappdelegate-objc.mm + PROPERTIES + COMPILE_DEFINITIONS "${VIEWER_CHANNEL_VERSION_DEFINES}" + ) find_library(AGL_LIBRARY AGL) find_library(APPKIT_LIBRARY AppKit) @@ -1366,6 +1371,7 @@ if (DARWIN) ${AGL_LIBRARY} ${IOKIT_LIBRARY} ${COREAUDIO_LIBRARY} + ${BUGSPLAT_LIBRARIES} ) # Add resource files to the project. @@ -1393,6 +1399,11 @@ endif (DARWIN) if (LINUX) LIST(APPEND viewer_SOURCE_FILES llappviewerlinux.cpp) + set_source_files_properties( + llappviewerlinux.cpp + PROPERTIES + COMPILE_DEFINITIONS "${VIEWER_CHANNEL_VERSION_DEFINES}" + ) LIST(APPEND viewer_SOURCE_FILES llappviewerlinux_api_dbus.cpp) SET(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -Wl,--as-needed") @@ -1409,6 +1420,11 @@ if (WINDOWS) llappviewerwin32.cpp llwindebug.cpp ) + set_source_files_properties( + llappviewerwin32.cpp + PROPERTIES + COMPILE_DEFINITIONS "${VIEWER_CHANNEL_VERSION_DEFINES}" + ) list(APPEND viewer_HEADER_FILES llappviewerwin32.h @@ -1692,6 +1708,11 @@ if (SDL_FOUND) ) endif (SDL_FOUND) +if (BUGSPLAT) + set_property(TARGET ${VIEWER_BINARY_NAME} + PROPERTY COMPILE_DEFINITIONS "LL_BUGSPLAT") +endif (BUGSPLAT) + # add package files file(GLOB EVENT_HOST_SCRIPT_GLOB_LIST ${CMAKE_CURRENT_SOURCE_DIR}/../viewer_components/*.py) @@ -1790,7 +1811,7 @@ if (WINDOWS) ${SHARED_LIB_STAGING_DIR}/Debug/fmodexL.dll ) endif (FMODEX) - + add_custom_command( OUTPUT ${CMAKE_CFG_INTDIR}/copy_touched.bat COMMAND ${PYTHON_EXECUTABLE} diff --git a/indra/newview/llappviewerwin32.cpp b/indra/newview/llappviewerwin32.cpp index 48b3a1c485..8a014c55d7 100644 --- a/indra/newview/llappviewerwin32.cpp +++ b/indra/newview/llappviewerwin32.cpp @@ -66,8 +66,18 @@ #endif #include "stringize.h" +#include "lldir.h" #include + +// Bugsplat (http://bugsplat.com) crash reporting tool +#ifdef LL_BUGSPLAT +#include "BugSplat.h" + +// FIXME: need a production BugSplat database name +static const wchar_t *bugdb_name = L"second_life_callum_test"; +#endif + namespace { void (*gOldTerminateHandler)() = NULL; @@ -495,15 +505,46 @@ bool LLAppViewerWin32::init() LLWinDebug::instance(); #endif -#if LL_WINDOWS #if LL_SEND_CRASH_REPORTS - +#if ! defined(LL_BUGSPLAT) LLAppViewer* pApp = LLAppViewer::instance(); pApp->initCrashReporting(); -#endif -#endif +#else // LL_BUGSPLAT + + std::wstring version_string(WSTRINGIZE(LL_VIEWER_VERSION_MAJOR << '.' << + LL_VIEWER_VERSION_MINOR << '.' << + LL_VIEWER_VERSION_PATCH << '.' << + LL_VIEWER_VERSION_BUILD)); + + auto sender = new MiniDmpSender( + bugdb_name, LL_TO_WSTRING(LL_VIEWER_CHANNEL), version_string.c_str(), nullptr); + sender->setCallback( + [sender](unsigned int nCode, void* lpVal1, void* lpVal2) + { + // If we haven't yet initialized LLDir, don't bother trying to + // find our log file. + // Alternatively -- if we might encounter trouble trying to query + // LLDir during crash cleanup -- consider making gDirUtilp an + // LLPounceable, and attach a callback that stores the pathname to + // the log file here. + if (nCode == MDSCB_EXCEPTIONCODE && gDirUtilp) + { + // send the main viewer log file + // widen to wstring, then pass c_str() + sender->sendAdditionalFile( + wstringize(gDirUtilp->getExpandedFilename(LL_PATH_LOGS, "SecondLife.log")).c_str()); + } + + return false; + }); + + LL_INFOS() << "Engaged BugSplat(" << LL_TO_STRING(LL_VIEWER_CHANNEL) + << version_string << ')' << LL_ENDL; + +#endif // LL_BUGSPLAT +#endif // LL_SEND_CRASH_REPORTS bool success = LLAppViewer::init(); -- cgit v1.3 From ac2604a039bb9477cf9102dfccd77619a6061d7a Mon Sep 17 00:00:00 2001 From: Nat Goodspeed Date: Thu, 14 Jun 2018 11:31:17 -0400 Subject: SL-821: Avoid Breakpad (and signal handling in general) for BugSplat. Pass LL_BUGSPLAT into llapp.cpp compile to be able to detect that. --- indra/llcommon/CMakeLists.txt | 5 +++++ indra/llcommon/llapp.cpp | 23 ++++++++++++++++------- 2 files changed, 21 insertions(+), 7 deletions(-) (limited to 'indra/llcommon') diff --git a/indra/llcommon/CMakeLists.txt b/indra/llcommon/CMakeLists.txt index d9eb13d65a..8977acb873 100644 --- a/indra/llcommon/CMakeLists.txt +++ b/indra/llcommon/CMakeLists.txt @@ -255,6 +255,11 @@ set(llcommon_HEADER_FILES set_source_files_properties(${llcommon_HEADER_FILES} PROPERTIES HEADER_FILE_ONLY TRUE) +if (DEFINED ENV{BUGSPLAT_DB}) + set_source_files_properties(llapp.cpp + PROPERTIES COMPILE_DEFINITIONS "LL_BUGSPLAT") +endif (DEFINED ENV{BUGSPLAT_DB}) + list(APPEND llcommon_SOURCE_FILES ${llcommon_HEADER_FILES}) if(LLCOMMON_LINK_SHARED) diff --git a/indra/llcommon/llapp.cpp b/indra/llcommon/llapp.cpp index 6cc9e804d4..421af3006e 100644 --- a/indra/llcommon/llapp.cpp +++ b/indra/llcommon/llapp.cpp @@ -392,7 +392,7 @@ void LLApp::setupErrorHandling(bool second_instance) #if LL_WINDOWS -#if LL_SEND_CRASH_REPORTS +#if LL_SEND_CRASH_REPORTS && ! defined(LL_BUGSPLAT) EnableCrashingOnCrashes(); // This sets a callback to handle w32 signals to the console window. @@ -454,8 +454,15 @@ void LLApp::setupErrorHandling(bool second_instance) mExceptionHandler->set_handle_debug_exceptions(true); } } -#endif -#else +#endif // LL_SEND_CRASH_REPORTS && ! defined(LL_BUGSPLAT) +#else // ! LL_WINDOWS + +#if defined(LL_BUGSPLAT) + // Don't install our own signal handlers -- BugSplat needs to hook them, + // or it's completely ineffectual. + bool installHandler = false; + +#else // ! LL_BUGSPLAT // // Start up signal handling. // @@ -463,9 +470,11 @@ void LLApp::setupErrorHandling(bool second_instance) // thread, asynchronous signals can be delivered to any thread (in theory) // setup_signals(); - + // Add google breakpad exception handler configured for Darwin/Linux. bool installHandler = true; +#endif // ! LL_BUGSPLAT + #if LL_DARWIN // For the special case of Darwin, we do not want to install the handler if // the process is being debugged as the app will exit with value ABRT (6) if @@ -498,7 +507,7 @@ void LLApp::setupErrorHandling(bool second_instance) // installing the handler. installHandler = true; } - #endif + #endif // ! LL_RELEASE_FOR_DOWNLOAD if(installHandler && (mExceptionHandler == 0)) { @@ -514,9 +523,9 @@ void LLApp::setupErrorHandling(bool second_instance) google_breakpad::MinidumpDescriptor desc(mDumpPath); mExceptionHandler = new google_breakpad::ExceptionHandler(desc, NULL, unix_minidump_callback, NULL, true, -1); } -#endif +#endif // LL_LINUX -#endif +#endif // ! LL_WINDOWS startErrorThread(); } -- cgit v1.3 From cd52724ef8f8a19ebe28c73f39a582b56fb58093 Mon Sep 17 00:00:00 2001 From: Nat Goodspeed Date: Thu, 28 Jun 2018 21:49:07 -0400 Subject: DRTVWR-447: Suppress BugSplat UI; auto-fill certain BugSplat data. Direct BugSplat to send crash reports without prompting, on both Windows and Mac. Add a mechanism by which code called after LL_ERRS() can retrieve the fatal log message string. (How did the crash logger extract that for Linden crash logging?) Add that fatal message to crash reports on Windows. But as BugsplatMac is engaged only on the run _after_ the crash, we no longer have that message in memory. Also add user name and region location to Windows crash reports. On Mac, (a) we don't have the information from the previous run and (b) BugsplatMac doesn't provide an API to attach that information to the crash report. Add Mac logging to indicate the success or failure of sending the crash report. Add Windows logging to indicate we're about to send. --- indra/llcommon/llerror.cpp | 33 ++++++++++++------- indra/llcommon/llerrorcontrol.h | 3 ++ indra/newview/llappdelegate-objc.mm | 34 +++++++++++++------ indra/newview/llappviewermacosx-for-objc.h | 2 ++ indra/newview/llappviewermacosx.cpp | 12 +++++++ indra/newview/llappviewerwin32.cpp | 53 +++++++++++++++++++++--------- 6 files changed, 101 insertions(+), 36 deletions(-) (limited to 'indra/llcommon') diff --git a/indra/llcommon/llerror.cpp b/indra/llcommon/llerror.cpp index f31a054139..b5e7e81f21 100644 --- a/indra/llcommon/llerror.cpp +++ b/indra/llcommon/llerror.cpp @@ -377,6 +377,7 @@ namespace public: std::ostringstream messageStream; bool messageStreamInUse; + std::string mFatalMessage; void addCallSite(LLError::CallSite&); void invalidateCallSites(); @@ -670,11 +671,16 @@ namespace LLError s->mCrashFunction = f; } - FatalFunction getFatalFunction() - { + FatalFunction getFatalFunction() + { SettingsConfigPtr s = Settings::getInstance()->getSettingsConfig(); - return s->mCrashFunction; - } + return s->mCrashFunction; + } + + std::string getFatalMessage() + { + return Globals::getInstance()->mFatalMessage; + } void setTimeFunction(TimeFunction f) { @@ -1194,7 +1200,7 @@ namespace LLError { writeToRecorders(site, "error", true, true, true, false, false); } - + std::ostringstream message_stream; if (site.mPrintOnce) @@ -1219,14 +1225,19 @@ namespace LLError s->mUniqueLogMessages[message] = 1; } } - + message_stream << message; - - writeToRecorders(site, message_stream.str()); - - if (site.mLevel == LEVEL_ERROR && s->mCrashFunction) + std::string message_line(message_stream.str()); + + writeToRecorders(site, message_line); + + if (site.mLevel == LEVEL_ERROR) { - s->mCrashFunction(message_stream.str()); + g->mFatalMessage = message_line; + if (s->mCrashFunction) + { + s->mCrashFunction(message_line); + } } } } diff --git a/indra/llcommon/llerrorcontrol.h b/indra/llcommon/llerrorcontrol.h index caf2ba72c2..ddbcdc94a0 100644 --- a/indra/llcommon/llerrorcontrol.h +++ b/indra/llcommon/llerrorcontrol.h @@ -102,6 +102,9 @@ namespace LLError LL_COMMON_API FatalFunction getFatalFunction(); // Retrieve the previously-set FatalFunction + LL_COMMON_API std::string getFatalMessage(); + // Retrieve the message last passed to FatalFunction, if any + /// temporarily override the FatalFunction for the duration of a /// particular scope, e.g. for unit tests class LL_COMMON_API OverrideFatalFunction diff --git a/indra/newview/llappdelegate-objc.mm b/indra/newview/llappdelegate-objc.mm index 4510f4070f..82e49540a4 100644 --- a/indra/newview/llappdelegate-objc.mm +++ b/indra/newview/llappdelegate-objc.mm @@ -74,9 +74,9 @@ #if defined(LL_BUGSPLAT) // https://www.bugsplat.com/docs/platforms/os-x#initialization -// [BugsplatStartupManager sharedManager].autoSubmitCrashReport = YES; -// [BugsplatStartupManager sharedManager].askUserDetails = NO; - [BugsplatStartupManager sharedManager].delegate = self; + [BugsplatStartupManager sharedManager].autoSubmitCrashReport = YES; + [BugsplatStartupManager sharedManager].askUserDetails = NO; + [BugsplatStartupManager sharedManager].delegate = self; [[BugsplatStartupManager sharedManager] start]; #endif } @@ -196,17 +196,20 @@ #if defined(LL_BUGSPLAT) -#if 0 -// Apparently this override method only contributes the User Description field -// of BugSplat's All Crashes table. Despite the method name, it would seem to -// be a bad place to try to stuff all of SecondLife.log. - (NSString *)applicationLogForBugsplatStartupManager:(BugsplatStartupManager *)bugsplatStartupManager { -// return NSStringFromSelector(_cmd); infos("Reached applicationLogForBugsplatStartupManager"); - return @"[contents of SecondLife.log]"; + // Apparently this override method only contributes the User Description + // field of BugSplat's All Crashes table. Despite the method name, it + // would seem to be a bad place to try to stuff all of SecondLife.log. + return [NSString stringWithCString:getFatalMessage().c_str() + encoding:NSUTF8StringEncoding]; +} + +- (void)bugsplatStartupManagerWillSendCrashReport:(BugsplatStartupManager *)bugsplatStartupManager +{ + infos("Reached bugsplatStartupManagerWillSendCrashReport"); } -#endif - (BugsplatAttachment *)attachmentForBugsplatStartupManager:(BugsplatStartupManager *)bugsplatStartupManager { // We get the *old* log file pathname (for SecondLife.old) because it's on @@ -228,6 +231,17 @@ return attachment; } +- (void)bugsplatStartupManagerDidFinishSendingCrashReport:(BugsplatStartupManager *)bugsplatStartupManager +{ + infos("Sent crash report to BugSplat"); +} + +- (void)bugsplatStartupManager:(BugsplatStartupManager *)bugsplatStartupManager didFailWithError:(NSError *)error +{ + // TODO: message string from NSError + infos("Could not send crash report to BugSplat"); +} + #endif // LL_BUGSPLAT @end diff --git a/indra/newview/llappviewermacosx-for-objc.h b/indra/newview/llappviewermacosx-for-objc.h index c439297611..ac85d7e8c3 100644 --- a/indra/newview/llappviewermacosx-for-objc.h +++ b/indra/newview/llappviewermacosx-for-objc.h @@ -30,6 +30,8 @@ bool pumpMainLoop(); void handleQuit(); void cleanupViewer(); std::string getOldLogFilePathname(); +std::string getFatalMessage(); +std::string getAgentFullname(); void infos(const std::string& message); #endif /* ! defined(LL_LLAPPVIEWERMACOSX_FOR_OBJC_H) */ diff --git a/indra/newview/llappviewermacosx.cpp b/indra/newview/llappviewermacosx.cpp index d014e992f9..c3a3c3284a 100644 --- a/indra/newview/llappviewermacosx.cpp +++ b/indra/newview/llappviewermacosx.cpp @@ -45,6 +45,8 @@ #include "llmd5.h" #include "llfloaterworldmap.h" #include "llurldispatcher.h" +#include "llerrorcontrol.h" +#include "llvoavatarself.h" // for gAgentAvatarp->getFullname() #include #ifdef LL_CARBON_CRASH_HANDLER #include @@ -153,6 +155,16 @@ std::string getOldLogFilePathname() return gDirUtilp->getExpandedFilename(LL_PATH_LOGS, "SecondLife.old"); } +std::string getFatalMessage() +{ + return LLError::getFatalMessage(); +} + +std::string getAgentFullname() +{ + return gAgentAvatarp? gAgentAvatarp->getFullname() : std::string(); +} + void infos(const std::string& message) { LL_INFOS() << message << LL_ENDL; diff --git a/indra/newview/llappviewerwin32.cpp b/indra/newview/llappviewerwin32.cpp index 247b94db3e..1e135fa229 100644 --- a/indra/newview/llappviewerwin32.cpp +++ b/indra/newview/llappviewerwin32.cpp @@ -67,6 +67,7 @@ #include "stringize.h" #include "lldir.h" +#include "llerrorcontrol.h" #include #include @@ -74,7 +75,10 @@ // Bugsplat (http://bugsplat.com) crash reporting tool #ifdef LL_BUGSPLAT #include "BugSplat.h" -#include "reader.h" // JsonCpp +#include "reader.h" // JsonCpp +#include "llagent.h" // for agent location +#include "llviewerregion.h" +#include "llvoavatarself.h" // for agent name namespace { @@ -85,7 +89,8 @@ namespace // std::basic_string instance will survive until the function returns. // Calling c_str() on a std::basic_string local to wunder() would be // Undefined Behavior: we'd be left with a pointer into a destroyed - // std::basic_string instance. + // std::basic_string instance. But we can do that with a macro... + #define WCSTR(string) wunder(string).c_str() // It would be nice if, when wchar_t is the same as __wchar_t, this whole // function would optimize away. However, we use it only for the arguments @@ -111,19 +116,35 @@ namespace bool bugsplatSendLog(UINT nCode, LPVOID lpVal1, LPVOID lpVal2) { - // If we haven't yet initialized LLDir, don't bother trying to - // find our log file. - // Alternatively -- if we might encounter trouble trying to query - // LLDir during crash cleanup -- consider making gDirUtilp an - // LLPounceable, and attach a callback that stores the pathname to - // the log file here. - if (nCode == MDSCB_EXCEPTIONCODE && gDirUtilp) + if (nCode == MDSCB_EXCEPTIONCODE) { // send the main viewer log file // widen to wstring, convert to __wchar_t, then pass c_str() sBugSplatSender->sendAdditionalFile( - wunder(gDirUtilp->getExpandedFilename(LL_PATH_LOGS, "SecondLife.log")).c_str()); - } + WCSTR(gDirUtilp->getExpandedFilename(LL_PATH_LOGS, "SecondLife.log"))); + + if (gAgentAvatarp) + { + // user name, when we have it + sBugSplatSender->setDefaultUserName(WCSTR(gAgentAvatarp->getFullname())); + } + + // LL_ERRS message, when there is one + sBugSplatSender->setDefaultUserDescription(WCSTR(LLError::getFatalMessage())); + + if (gAgent.getRegion()) + { + // region location, when we have it + LLVector3 loc = gAgent.getPositionAgent(); + sBugSplatSender->resetAppIdentifier( + WCSTR(STRINGIZE(gAgent.getRegion()->getName() + << '/' << loc.mV[0] + << '/' << loc.mV[1] + << '/' << loc.mV[2]))); + } + + LL_INFOS() << "Sending crash report to BugSplat." << LL_ENDL; + } // MDSCB_EXCEPTIONCODE return false; } @@ -603,10 +624,12 @@ bool LLAppViewerWin32::init() // have to convert normal wide strings to strings of __wchar_t sBugSplatSender = new MiniDmpSender( - wunder(BugSplat_DB.asString()).c_str(), - wunder(LL_TO_WSTRING(LL_VIEWER_CHANNEL)).c_str(), - wunder(version_string).c_str(), - nullptr); + 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 sBugSplatSender->setCallback(bugsplatSendLog); // engage stringize() overload that converts from wstring -- cgit v1.3 From c2178bb6ac139d47eb2bfdf9e85811a6f02810ed Mon Sep 17 00:00:00 2001 From: Nat Goodspeed Date: Fri, 24 Aug 2018 09:56:56 -0400 Subject: DRTVWR-447: Introduce explicit CMake BUGSPLAT_DB variable. Define the CMake cache variable, with empty string as its default. Make build.sh pass the BUGSPLAT_DB environment variable as a CMake command-line variable assignment. Change CMake 'if (DEFINED ENV{BUGSPLAT_DB})' to plain 'if (BUGSPLAT_DB)'. Make CMake pass new --bugsplat switch to every one of SIX different invocations of viewer_manifest.py. Give llmanifest.main() function an argument to allow supplementing the base set of command-line switches with additional application-specific switches. In viewer_manifest.py, define new --bugsplat command-line switch and pass to llmanifest.main(). Instead of consulting os.environ['BUGSPLAT_DB'], consult self.args['bugsplat']. --- build.sh | 1 + indra/cmake/Copy3rdPartyLibs.cmake | 4 +-- indra/cmake/Variables.cmake | 1 + indra/cmake/bugsplat.cmake | 9 +++-- indra/lib/python/indra/util/llmanifest.py | 56 +++++++++++++++++-------------- indra/llcommon/CMakeLists.txt | 4 +-- indra/newview/CMakeLists.txt | 52 +++++++++++++++------------- indra/newview/viewer_manifest.py | 45 +++++++++++++------------ 8 files changed, 94 insertions(+), 78 deletions(-) (limited to 'indra/llcommon') diff --git a/build.sh b/build.sh index d531c0b046..c38bb6fff4 100755 --- a/build.sh +++ b/build.sh @@ -122,6 +122,7 @@ pre_build() -DPACKAGE:BOOL=ON \ -DHAVOK:BOOL="$HAVOK" \ -DRELEASE_CRASH_REPORTING:BOOL="$RELEASE_CRASH_REPORTING" \ + -DBUGSPLAT_DB:STRING="${BUGSPLAT_DB:-}" \ -DVIEWER_CHANNEL:STRING="${viewer_channel}" \ -DGRID:STRING="\"$viewer_grid\"" \ -DTEMPLATE_VERIFIER_OPTIONS:STRING="$template_verifier_options" $template_verifier_master_url \ diff --git a/indra/cmake/Copy3rdPartyLibs.cmake b/indra/cmake/Copy3rdPartyLibs.cmake index c9519b0e1d..dde53835fb 100644 --- a/indra/cmake/Copy3rdPartyLibs.cmake +++ b/indra/cmake/Copy3rdPartyLibs.cmake @@ -51,7 +51,7 @@ if(WINDOWS) # Filenames are different for 32/64 bit BugSplat file and we don't # have any control over them so need to branch. - if (DEFINED ENV{BUGSPLAT_DB}) + if (BUGSPLAT_DB) if(ADDRESS_SIZE EQUAL 32) set(release_files ${release_files} BugSplat.dll) set(release_files ${release_files} BugSplatRc.dll) @@ -61,7 +61,7 @@ if(WINDOWS) set(release_files ${release_files} BugSplatRc64.dll) set(release_files ${release_files} BsSndRpt64.exe) endif(ADDRESS_SIZE EQUAL 32) - endif (DEFINED ENV{BUGSPLAT_DB}) + endif (BUGSPLAT_DB) if (FMODEX) diff --git a/indra/cmake/Variables.cmake b/indra/cmake/Variables.cmake index b913d6398e..e49de0a79b 100644 --- a/indra/cmake/Variables.cmake +++ b/indra/cmake/Variables.cmake @@ -33,6 +33,7 @@ set(INTEGRATION_TESTS_PREFIX) set(LL_TESTS ON CACHE BOOL "Build and run unit and integration tests (disable for build timing runs to reduce variation") set(INCREMENTAL_LINK OFF CACHE BOOL "Use incremental linking on win32 builds (enable for faster links on some machines)") set(ENABLE_MEDIA_PLUGINS ON CACHE BOOL "Turn off building media plugins if they are imported by third-party library mechanism") +set(BUGSPLAT_DB "" CACHE STRING "BugSplat database name, if BugSplat crash reporting is desired") if(LIBS_CLOSED_DIR) file(TO_CMAKE_PATH "${LIBS_CLOSED_DIR}" LIBS_CLOSED_DIR) diff --git a/indra/cmake/bugsplat.cmake b/indra/cmake/bugsplat.cmake index eb5808b1fb..59644b73ce 100644 --- a/indra/cmake/bugsplat.cmake +++ b/indra/cmake/bugsplat.cmake @@ -1,7 +1,6 @@ -# BugSplat is engaged by setting environment variable BUGSPLAT_DB to the -# target BugSplat database name prior to running CMake (and during autobuild -# build). -if (DEFINED ENV{BUGSPLAT_DB}) +# BugSplat is engaged by setting BUGSPLAT_DB to the target BugSplat database +# name. +if (BUGSPLAT_DB) if (USESYSTEMLIBS) message(STATUS "Looking for system BugSplat") set(BUGSPLAT_FIND_QUIETLY ON) @@ -23,4 +22,4 @@ if (DEFINED ENV{BUGSPLAT_DB}) endif (WINDOWS) set(BUGSPLAT_INCLUDE_DIR ${LIBS_PREBUILT_DIR}/include/bugsplat) endif (USESYSTEMLIBS) -endif (DEFINED ENV{BUGSPLAT_DB}) +endif (BUGSPLAT_DB) diff --git a/indra/lib/python/indra/util/llmanifest.py b/indra/lib/python/indra/util/llmanifest.py index 611f72269e..c4dcad51b7 100755 --- a/indra/lib/python/indra/util/llmanifest.py +++ b/indra/lib/python/indra/util/llmanifest.py @@ -33,13 +33,14 @@ import filecmp import fnmatch import getopt import glob +import itertools +import operator import os import re import shutil +import subprocess import sys import tarfile -import errno -import subprocess class ManifestError(RuntimeError): """Use an exception more specific than generic Python RuntimeError""" @@ -90,7 +91,7 @@ DEFAULT_SRCTREE = os.path.dirname(sys.argv[0]) CHANNEL_VENDOR_BASE = 'Second Life' RELEASE_CHANNEL = CHANNEL_VENDOR_BASE + ' Release' -ARGUMENTS=[ +BASE_ARGUMENTS=[ dict(name='actions', description="""This argument specifies the actions that are to be taken when the script is run. The meaningful actions are currently: @@ -108,8 +109,19 @@ ARGUMENTS=[ Example use: %(name)s --arch=i686 On Linux this would try to use Linux_i686Manifest.""", default=""), + dict(name='artwork', description='Artwork directory.', default=DEFAULT_SRCTREE), dict(name='build', description='Build directory.', default=DEFAULT_SRCTREE), dict(name='buildtype', description='Build type (i.e. Debug, Release, RelWithDebInfo).', default=None), + dict(name='bundleid', + description="""The Mac OS X Bundle identifier.""", + default="com.secondlife.indra.viewer"), + dict(name='channel', + description="""The channel to use for updates, packaging, settings name, etc.""", + default='CHANNEL UNSET'), + dict(name='channel_suffix', + description="""Addition to the channel for packaging and channel value, + but not application name (used internally)""", + default=None), dict(name='configuration', description="""The build configuration used.""", default="Release"), @@ -117,12 +129,6 @@ ARGUMENTS=[ dict(name='grid', description="""Which grid the client will try to connect to.""", default=None), - dict(name='channel', - description="""The channel to use for updates, packaging, settings name, etc.""", - default='CHANNEL UNSET'), - dict(name='channel_suffix', - description="""Addition to the channel for packaging and channel value, but not application name (used internally)""", - default=None), dict(name='installer_name', description=""" The name of the file that the installer should be packaged up into. Only used on Linux at the moment.""", @@ -134,10 +140,14 @@ ARGUMENTS=[ description="""The current platform, to be used for looking up which manifest class to run.""", default=get_default_platform), + dict(name='signature', + description="""This specifies an identity to sign the viewer with, if any. + If no value is supplied, the default signature will be used, if any. Currently + only used on Mac OS X.""", + default=None), dict(name='source', description='Source directory.', default=DEFAULT_SRCTREE), - dict(name='artwork', description='Artwork directory.', default=DEFAULT_SRCTREE), dict(name='touch', description="""File to touch when action is finished. Touch file will contain the name of the final package in a form suitable @@ -145,23 +155,15 @@ ARGUMENTS=[ default=None), dict(name='versionfile', description="""The name of a file containing the full version number."""), - dict(name='bundleid', - description="""The Mac OS X Bundle identifier.""", - default="com.secondlife.indra.viewer"), - dict(name='signature', - description="""This specifies an identity to sign the viewer with, if any. - If no value is supplied, the default signature will be used, if any. Currently - only used on Mac OS X.""", - default=None) ] -def usage(srctree=""): +def usage(arguments, srctree=""): nd = {'name':sys.argv[0]} print """Usage: %(name)s [options] [destdir] Options: """ % nd - for arg in ARGUMENTS: + for arg in arguments: default = arg['default'] if hasattr(default, '__call__'): default = "(computed value) \"" + str(default(srctree)) + '"' @@ -172,11 +174,15 @@ def usage(srctree=""): default, arg['description'] % nd) -def main(): -## import itertools +def main(extra=[]): ## print ' '.join((("'%s'" % item) if ' ' in item else item) ## for item in itertools.chain([sys.executable], sys.argv)) - option_names = [arg['name'] + '=' for arg in ARGUMENTS] + # Supplement our default command-line switches with any desired by + # application-specific caller. + arguments = list(itertools.chain(BASE_ARGUMENTS, extra)) + # Alphabetize them by option name in case we display usage. + arguments.sort(key=operator.itemgetter('name')) + option_names = [arg['name'] + '=' for arg in arguments] option_names.append('help') options, remainder = getopt.getopt(sys.argv[1:], "", option_names) @@ -199,11 +205,11 @@ def main(): # early out for help if 'help' in args: # *TODO: it is a huge hack to pass around the srctree like this - usage(args['source']) + usage(arguments, srctree=args['source']) return # defaults - for arg in ARGUMENTS: + for arg in arguments: if arg['name'] not in args: default = arg['default'] if hasattr(default, '__call__'): diff --git a/indra/llcommon/CMakeLists.txt b/indra/llcommon/CMakeLists.txt index 8977acb873..42ad56f1b0 100644 --- a/indra/llcommon/CMakeLists.txt +++ b/indra/llcommon/CMakeLists.txt @@ -255,10 +255,10 @@ set(llcommon_HEADER_FILES set_source_files_properties(${llcommon_HEADER_FILES} PROPERTIES HEADER_FILE_ONLY TRUE) -if (DEFINED ENV{BUGSPLAT_DB}) +if (BUGSPLAT_DB) set_source_files_properties(llapp.cpp PROPERTIES COMPILE_DEFINITIONS "LL_BUGSPLAT") -endif (DEFINED ENV{BUGSPLAT_DB}) +endif (BUGSPLAT_DB) list(APPEND llcommon_SOURCE_FILES ${llcommon_HEADER_FILES}) diff --git a/indra/newview/CMakeLists.txt b/indra/newview/CMakeLists.txt index 31c4c02d99..64a8e15c4b 100644 --- a/indra/newview/CMakeLists.txt +++ b/indra/newview/CMakeLists.txt @@ -8,9 +8,9 @@ include(00-Common) include(Linking) include(Boost) -if (DEFINED ENV{BUGSPLAT_DB}) +if (BUGSPLAT_DB) include(bugsplat) -endif (DEFINED ENV{BUGSPLAT_DB}) +endif (BUGSPLAT_DB) include(BuildPackagesInfo) include(BuildVersion) include(CMakeCopyIfDifferent) @@ -99,11 +99,11 @@ include_directories( ${CMAKE_CURRENT_SOURCE_DIR} ) -if (DEFINED ENV{BUGSPLAT_DB}) +if (BUGSPLAT_DB) include_directories( ${BUGSPLAT_INCLUDE_DIR} ) -endif (DEFINED ENV{BUGSPLAT_DB}) +endif (BUGSPLAT_DB) include_directories(SYSTEM ${LLCOMMON_SYSTEM_INCLUDE_DIRS} @@ -1390,11 +1390,11 @@ if (DARWIN) ${COREAUDIO_LIBRARY} ) - if (DEFINED ENV{BUGSPLAT_DB}) + if (BUGSPLAT_DB) list(APPEND viewer_LIBRARIES ${BUGSPLAT_LIBRARIES} ) - endif (DEFINED ENV{BUGSPLAT_DB}) + endif (BUGSPLAT_DB) # Add resource files to the project. set(viewer_RESOURCE_FILES @@ -1729,10 +1729,10 @@ if (SDL_FOUND) ) endif (SDL_FOUND) -if (DEFINED ENV{BUGSPLAT_DB}) +if (BUGSPLAT_DB) set_property(TARGET ${VIEWER_BINARY_NAME} PROPERTY COMPILE_DEFINITIONS "LL_BUGSPLAT") -endif (DEFINED ENV{BUGSPLAT_DB}) +endif (BUGSPLAT_DB) # add package files file(GLOB EVENT_HOST_SCRIPT_GLOB_LIST @@ -1841,15 +1841,16 @@ if (WINDOWS) --actions=copy --arch=${ARCH} --artwork=${ARTWORK_DIR} + "--bugsplat=${BUGSPLAT_DB}" --build=${CMAKE_CURRENT_BINARY_DIR} --buildtype=${CMAKE_BUILD_TYPE} + "--channel=${VIEWER_CHANNEL}" --configuration=${CMAKE_CFG_INTDIR} --dest=${CMAKE_CURRENT_BINARY_DIR}/${CMAKE_CFG_INTDIR} --grid=${GRID} - "--channel=${VIEWER_CHANNEL}" - --versionfile=${CMAKE_CURRENT_BINARY_DIR}/viewer_version.txt --source=${CMAKE_CURRENT_SOURCE_DIR} --touch=${CMAKE_CURRENT_BINARY_DIR}/${CMAKE_CFG_INTDIR}/copy_touched.bat + --versionfile=${CMAKE_CURRENT_BINARY_DIR}/viewer_version.txt DEPENDS ${CMAKE_CURRENT_SOURCE_DIR}/viewer_manifest.py stage_third_party_libs @@ -1892,15 +1893,16 @@ if (WINDOWS) ${CMAKE_CURRENT_SOURCE_DIR}/viewer_manifest.py --arch=${ARCH} --artwork=${ARTWORK_DIR} + "--bugsplat=${BUGSPLAT_DB}" --build=${CMAKE_CURRENT_BINARY_DIR} --buildtype=${CMAKE_BUILD_TYPE} "--channel=${VIEWER_CHANNEL}" - --versionfile=${CMAKE_CURRENT_BINARY_DIR}/viewer_version.txt --configuration=${CMAKE_CFG_INTDIR} --dest=${CMAKE_CURRENT_BINARY_DIR}/${CMAKE_CFG_INTDIR} --grid=${GRID} --source=${CMAKE_CURRENT_SOURCE_DIR} --touch=${CMAKE_CURRENT_BINARY_DIR}/${CMAKE_CFG_INTDIR}/touched.bat + --versionfile=${CMAKE_CURRENT_BINARY_DIR}/viewer_version.txt DEPENDS ${VIEWER_BINARY_NAME} ${CMAKE_CURRENT_SOURCE_DIR}/viewer_manifest.py @@ -2007,11 +2009,11 @@ target_link_libraries(${VIEWER_BINARY_NAME} ${LLAPPEARANCE_LIBRARIES} ) -if (DEFINED ENV{BUGSPLAT_DB}) +if (BUGSPLAT_DB) target_link_libraries(${VIEWER_BINARY_NAME} ${BUGSPLAT_LIBRARIES} ) -endif (DEFINED ENV{BUGSPLAT_DB}) +endif (BUGSPLAT_DB) set(ARTWORK_DIR ${CMAKE_CURRENT_SOURCE_DIR} CACHE PATH "Path to artwork files.") @@ -2036,15 +2038,16 @@ if (LINUX) ${CMAKE_CURRENT_SOURCE_DIR}/viewer_manifest.py --arch=${ARCH} --artwork=${ARTWORK_DIR} + "--bugsplat=${BUGSPLAT_DB}" --build=${CMAKE_CURRENT_BINARY_DIR} --buildtype=${CMAKE_BUILD_TYPE} "--channel=${VIEWER_CHANNEL}" - --versionfile=${CMAKE_CURRENT_BINARY_DIR}/viewer_version.txt --configuration=${CMAKE_CFG_INTDIR} --dest=${CMAKE_CURRENT_BINARY_DIR}/packaged --grid=${GRID} --source=${CMAKE_CURRENT_SOURCE_DIR} --touch=${CMAKE_CURRENT_BINARY_DIR}/${CMAKE_CFG_INTDIR}/.${product}.touched + --versionfile=${CMAKE_CURRENT_BINARY_DIR}/viewer_version.txt DEPENDS ${CMAKE_CURRENT_SOURCE_DIR}/viewer_manifest.py ${COPY_INPUT_DEPENDENCIES} @@ -2058,17 +2061,18 @@ if (LINUX) COMMAND ${PYTHON_EXECUTABLE} ARGS ${CMAKE_CURRENT_SOURCE_DIR}/viewer_manifest.py - --arch=${ARCH} --actions=copy + --arch=${ARCH} --artwork=${ARTWORK_DIR} + "--bugsplat=${BUGSPLAT_DB}" --build=${CMAKE_CURRENT_BINARY_DIR} --buildtype=${CMAKE_BUILD_TYPE} + "--channel=${VIEWER_CHANNEL}" --configuration=${CMAKE_CFG_INTDIR} --dest=${CMAKE_CURRENT_BINARY_DIR}/packaged --grid=${GRID} - "--channel=${VIEWER_CHANNEL}" - --versionfile=${CMAKE_CURRENT_BINARY_DIR}/viewer_version.txt --source=${CMAKE_CURRENT_SOURCE_DIR} + --versionfile=${CMAKE_CURRENT_BINARY_DIR}/viewer_version.txt DEPENDS ${CMAKE_CURRENT_SOURCE_DIR}/viewer_manifest.py ${COPY_INPUT_DEPENDENCIES} @@ -2137,15 +2141,16 @@ if (DARWIN) --actions=copy --arch=${ARCH} --artwork=${ARTWORK_DIR} + "--bugsplat=${BUGSPLAT_DB}" --build=${CMAKE_CURRENT_BINARY_DIR} --buildtype=${CMAKE_BUILD_TYPE} + --bundleid=${MACOSX_BUNDLE_GUI_IDENTIFIER} + "--channel=${VIEWER_CHANNEL}" --configuration=${CMAKE_CFG_INTDIR} --dest=${CMAKE_CURRENT_BINARY_DIR}/${CMAKE_CFG_INTDIR}/${product}.app --grid=${GRID} - "--channel=${VIEWER_CHANNEL}" - --versionfile=${CMAKE_CURRENT_BINARY_DIR}/viewer_version.txt - --bundleid=${MACOSX_BUNDLE_GUI_IDENTIFIER} --source=${CMAKE_CURRENT_SOURCE_DIR} + --versionfile=${CMAKE_CURRENT_BINARY_DIR}/viewer_version.txt DEPENDS ${VIEWER_BINARY_NAME} ${CMAKE_CURRENT_SOURCE_DIR}/viewer_manifest.py @@ -2170,15 +2175,16 @@ if (DARWIN) ${CMAKE_CURRENT_SOURCE_DIR}/viewer_manifest.py --arch=${ARCH} --artwork=${ARTWORK_DIR} + "--bugsplat=${BUGSPLAT_DB}" --build=${CMAKE_CURRENT_BINARY_DIR} --buildtype=${CMAKE_BUILD_TYPE} + "--channel=${VIEWER_CHANNEL}" --configuration=${CMAKE_CFG_INTDIR} --dest=${CMAKE_CURRENT_BINARY_DIR}/${CMAKE_CFG_INTDIR}/${product}.app --grid=${GRID} - "--channel=${VIEWER_CHANNEL}" - --versionfile=${CMAKE_CURRENT_BINARY_DIR}/viewer_version.txt --source=${CMAKE_CURRENT_SOURCE_DIR} --touch=${CMAKE_CURRENT_BINARY_DIR}/${CMAKE_CFG_INTDIR}/.${product}.touched + --versionfile=${CMAKE_CURRENT_BINARY_DIR}/viewer_version.txt ${SIGNING_SETTING} DEPENDS ${CMAKE_CURRENT_SOURCE_DIR}/viewer_manifest.py @@ -2190,7 +2196,7 @@ if (INSTALL) include(${CMAKE_CURRENT_SOURCE_DIR}/ViewerInstall.cmake) endif (INSTALL) -if (PACKAGE AND (RELEASE_CRASH_REPORTING OR NON_RELEASE_CRASH_REPORTING) AND NOT DEFINED ENV{BUGSPLAT_DB}) +if (PACKAGE AND (RELEASE_CRASH_REPORTING OR NON_RELEASE_CRASH_REPORTING) AND NOT BUGSPLAT_DB) set(SYMBOL_SEARCH_DIRS "") # Note that the path to VIEWER_SYMBOL_FILE must match that in ../../build.sh if (WINDOWS) diff --git a/indra/newview/viewer_manifest.py b/indra/newview/viewer_manifest.py index ea0b3625be..e5f0575e86 100755 --- a/indra/newview/viewer_manifest.py +++ b/indra/newview/viewer_manifest.py @@ -188,11 +188,10 @@ class ViewerManifest(LLManifest): "Address Size":self.address_size, "Update Service":"https://update.secondlife.com/update", } - try: - build_data_dict["BugSplat DB"] = os.environ["BUGSPLAT_DB"] - except KeyError: - # skip the assignment if there's no BUGSPLAT_DB variable - pass + # Only store this if it's both present and non-empty + bugsplat_db = self.args.get('bugsplat') + if bugsplat_db: + build_data_dict["BugSplat DB"] = bugsplat_db build_data_dict = self.finish_build_data_dict(build_data_dict) with open(os.path.join(os.pardir,'build_data.json'), 'w') as build_data_handle: json.dump(build_data_dict,build_data_handle) @@ -589,14 +588,15 @@ class WindowsManifest(ViewerManifest): self.path("libhunspell.dll") # BugSplat - if(self.address_size == 64): - self.path("BsSndRpt64.exe") - self.path("BugSplat64.dll") - self.path("BugSplatRc64.dll") - else: - self.path("BsSndRpt.exe") - self.path("BugSplat.dll") - self.path("BugSplatRc.dll") + if self.args.get('bugsplat'): + if(self.address_size == 64): + self.path("BsSndRpt64.exe") + self.path("BugSplat64.dll") + self.path("BugSplatRc64.dll") + else: + self.path("BsSndRpt.exe") + self.path("BugSplat.dll") + self.path("BugSplatRc.dll") # For google-perftools tcmalloc allocator. try: @@ -1038,7 +1038,7 @@ open "%s" --args "$@" if ("package" in self.args['actions'] or "unpacked" in self.args['actions']): # only if we're engaging BugSplat - if "BUGSPLAT_DB" in os.environ: + if self.args.get('bugsplat'): # Create a symbol archive BEFORE stripping the # binary. self.run_command(['dsymutil', exepath]) @@ -1085,13 +1085,11 @@ open "%s" --args "$@" # runs the executable, instead of launching the app) Info["CFBundleExecutable"] = exename Info["CFBundleIconFile"] = viewer_icon - try: + bugsplat_db = self.args.get('bugsplat') + if bugsplat_db: # https://www.bugsplat.com/docs/platforms/os-x#configuration Info["BugsplatServerURL"] = \ - "https://{BUGSPLAT_DB}.bugsplatsoftware.com/".format(**os.environ) - except KeyError: - # skip the assignment if there's no BUGSPLAT_DB variable - pass + "https://{}.bugsplatsoftware.com/".format(bugsplat_db) self.put_in_file( plistlib.writePlistToString(Info), os.path.basename(Info_plist), @@ -1104,7 +1102,8 @@ open "%s" --args "$@" # Remember where we parked this car. CEF_framework = self.dst_path_of(CEF_framework) - self.path2basename(relpkgdir, "BugsplatMac.framework") + if self.args.get('bugsplat'): + self.path2basename(relpkgdir, "BugsplatMac.framework") with self.prefix(dst="Resources"): # defer cross-platform file copies until we're in the right @@ -1727,4 +1726,8 @@ class Linux_x86_64_Manifest(LinuxManifest): ################################################################ if __name__ == "__main__": - main() + extra_arguments = [ + dict(name='bugsplat', description="""BugSplat database to which to post crashes, + if BugSplat crash reporting is desired""", default=''), + ] + main(extra=extra_arguments) -- cgit v1.3 From 49c483eeb350f3620f26ce933007c3d4e9f66d4f Mon Sep 17 00:00:00 2001 From: Oz Linden Date: Wed, 5 Sep 2018 18:07:35 -0400 Subject: add more block structure to TeamCity log output for components --- indra/CMakeLists.txt | 2 ++ indra/cmake/00-Common.cmake | 21 +++++++++++++++++++++ indra/cmake/LLAddBuildTest.cmake | 4 ++++ .../llimage_libtest/CMakeLists.txt | 3 ++- indra/integration_tests/llui_libtest/CMakeLists.txt | 1 + indra/linux_crash_logger/CMakeLists.txt | 4 +++- indra/llappearance/CMakeLists.txt | 2 ++ indra/llaudio/CMakeLists.txt | 1 + indra/llcharacter/CMakeLists.txt | 1 + indra/llcommon/CMakeLists.txt | 2 ++ indra/llcorehttp/CMakeLists.txt | 2 ++ indra/llcrashlogger/CMakeLists.txt | 1 + indra/llimage/CMakeLists.txt | 1 + indra/llimagej2coj/CMakeLists.txt | 3 +++ indra/llinventory/CMakeLists.txt | 1 + indra/llkdu/CMakeLists.txt | 1 + indra/llmath/CMakeLists.txt | 1 + indra/llmessage/CMakeLists.txt | 1 + indra/llplugin/CMakeLists.txt | 1 + indra/llplugin/slplugin/CMakeLists.txt | 3 ++- indra/llprimitive/CMakeLists.txt | 1 + indra/llrender/CMakeLists.txt | 2 ++ indra/llui/CMakeLists.txt | 1 + indra/llvfs/CMakeLists.txt | 1 + indra/llwindow/CMakeLists.txt | 2 ++ indra/llxml/CMakeLists.txt | 1 + indra/mac_crash_logger/CMakeLists.txt | 1 + indra/media_plugins/base/CMakeLists.txt | 3 ++- indra/media_plugins/cef/CMakeLists.txt | 3 ++- indra/media_plugins/example/CMakeLists.txt | 3 ++- indra/media_plugins/gstreamer010/CMakeLists.txt | 3 ++- indra/media_plugins/libvlc/CMakeLists.txt | 3 ++- indra/newview/CMakeLists.txt | 7 +++++++ indra/test/CMakeLists.txt | 1 + indra/viewer_components/login/CMakeLists.txt | 1 + indra/win_crash_logger/CMakeLists.txt | 1 + 36 files changed, 82 insertions(+), 8 deletions(-) (limited to 'indra/llcommon') diff --git a/indra/CMakeLists.txt b/indra/CMakeLists.txt index a40b2c0846..08d0c7b510 100644 --- a/indra/CMakeLists.txt +++ b/indra/CMakeLists.txt @@ -44,6 +44,8 @@ if (WINDOWS AND EXISTS ${LIBS_CLOSED_DIR}copy_win_scripts) endif (WINDOWS AND EXISTS ${LIBS_CLOSED_DIR}copy_win_scripts) add_custom_target(viewer) +buildscripts_block(viewer) + add_subdirectory(${LIBS_OPEN_PREFIX}llcrashlogger) add_subdirectory(${LIBS_OPEN_PREFIX}llplugin) add_subdirectory(${LIBS_OPEN_PREFIX}llui) diff --git a/indra/cmake/00-Common.cmake b/indra/cmake/00-Common.cmake index 40fc706a99..24f6329d10 100644 --- a/indra/cmake/00-Common.cmake +++ b/indra/cmake/00-Common.cmake @@ -217,4 +217,25 @@ else (USESYSTEMLIBS) ) endif (USESYSTEMLIBS) +macro (buildscripts_block target_name) + # add custom commands to bracket a target build to make logs easier to read + + if (DEFINED ENV{TEAMCITY_BUILDCONF_NAME}) + add_custom_command(TARGET ${target_name} PRE_BUILD + COMMAND echo ARGS "##teamcity[blockOpened name='${target_name}']" VERBATIM + ) + add_custom_command(TARGET ${target_name} POST_BUILD + COMMAND echo ARGS "##teamcity[blockClosed name='${target_name}']" VERBATIM + ) + else (DEFINED ENV{TEAMCITY_BUILDCONF_NAME}) + add_custom_command(TARGET ${target_name} PRE_BUILD + COMMAND echo ARGS "################## START ${target_name}" VERBATIM + ) + add_custom_command(TARGET ${target_name} POST_BUILD + COMMAND echo ARGS "################## FINISH ${target_name}" VERBATIM + ) + endif (DEFINED ENV{TEAMCITY_BUILDCONF_NAME}) + +endmacro (buildscripts_block target_name) + endif(NOT DEFINED ${CMAKE_CURRENT_LIST_FILE}_INCLUDED) diff --git a/indra/cmake/LLAddBuildTest.cmake b/indra/cmake/LLAddBuildTest.cmake index 024bfe14a1..3b5bc0af7c 100644 --- a/indra/cmake/LLAddBuildTest.cmake +++ b/indra/cmake/LLAddBuildTest.cmake @@ -1,4 +1,5 @@ # -*- cmake -*- +include(00-Common) include(LLTestCommand) include(GoogleMock) include(Tut) @@ -104,6 +105,7 @@ INCLUDE(GoogleMock) # Setup target ADD_EXECUTABLE(PROJECT_${project}_TEST_${name} ${${name}_test_SOURCE_FILES}) + buildscripts_block(PROJECT_${project}_TEST_${name}) SET_TARGET_PROPERTIES(PROJECT_${project}_TEST_${name} PROPERTIES RUNTIME_OUTPUT_DIRECTORY "${EXE_STAGING_DIR}") # @@ -165,6 +167,7 @@ INCLUDE(GoogleMock) # Add the test runner target per-project # (replaces old _test_ok targets all over the place) ADD_CUSTOM_TARGET(${project}_tests ALL DEPENDS ${${project}_TEST_OUTPUT}) + buildscripts_block(${project}_tests) ADD_DEPENDENCIES(${project} ${project}_tests) ENDMACRO(LL_ADD_PROJECT_UNIT_TESTS) @@ -212,6 +215,7 @@ FUNCTION(LL_ADD_INTEGRATION_TEST message(STATUS "ADD_EXECUTABLE(INTEGRATION_TEST_${testname} ${source_files})") endif(TEST_DEBUG) ADD_EXECUTABLE(INTEGRATION_TEST_${testname} ${source_files}) + buildscripts_block(INTEGRATION_TEST_${testname}) SET_TARGET_PROPERTIES(INTEGRATION_TEST_${testname} PROPERTIES RUNTIME_OUTPUT_DIRECTORY "${EXE_STAGING_DIR}" diff --git a/indra/integration_tests/llimage_libtest/CMakeLists.txt b/indra/integration_tests/llimage_libtest/CMakeLists.txt index 13cf1f7bde..4e23a1fc87 100644 --- a/indra/integration_tests/llimage_libtest/CMakeLists.txt +++ b/indra/integration_tests/llimage_libtest/CMakeLists.txt @@ -40,7 +40,8 @@ add_executable(llimage_libtest WIN32 MACOSX_BUNDLE ${llimage_libtest_SOURCE_FILES} -) + ) +buildscripts_block(llimage_libtest) set_target_properties(llimage_libtest PROPERTIES diff --git a/indra/integration_tests/llui_libtest/CMakeLists.txt b/indra/integration_tests/llui_libtest/CMakeLists.txt index 34e34c7e47..2d21f9af0f 100644 --- a/indra/integration_tests/llui_libtest/CMakeLists.txt +++ b/indra/integration_tests/llui_libtest/CMakeLists.txt @@ -56,6 +56,7 @@ set_source_files_properties(${llui_libtest_HEADER_FILES} list(APPEND llui_libtest_SOURCE_FILES ${llui_libtest_HEADER_FILES}) add_executable(llui_libtest ${llui_libtest_SOURCE_FILES}) +buildscripts_block(llui_libtest) # Link with OS-specific libraries for LLWindow dependency if (DARWIN) diff --git a/indra/linux_crash_logger/CMakeLists.txt b/indra/linux_crash_logger/CMakeLists.txt index 029096df37..165b33fede 100644 --- a/indra/linux_crash_logger/CMakeLists.txt +++ b/indra/linux_crash_logger/CMakeLists.txt @@ -55,6 +55,7 @@ list(APPEND linux_crash_logger_SOURCE_FILES set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -Wl,--as-needed") add_executable(linux-crash-logger ${linux_crash_logger_SOURCE_FILES}) +buildscripts_block(linux-crash-logger) # llcommon uses `clock_gettime' which is provided by librt on linux. set(LIBRT_LIBRARY rt) @@ -78,4 +79,5 @@ target_link_libraries(linux-crash-logger ) add_custom_target(linux-crash-logger-target ALL - DEPENDS linux-crash-logger) + DEPENDS linux-crash-logger) +buildscripts_block(linux-crash-logger-target) diff --git a/indra/llappearance/CMakeLists.txt b/indra/llappearance/CMakeLists.txt index 20eb4678dd..ad33fed010 100644 --- a/indra/llappearance/CMakeLists.txt +++ b/indra/llappearance/CMakeLists.txt @@ -77,6 +77,7 @@ set_source_files_properties(${llappearance_HEADER_FILES} list(APPEND llappearance_SOURCE_FILES ${llappearance_HEADER_FILES}) add_library (llappearance ${llappearance_SOURCE_FILES}) +buildscripts_block(llappearance) target_link_libraries(llappearance ${LLCHARACTER_LIBRARIES} @@ -94,6 +95,7 @@ target_link_libraries(llappearance if (BUILD_HEADLESS) add_library (llappearanceheadless ${llappearance_SOURCE_FILES}) + buildscripts_block(llappearanceheadless) target_link_libraries(llappearanceheadless ${LLCHARACTER_LIBRARIES} diff --git a/indra/llaudio/CMakeLists.txt b/indra/llaudio/CMakeLists.txt index e943dd5d5c..fc81d8c6f2 100644 --- a/indra/llaudio/CMakeLists.txt +++ b/indra/llaudio/CMakeLists.txt @@ -77,6 +77,7 @@ set_source_files_properties(${llaudio_HEADER_FILES} list(APPEND llaudio_SOURCE_FILES ${llaudio_HEADER_FILES}) add_library (llaudio ${llaudio_SOURCE_FILES}) +buildscripts_block(llaudio) target_link_libraries( llaudio ${LLCOMMON_LIBRARIES} diff --git a/indra/llcharacter/CMakeLists.txt b/indra/llcharacter/CMakeLists.txt index a17a5b0aa6..3d0eb09ada 100644 --- a/indra/llcharacter/CMakeLists.txt +++ b/indra/llcharacter/CMakeLists.txt @@ -79,6 +79,7 @@ set_source_files_properties(${llcharacter_HEADER_FILES} list(APPEND llcharacter_SOURCE_FILES ${llcharacter_HEADER_FILES}) add_library (llcharacter ${llcharacter_SOURCE_FILES}) +buildscripts_block(llcharacter) target_link_libraries( llcharacter diff --git a/indra/llcommon/CMakeLists.txt b/indra/llcommon/CMakeLists.txt index 42ad56f1b0..0d58a59e3f 100644 --- a/indra/llcommon/CMakeLists.txt +++ b/indra/llcommon/CMakeLists.txt @@ -24,6 +24,7 @@ include_directories( ) # add_executable(lltreeiterators lltreeiterators.cpp) +# buildscripts_block(lltreeiterators) # # target_link_libraries(lltreeiterators # ${LLCOMMON_LIBRARIES}) @@ -279,6 +280,7 @@ if(LLCOMMON_LINK_SHARED) else(LLCOMMON_LINK_SHARED) add_library (llcommon ${llcommon_SOURCE_FILES}) endif(LLCOMMON_LINK_SHARED) +buildscripts_block(llcommon) target_link_libraries( llcommon diff --git a/indra/llcorehttp/CMakeLists.txt b/indra/llcorehttp/CMakeLists.txt index 9dbc6f447e..c42bd7b6b2 100644 --- a/indra/llcorehttp/CMakeLists.txt +++ b/indra/llcorehttp/CMakeLists.txt @@ -90,6 +90,7 @@ endif (DARWIN OR LINUX) list(APPEND llcorehttp_SOURCE_FILES ${llcorehttp_HEADER_FILES}) add_library (llcorehttp ${llcorehttp_SOURCE_FILES}) +buildscripts_block(llcorehttp) target_link_libraries( llcorehttp ${CURL_LIBRARIES} @@ -214,6 +215,7 @@ endif (DARWIN) add_executable(http_texture_load ${llcorehttp_EXAMPLE_SOURCE_FILES} ) + buildscripts_block(http_texture_load) set_target_properties(http_texture_load PROPERTIES RUNTIME_OUTPUT_DIRECTORY "${EXE_STAGING_DIR}" diff --git a/indra/llcrashlogger/CMakeLists.txt b/indra/llcrashlogger/CMakeLists.txt index da23b46b7b..7d7f3f0167 100644 --- a/indra/llcrashlogger/CMakeLists.txt +++ b/indra/llcrashlogger/CMakeLists.txt @@ -41,3 +41,4 @@ set_source_files_properties(${llcrashlogger_HEADER_FILES} list(APPEND llcrashlogger_SOURCE_FILES ${llcrashlogger_HEADER_FILES}) add_library(llcrashlogger ${llcrashlogger_SOURCE_FILES}) +buildscripts_block(llcrashlogger) diff --git a/indra/llimage/CMakeLists.txt b/indra/llimage/CMakeLists.txt index 293ada7548..4b57a77999 100644 --- a/indra/llimage/CMakeLists.txt +++ b/indra/llimage/CMakeLists.txt @@ -59,6 +59,7 @@ set_source_files_properties(${llimage_HEADER_FILES} list(APPEND llimage_SOURCE_FILES ${llimage_HEADER_FILES}) add_library (llimage ${llimage_SOURCE_FILES}) +buildscripts_block(llimage) # Libraries on which this library depends, needed for Linux builds # Sort by high-level to low-level if (USE_KDU) diff --git a/indra/llimagej2coj/CMakeLists.txt b/indra/llimagej2coj/CMakeLists.txt index 97d22cf86a..f05842b721 100644 --- a/indra/llimagej2coj/CMakeLists.txt +++ b/indra/llimagej2coj/CMakeLists.txt @@ -29,7 +29,10 @@ set_source_files_properties(${llimagej2coj_HEADER_FILES} list(APPEND llimagej2coj_SOURCE_FILES ${llimagej2coj_HEADER_FILES}) add_library (llimagej2coj ${llimagej2coj_SOURCE_FILES}) +buildscripts_block(llimagej2coj) + target_link_libraries( llimagej2coj ${OPENJPEG_LIBRARIES} ) + diff --git a/indra/llinventory/CMakeLists.txt b/indra/llinventory/CMakeLists.txt index 68dd00d880..6a5892127d 100644 --- a/indra/llinventory/CMakeLists.txt +++ b/indra/llinventory/CMakeLists.txt @@ -60,6 +60,7 @@ set_source_files_properties(${llinventory_HEADER_FILES} list(APPEND llinventory_SOURCE_FILES ${llinventory_HEADER_FILES}) add_library (llinventory ${llinventory_SOURCE_FILES}) +buildscripts_block(llinventory) diff --git a/indra/llkdu/CMakeLists.txt b/indra/llkdu/CMakeLists.txt index cb0e204e91..59f6d08517 100644 --- a/indra/llkdu/CMakeLists.txt +++ b/indra/llkdu/CMakeLists.txt @@ -50,6 +50,7 @@ set_source_files_properties(${llkdu_SOURCE_FILES} if (USE_KDU) add_library (llkdu ${llkdu_SOURCE_FILES}) + buildscripts_block(llkdu) target_link_libraries(llkdu ${KDU_LIBRARY}) diff --git a/indra/llmath/CMakeLists.txt b/indra/llmath/CMakeLists.txt index 4c8bcdac91..110173add3 100644 --- a/indra/llmath/CMakeLists.txt +++ b/indra/llmath/CMakeLists.txt @@ -101,6 +101,7 @@ set_source_files_properties(${llmath_HEADER_FILES} list(APPEND llmath_SOURCE_FILES ${llmath_HEADER_FILES}) add_library (llmath ${llmath_SOURCE_FILES}) +buildscripts_block(llmath) target_link_libraries(llmath ${LLCOMMON_LIBRARIES} diff --git a/indra/llmessage/CMakeLists.txt b/indra/llmessage/CMakeLists.txt index e0922c0667..ab59c8bb40 100644 --- a/indra/llmessage/CMakeLists.txt +++ b/indra/llmessage/CMakeLists.txt @@ -203,6 +203,7 @@ set_source_files_properties(${llmessage_HEADER_FILES} list(APPEND llmessage_SOURCE_FILES ${llmessage_HEADER_FILES}) add_library (llmessage ${llmessage_SOURCE_FILES}) +buildscripts_block(llmessage) if (LINUX) target_link_libraries( diff --git a/indra/llplugin/CMakeLists.txt b/indra/llplugin/CMakeLists.txt index 5cc129a267..9d79eabbb3 100644 --- a/indra/llplugin/CMakeLists.txt +++ b/indra/llplugin/CMakeLists.txt @@ -65,6 +65,7 @@ endif(NOT ADDRESS_SIZE EQUAL 32) list(APPEND llplugin_SOURCE_FILES ${llplugin_HEADER_FILES}) add_library (llplugin ${llplugin_SOURCE_FILES}) +buildscripts_block(llplugin) add_subdirectory(slplugin) diff --git a/indra/llplugin/slplugin/CMakeLists.txt b/indra/llplugin/slplugin/CMakeLists.txt index 0e5e835777..3a9d661ff6 100644 --- a/indra/llplugin/slplugin/CMakeLists.txt +++ b/indra/llplugin/slplugin/CMakeLists.txt @@ -48,7 +48,8 @@ add_executable(SLPlugin WIN32 MACOSX_BUNDLE ${SLPlugin_SOURCE_FILES} -) + ) +buildscripts_block(SLPlugin) if (WINDOWS) set_target_properties(SLPlugin diff --git a/indra/llprimitive/CMakeLists.txt b/indra/llprimitive/CMakeLists.txt index dd2e806dda..12c6882844 100644 --- a/indra/llprimitive/CMakeLists.txt +++ b/indra/llprimitive/CMakeLists.txt @@ -71,6 +71,7 @@ set_source_files_properties(${llprimitive_HEADER_FILES} list(APPEND llprimitive_SOURCE_FILES ${llprimitive_HEADER_FILES}) add_library (llprimitive ${llprimitive_SOURCE_FILES}) +buildscripts_block(llprimitive) target_link_libraries(llprimitive ${LLCOMMON_LIBRARIES} diff --git a/indra/llrender/CMakeLists.txt b/indra/llrender/CMakeLists.txt index 07a0d8c402..de5f24758c 100644 --- a/indra/llrender/CMakeLists.txt +++ b/indra/llrender/CMakeLists.txt @@ -91,6 +91,7 @@ if (BUILD_HEADLESS) add_library (llrenderheadless ${llrender_SOURCE_FILES} ) + buildscripts_block(llrenderheadless) set_property(TARGET llrenderheadless PROPERTY COMPILE_DEFINITIONS LL_MESA=1 LL_MESA_HEADLESS=1 @@ -110,6 +111,7 @@ if (BUILD_HEADLESS) endif (BUILD_HEADLESS) add_library (llrender ${llrender_SOURCE_FILES}) +buildscripts_block(llrender) if (SDL_FOUND) set_property(TARGET llrender diff --git a/indra/llui/CMakeLists.txt b/indra/llui/CMakeLists.txt index 8054eb3619..41a79d5752 100644 --- a/indra/llui/CMakeLists.txt +++ b/indra/llui/CMakeLists.txt @@ -269,6 +269,7 @@ set_source_files_properties(llurlentry.cpp list(APPEND llui_SOURCE_FILES ${llui_HEADER_FILES}) add_library (llui ${llui_SOURCE_FILES}) +buildscripts_block(llui) # Libraries on which this library depends, needed for Linux builds # Sort by high-level to low-level target_link_libraries(llui diff --git a/indra/llvfs/CMakeLists.txt b/indra/llvfs/CMakeLists.txt index 67dce8c073..a9d602d333 100644 --- a/indra/llvfs/CMakeLists.txt +++ b/indra/llvfs/CMakeLists.txt @@ -64,6 +64,7 @@ set_source_files_properties(${llvfs_HEADER_FILES} list(APPEND llvfs_SOURCE_FILES ${llvfs_HEADER_FILES}) add_library (llvfs ${llvfs_SOURCE_FILES}) +buildscripts_block(llvfs) set(vfs_BOOST_LIBRARIES ${BOOST_FILESYSTEM_LIBRARY} diff --git a/indra/llwindow/CMakeLists.txt b/indra/llwindow/CMakeLists.txt index 0743fd899f..d7ab3bfebb 100644 --- a/indra/llwindow/CMakeLists.txt +++ b/indra/llwindow/CMakeLists.txt @@ -175,6 +175,7 @@ if (BUILD_HEADLESS) ${llwindow_SOURCE_FILES} ${llwindowheadless_SOURCE_FILES} ) + buildscripts_block(llwindowheadless) set_property(TARGET llwindowheadless PROPERTY COMPILE_DEFINITIONS LL_MESA=1 LL_MESA_HEADLESS=1 ) @@ -191,6 +192,7 @@ endif (llwindow_HEADER_FILES) ${llwindow_SOURCE_FILES} ${viewer_SOURCE_FILES} ) + buildscripts_block(llwindow) if (SDL_FOUND) set_property(TARGET llwindow diff --git a/indra/llxml/CMakeLists.txt b/indra/llxml/CMakeLists.txt index 17400a203e..cb2d0f5c76 100644 --- a/indra/llxml/CMakeLists.txt +++ b/indra/llxml/CMakeLists.txt @@ -40,6 +40,7 @@ set_source_files_properties(${llxml_HEADER_FILES} list(APPEND llxml_SOURCE_FILES ${llxml_HEADER_FILES}) add_library (llxml ${llxml_SOURCE_FILES}) +buildscripts_block(llxml) # Libraries on which this library depends, needed for Linux builds # Sort by high-level to low-level target_link_libraries( llxml diff --git a/indra/mac_crash_logger/CMakeLists.txt b/indra/mac_crash_logger/CMakeLists.txt index f6c4dfb59d..f62bab5673 100644 --- a/indra/mac_crash_logger/CMakeLists.txt +++ b/indra/mac_crash_logger/CMakeLists.txt @@ -58,6 +58,7 @@ list(APPEND mac_crash_logger_SOURCE_FILES ${mac_crash_logger_RESOURCE_FILES}) add_executable(mac-crash-logger MACOSX_BUNDLE ${mac_crash_logger_SOURCE_FILES}) +buildscripts_block(mac-crash-logger) set_target_properties(mac-crash-logger PROPERTIES diff --git a/indra/media_plugins/base/CMakeLists.txt b/indra/media_plugins/base/CMakeLists.txt index 70c81d4023..8ab535e14c 100644 --- a/indra/media_plugins/base/CMakeLists.txt +++ b/indra/media_plugins/base/CMakeLists.txt @@ -48,5 +48,6 @@ set(media_plugin_base_HEADER_FILES add_library(media_plugin_base ${media_plugin_base_SOURCE_FILES} -) + ) +buildscripts_block(media_plugin_base) diff --git a/indra/media_plugins/cef/CMakeLists.txt b/indra/media_plugins/cef/CMakeLists.txt index 5452fd9d1e..dedc47e341 100644 --- a/indra/media_plugins/cef/CMakeLists.txt +++ b/indra/media_plugins/cef/CMakeLists.txt @@ -81,7 +81,8 @@ list(APPEND media_plugin_cef_SOURCE_FILES ${media_plugin_cef_HEADER_FILES}) add_library(media_plugin_cef SHARED ${media_plugin_cef_SOURCE_FILES} -) + ) +buildscripts_block(media_plugin_cef) #add_dependencies(media_plugin_cef # ${MEDIA_PLUGIN_BASE_LIBRARIES} diff --git a/indra/media_plugins/example/CMakeLists.txt b/indra/media_plugins/example/CMakeLists.txt index 6f5b28b8e9..95d3d5b5a2 100644 --- a/indra/media_plugins/example/CMakeLists.txt +++ b/indra/media_plugins/example/CMakeLists.txt @@ -47,7 +47,8 @@ set(media_plugin_example_SOURCE_FILES add_library(media_plugin_example SHARED ${media_plugin_example_SOURCE_FILES} -) + ) +buildscripts_block(media_plugin_example) target_link_libraries(media_plugin_example ${LLPLUGIN_LIBRARIES} diff --git a/indra/media_plugins/gstreamer010/CMakeLists.txt b/indra/media_plugins/gstreamer010/CMakeLists.txt index 6d18814b1e..18b4b761cf 100644 --- a/indra/media_plugins/gstreamer010/CMakeLists.txt +++ b/indra/media_plugins/gstreamer010/CMakeLists.txt @@ -56,7 +56,8 @@ set(media_plugin_gstreamer010_HEADER_FILES add_library(media_plugin_gstreamer010 SHARED ${media_plugin_gstreamer010_SOURCE_FILES} -) + ) +buildscripts_block(media_plugin_gstreamer010) target_link_libraries(media_plugin_gstreamer010 ${LLPLUGIN_LIBRARIES} diff --git a/indra/media_plugins/libvlc/CMakeLists.txt b/indra/media_plugins/libvlc/CMakeLists.txt index d3e9243069..7946e7ccfc 100644 --- a/indra/media_plugins/libvlc/CMakeLists.txt +++ b/indra/media_plugins/libvlc/CMakeLists.txt @@ -48,7 +48,8 @@ set(media_plugin_libvlc_SOURCE_FILES add_library(media_plugin_libvlc SHARED ${media_plugin_libvlc_SOURCE_FILES} -) + ) +buildscripts_block(media_plugin_libvlc) target_link_libraries(media_plugin_libvlc ${LLPLUGIN_LIBRARIES} diff --git a/indra/newview/CMakeLists.txt b/indra/newview/CMakeLists.txt index e573b927d7..560c9d0737 100644 --- a/indra/newview/CMakeLists.txt +++ b/indra/newview/CMakeLists.txt @@ -1722,6 +1722,7 @@ add_executable(${VIEWER_BINARY_NAME} MACOSX_BUNDLE ${viewer_SOURCE_FILES} ) +buildscripts_block(${VIEWER_BINARY_NAME}) if (SDL_FOUND) set_property(TARGET ${VIEWER_BINARY_NAME} @@ -1914,6 +1915,7 @@ if (WINDOWS) ${CMAKE_CFG_INTDIR}/touched.bat windows-setup-build-all ) + buildscripts_block(llpackage) # temporarily disable packaging of event_host until hg subrepos get # sorted out on the parabuild cluster... #${CMAKE_CURRENT_BINARY_DIR}/${CMAKE_CFG_INTDIR}/event_host.tar.bz2) @@ -2253,6 +2255,7 @@ if (PACKAGE AND (RELEASE_CRASH_REPORTING OR NON_RELEASE_CRASH_REPORTING) AND VIE VERBATIM) add_custom_target(generate_symbols DEPENDS "${VIEWER_SYMBOL_FILE}" ${VIEWER_BINARY_NAME} "${VIEWER_COPY_MANIFEST}") + buildscripts_block(generate_symbols) add_dependencies(generate_symbols ${VIEWER_BINARY_NAME}) if (WINDOWS OR LINUX) add_dependencies(generate_symbols "${VIEWER_COPY_MANIFEST}") @@ -2285,6 +2288,7 @@ if (PACKAGE AND (RELEASE_CRASH_REPORTING OR NON_RELEASE_CRASH_REPORTING) AND VIE COMMENT "Packing viewer PDB into ${VIEWER_SYMBOL_FILE_CYGWIN}" ) add_custom_target(generate_symbols DEPENDS "${VIEWER_SYMBOL_FILE}" ${VIEWER_BINARY_NAME}) + buildscripts_block(generate_symbols) add_dependencies(generate_symbols ${VIEWER_BINARY_NAME}) endif (WINDOWS) if (DARWIN) @@ -2296,6 +2300,7 @@ if (PACKAGE AND (RELEASE_CRASH_REPORTING OR NON_RELEASE_CRASH_REPORTING) AND VIE COMMENT "Generating ${VIEWER_APP_DSYM}" ) add_custom_target(dsym_generate DEPENDS "${VIEWER_APP_DSYM}") + buildscripts_block(dsym_generate) add_dependencies(dsym_generate ${VIEWER_BINARY_NAME}) add_custom_command(OUTPUT "${VIEWER_SYMBOL_FILE}" # See above comments about "tar ...j" @@ -2310,6 +2315,7 @@ if (PACKAGE AND (RELEASE_CRASH_REPORTING OR NON_RELEASE_CRASH_REPORTING) AND VIE COMMENT "Packing dSYM into ${VIEWER_SYMBOL_FILE}" ) add_custom_target(dsym_tarball DEPENDS "${VIEWER_SYMBOL_FILE}") + buildscripts_block(dsym_tarball) add_dependencies(dsym_tarball dsym_generate) add_custom_command(OUTPUT "${VIEWER_APP_XCARCHIVE}" COMMAND "zip" @@ -2337,6 +2343,7 @@ if (PACKAGE AND (RELEASE_CRASH_REPORTING OR NON_RELEASE_CRASH_REPORTING) AND VIE "${VIEWER_APP_XCARCHIVE}" "${CMAKE_CURRENT_BINARY_DIR}/dsym.stamp" ) + buildscripts_block(generate_symbols) add_dependencies(generate_symbols dsym_tarball dsym_xcarchive) endif (DARWIN) if (LINUX) diff --git a/indra/test/CMakeLists.txt b/indra/test/CMakeLists.txt index 8344cead57..11ec2226ea 100644 --- a/indra/test/CMakeLists.txt +++ b/indra/test/CMakeLists.txt @@ -81,6 +81,7 @@ set_source_files_properties(${test_HEADER_FILES} list(APPEND test_SOURCE_FILES ${test_HEADER_FILES}) add_executable(lltest ${test_SOURCE_FILES}) +buildscripts_block(lltest) target_link_libraries(lltest ${LLDATABASE_LIBRARIES} diff --git a/indra/viewer_components/login/CMakeLists.txt b/indra/viewer_components/login/CMakeLists.txt index 3bedeb7292..79706e0df4 100644 --- a/indra/viewer_components/login/CMakeLists.txt +++ b/indra/viewer_components/login/CMakeLists.txt @@ -42,6 +42,7 @@ list(APPEND add_library(lllogin ${login_SOURCE_FILES} ) +buildscripts_block(lllogin) target_link_libraries(lllogin ${LLMESSAGE_LIBRARIES} diff --git a/indra/win_crash_logger/CMakeLists.txt b/indra/win_crash_logger/CMakeLists.txt index 144d037a31..9d651fcbc9 100644 --- a/indra/win_crash_logger/CMakeLists.txt +++ b/indra/win_crash_logger/CMakeLists.txt @@ -71,6 +71,7 @@ list(APPEND find_library(DXGUID_LIBRARY dxguid ${DIRECTX_LIBRARY_DIR}) add_executable(windows-crash-logger WIN32 ${win_crash_logger_SOURCE_FILES}) +buildscripts_block(windows-crash-logger) target_link_libraries(windows-crash-logger ${BREAKPAD_EXCEPTION_HANDLER_LIBRARIES} -- cgit v1.3 From 9fd463bd9496ba5d97abec6ee75b9c0c089aa69d Mon Sep 17 00:00:00 2001 From: Oz Linden Date: Fri, 7 Sep 2018 09:13:57 -0400 Subject: remove only-partially-successful attempt to put teamcity blocks around targets --- indra/CMakeLists.txt | 1 - indra/cmake/00-Common.cmake | 23 ---------------------- indra/cmake/LLAddBuildTest.cmake | 3 --- .../llimage_libtest/CMakeLists.txt | 1 - .../integration_tests/llui_libtest/CMakeLists.txt | 1 - indra/linux_crash_logger/CMakeLists.txt | 2 -- indra/llappearance/CMakeLists.txt | 2 -- indra/llaudio/CMakeLists.txt | 1 - indra/llcharacter/CMakeLists.txt | 1 - indra/llcommon/CMakeLists.txt | 2 -- indra/llcorehttp/CMakeLists.txt | 2 -- indra/llcrashlogger/CMakeLists.txt | 1 - indra/llimage/CMakeLists.txt | 1 - indra/llimagej2coj/CMakeLists.txt | 1 - indra/llinventory/CMakeLists.txt | 1 - indra/llkdu/CMakeLists.txt | 1 - indra/llmath/CMakeLists.txt | 1 - indra/llmessage/CMakeLists.txt | 1 - indra/llplugin/CMakeLists.txt | 1 - indra/llplugin/slplugin/CMakeLists.txt | 1 - indra/llprimitive/CMakeLists.txt | 1 - indra/llrender/CMakeLists.txt | 2 -- indra/llui/CMakeLists.txt | 1 - indra/llvfs/CMakeLists.txt | 1 - indra/llwindow/CMakeLists.txt | 2 -- indra/llxml/CMakeLists.txt | 1 - indra/mac_crash_logger/CMakeLists.txt | 1 - indra/media_plugins/base/CMakeLists.txt | 1 - indra/media_plugins/cef/CMakeLists.txt | 1 - indra/media_plugins/example/CMakeLists.txt | 1 - indra/media_plugins/gstreamer010/CMakeLists.txt | 1 - indra/media_plugins/libvlc/CMakeLists.txt | 1 - indra/newview/CMakeLists.txt | 7 ------- indra/test/CMakeLists.txt | 1 - indra/viewer_components/login/CMakeLists.txt | 1 - indra/win_crash_logger/CMakeLists.txt | 1 - 36 files changed, 72 deletions(-) (limited to 'indra/llcommon') diff --git a/indra/CMakeLists.txt b/indra/CMakeLists.txt index 08d0c7b510..6c20a813ba 100644 --- a/indra/CMakeLists.txt +++ b/indra/CMakeLists.txt @@ -44,7 +44,6 @@ if (WINDOWS AND EXISTS ${LIBS_CLOSED_DIR}copy_win_scripts) endif (WINDOWS AND EXISTS ${LIBS_CLOSED_DIR}copy_win_scripts) add_custom_target(viewer) -buildscripts_block(viewer) add_subdirectory(${LIBS_OPEN_PREFIX}llcrashlogger) add_subdirectory(${LIBS_OPEN_PREFIX}llplugin) diff --git a/indra/cmake/00-Common.cmake b/indra/cmake/00-Common.cmake index 503f4208fe..40fc706a99 100644 --- a/indra/cmake/00-Common.cmake +++ b/indra/cmake/00-Common.cmake @@ -217,27 +217,4 @@ else (USESYSTEMLIBS) ) endif (USESYSTEMLIBS) -macro (buildscripts_block target_name) - # add custom commands to bracket a target build to make logs easier to read - # this is disabled for windows because VS interleaves output in a way that defeats it - if (NOT WINDOWS AND DEFINED ENV{TEAMCITY_BUILDCONF_NAME}) - add_custom_command(TARGET ${target_name} PRE_BUILD - COMMAND echo ARGS "-n" "##" - COMMAND echo ARGS "teamcity[blockOpened name='${target_name}']" - ) - add_custom_command(TARGET ${target_name} POST_BUILD - COMMAND echo ARGS "-n" "##" - COMMAND echo ARGS "teamcity[blockClosed name='${target_name}']" - ) - else (NOT WINDOWS AND DEFINED ENV{TEAMCITY_BUILDCONF_NAME}) - add_custom_command(TARGET ${target_name} PRE_BUILD - COMMAND echo ARGS "################## START ${target_name}" - ) - add_custom_command(TARGET ${target_name} POST_BUILD - COMMAND echo ARGS "################## FINISH ${target_name}" - ) - endif (NOT WINDOWS AND DEFINED ENV{TEAMCITY_BUILDCONF_NAME}) - -endmacro (buildscripts_block target_name) - endif(NOT DEFINED ${CMAKE_CURRENT_LIST_FILE}_INCLUDED) diff --git a/indra/cmake/LLAddBuildTest.cmake b/indra/cmake/LLAddBuildTest.cmake index 3b5bc0af7c..b3f42c1a5e 100644 --- a/indra/cmake/LLAddBuildTest.cmake +++ b/indra/cmake/LLAddBuildTest.cmake @@ -105,7 +105,6 @@ INCLUDE(GoogleMock) # Setup target ADD_EXECUTABLE(PROJECT_${project}_TEST_${name} ${${name}_test_SOURCE_FILES}) - buildscripts_block(PROJECT_${project}_TEST_${name}) SET_TARGET_PROPERTIES(PROJECT_${project}_TEST_${name} PROPERTIES RUNTIME_OUTPUT_DIRECTORY "${EXE_STAGING_DIR}") # @@ -167,7 +166,6 @@ INCLUDE(GoogleMock) # Add the test runner target per-project # (replaces old _test_ok targets all over the place) ADD_CUSTOM_TARGET(${project}_tests ALL DEPENDS ${${project}_TEST_OUTPUT}) - buildscripts_block(${project}_tests) ADD_DEPENDENCIES(${project} ${project}_tests) ENDMACRO(LL_ADD_PROJECT_UNIT_TESTS) @@ -215,7 +213,6 @@ FUNCTION(LL_ADD_INTEGRATION_TEST message(STATUS "ADD_EXECUTABLE(INTEGRATION_TEST_${testname} ${source_files})") endif(TEST_DEBUG) ADD_EXECUTABLE(INTEGRATION_TEST_${testname} ${source_files}) - buildscripts_block(INTEGRATION_TEST_${testname}) SET_TARGET_PROPERTIES(INTEGRATION_TEST_${testname} PROPERTIES RUNTIME_OUTPUT_DIRECTORY "${EXE_STAGING_DIR}" diff --git a/indra/integration_tests/llimage_libtest/CMakeLists.txt b/indra/integration_tests/llimage_libtest/CMakeLists.txt index 4e23a1fc87..d9353f904c 100644 --- a/indra/integration_tests/llimage_libtest/CMakeLists.txt +++ b/indra/integration_tests/llimage_libtest/CMakeLists.txt @@ -41,7 +41,6 @@ add_executable(llimage_libtest MACOSX_BUNDLE ${llimage_libtest_SOURCE_FILES} ) -buildscripts_block(llimage_libtest) set_target_properties(llimage_libtest PROPERTIES diff --git a/indra/integration_tests/llui_libtest/CMakeLists.txt b/indra/integration_tests/llui_libtest/CMakeLists.txt index 2d21f9af0f..34e34c7e47 100644 --- a/indra/integration_tests/llui_libtest/CMakeLists.txt +++ b/indra/integration_tests/llui_libtest/CMakeLists.txt @@ -56,7 +56,6 @@ set_source_files_properties(${llui_libtest_HEADER_FILES} list(APPEND llui_libtest_SOURCE_FILES ${llui_libtest_HEADER_FILES}) add_executable(llui_libtest ${llui_libtest_SOURCE_FILES}) -buildscripts_block(llui_libtest) # Link with OS-specific libraries for LLWindow dependency if (DARWIN) diff --git a/indra/linux_crash_logger/CMakeLists.txt b/indra/linux_crash_logger/CMakeLists.txt index 165b33fede..315aed8d11 100644 --- a/indra/linux_crash_logger/CMakeLists.txt +++ b/indra/linux_crash_logger/CMakeLists.txt @@ -55,7 +55,6 @@ list(APPEND linux_crash_logger_SOURCE_FILES set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -Wl,--as-needed") add_executable(linux-crash-logger ${linux_crash_logger_SOURCE_FILES}) -buildscripts_block(linux-crash-logger) # llcommon uses `clock_gettime' which is provided by librt on linux. set(LIBRT_LIBRARY rt) @@ -80,4 +79,3 @@ target_link_libraries(linux-crash-logger add_custom_target(linux-crash-logger-target ALL DEPENDS linux-crash-logger) -buildscripts_block(linux-crash-logger-target) diff --git a/indra/llappearance/CMakeLists.txt b/indra/llappearance/CMakeLists.txt index ad33fed010..20eb4678dd 100644 --- a/indra/llappearance/CMakeLists.txt +++ b/indra/llappearance/CMakeLists.txt @@ -77,7 +77,6 @@ set_source_files_properties(${llappearance_HEADER_FILES} list(APPEND llappearance_SOURCE_FILES ${llappearance_HEADER_FILES}) add_library (llappearance ${llappearance_SOURCE_FILES}) -buildscripts_block(llappearance) target_link_libraries(llappearance ${LLCHARACTER_LIBRARIES} @@ -95,7 +94,6 @@ target_link_libraries(llappearance if (BUILD_HEADLESS) add_library (llappearanceheadless ${llappearance_SOURCE_FILES}) - buildscripts_block(llappearanceheadless) target_link_libraries(llappearanceheadless ${LLCHARACTER_LIBRARIES} diff --git a/indra/llaudio/CMakeLists.txt b/indra/llaudio/CMakeLists.txt index fc81d8c6f2..e943dd5d5c 100644 --- a/indra/llaudio/CMakeLists.txt +++ b/indra/llaudio/CMakeLists.txt @@ -77,7 +77,6 @@ set_source_files_properties(${llaudio_HEADER_FILES} list(APPEND llaudio_SOURCE_FILES ${llaudio_HEADER_FILES}) add_library (llaudio ${llaudio_SOURCE_FILES}) -buildscripts_block(llaudio) target_link_libraries( llaudio ${LLCOMMON_LIBRARIES} diff --git a/indra/llcharacter/CMakeLists.txt b/indra/llcharacter/CMakeLists.txt index 3d0eb09ada..a17a5b0aa6 100644 --- a/indra/llcharacter/CMakeLists.txt +++ b/indra/llcharacter/CMakeLists.txt @@ -79,7 +79,6 @@ set_source_files_properties(${llcharacter_HEADER_FILES} list(APPEND llcharacter_SOURCE_FILES ${llcharacter_HEADER_FILES}) add_library (llcharacter ${llcharacter_SOURCE_FILES}) -buildscripts_block(llcharacter) target_link_libraries( llcharacter diff --git a/indra/llcommon/CMakeLists.txt b/indra/llcommon/CMakeLists.txt index 0d58a59e3f..42ad56f1b0 100644 --- a/indra/llcommon/CMakeLists.txt +++ b/indra/llcommon/CMakeLists.txt @@ -24,7 +24,6 @@ include_directories( ) # add_executable(lltreeiterators lltreeiterators.cpp) -# buildscripts_block(lltreeiterators) # # target_link_libraries(lltreeiterators # ${LLCOMMON_LIBRARIES}) @@ -280,7 +279,6 @@ if(LLCOMMON_LINK_SHARED) else(LLCOMMON_LINK_SHARED) add_library (llcommon ${llcommon_SOURCE_FILES}) endif(LLCOMMON_LINK_SHARED) -buildscripts_block(llcommon) target_link_libraries( llcommon diff --git a/indra/llcorehttp/CMakeLists.txt b/indra/llcorehttp/CMakeLists.txt index c42bd7b6b2..9dbc6f447e 100644 --- a/indra/llcorehttp/CMakeLists.txt +++ b/indra/llcorehttp/CMakeLists.txt @@ -90,7 +90,6 @@ endif (DARWIN OR LINUX) list(APPEND llcorehttp_SOURCE_FILES ${llcorehttp_HEADER_FILES}) add_library (llcorehttp ${llcorehttp_SOURCE_FILES}) -buildscripts_block(llcorehttp) target_link_libraries( llcorehttp ${CURL_LIBRARIES} @@ -215,7 +214,6 @@ endif (DARWIN) add_executable(http_texture_load ${llcorehttp_EXAMPLE_SOURCE_FILES} ) - buildscripts_block(http_texture_load) set_target_properties(http_texture_load PROPERTIES RUNTIME_OUTPUT_DIRECTORY "${EXE_STAGING_DIR}" diff --git a/indra/llcrashlogger/CMakeLists.txt b/indra/llcrashlogger/CMakeLists.txt index 7d7f3f0167..da23b46b7b 100644 --- a/indra/llcrashlogger/CMakeLists.txt +++ b/indra/llcrashlogger/CMakeLists.txt @@ -41,4 +41,3 @@ set_source_files_properties(${llcrashlogger_HEADER_FILES} list(APPEND llcrashlogger_SOURCE_FILES ${llcrashlogger_HEADER_FILES}) add_library(llcrashlogger ${llcrashlogger_SOURCE_FILES}) -buildscripts_block(llcrashlogger) diff --git a/indra/llimage/CMakeLists.txt b/indra/llimage/CMakeLists.txt index 4b57a77999..293ada7548 100644 --- a/indra/llimage/CMakeLists.txt +++ b/indra/llimage/CMakeLists.txt @@ -59,7 +59,6 @@ set_source_files_properties(${llimage_HEADER_FILES} list(APPEND llimage_SOURCE_FILES ${llimage_HEADER_FILES}) add_library (llimage ${llimage_SOURCE_FILES}) -buildscripts_block(llimage) # Libraries on which this library depends, needed for Linux builds # Sort by high-level to low-level if (USE_KDU) diff --git a/indra/llimagej2coj/CMakeLists.txt b/indra/llimagej2coj/CMakeLists.txt index f05842b721..c9423d50dd 100644 --- a/indra/llimagej2coj/CMakeLists.txt +++ b/indra/llimagej2coj/CMakeLists.txt @@ -29,7 +29,6 @@ set_source_files_properties(${llimagej2coj_HEADER_FILES} list(APPEND llimagej2coj_SOURCE_FILES ${llimagej2coj_HEADER_FILES}) add_library (llimagej2coj ${llimagej2coj_SOURCE_FILES}) -buildscripts_block(llimagej2coj) target_link_libraries( llimagej2coj diff --git a/indra/llinventory/CMakeLists.txt b/indra/llinventory/CMakeLists.txt index 6a5892127d..68dd00d880 100644 --- a/indra/llinventory/CMakeLists.txt +++ b/indra/llinventory/CMakeLists.txt @@ -60,7 +60,6 @@ set_source_files_properties(${llinventory_HEADER_FILES} list(APPEND llinventory_SOURCE_FILES ${llinventory_HEADER_FILES}) add_library (llinventory ${llinventory_SOURCE_FILES}) -buildscripts_block(llinventory) diff --git a/indra/llkdu/CMakeLists.txt b/indra/llkdu/CMakeLists.txt index 59f6d08517..cb0e204e91 100644 --- a/indra/llkdu/CMakeLists.txt +++ b/indra/llkdu/CMakeLists.txt @@ -50,7 +50,6 @@ set_source_files_properties(${llkdu_SOURCE_FILES} if (USE_KDU) add_library (llkdu ${llkdu_SOURCE_FILES}) - buildscripts_block(llkdu) target_link_libraries(llkdu ${KDU_LIBRARY}) diff --git a/indra/llmath/CMakeLists.txt b/indra/llmath/CMakeLists.txt index 110173add3..4c8bcdac91 100644 --- a/indra/llmath/CMakeLists.txt +++ b/indra/llmath/CMakeLists.txt @@ -101,7 +101,6 @@ set_source_files_properties(${llmath_HEADER_FILES} list(APPEND llmath_SOURCE_FILES ${llmath_HEADER_FILES}) add_library (llmath ${llmath_SOURCE_FILES}) -buildscripts_block(llmath) target_link_libraries(llmath ${LLCOMMON_LIBRARIES} diff --git a/indra/llmessage/CMakeLists.txt b/indra/llmessage/CMakeLists.txt index ab59c8bb40..e0922c0667 100644 --- a/indra/llmessage/CMakeLists.txt +++ b/indra/llmessage/CMakeLists.txt @@ -203,7 +203,6 @@ set_source_files_properties(${llmessage_HEADER_FILES} list(APPEND llmessage_SOURCE_FILES ${llmessage_HEADER_FILES}) add_library (llmessage ${llmessage_SOURCE_FILES}) -buildscripts_block(llmessage) if (LINUX) target_link_libraries( diff --git a/indra/llplugin/CMakeLists.txt b/indra/llplugin/CMakeLists.txt index 9d79eabbb3..5cc129a267 100644 --- a/indra/llplugin/CMakeLists.txt +++ b/indra/llplugin/CMakeLists.txt @@ -65,7 +65,6 @@ endif(NOT ADDRESS_SIZE EQUAL 32) list(APPEND llplugin_SOURCE_FILES ${llplugin_HEADER_FILES}) add_library (llplugin ${llplugin_SOURCE_FILES}) -buildscripts_block(llplugin) add_subdirectory(slplugin) diff --git a/indra/llplugin/slplugin/CMakeLists.txt b/indra/llplugin/slplugin/CMakeLists.txt index 3a9d661ff6..33520ad64c 100644 --- a/indra/llplugin/slplugin/CMakeLists.txt +++ b/indra/llplugin/slplugin/CMakeLists.txt @@ -49,7 +49,6 @@ add_executable(SLPlugin MACOSX_BUNDLE ${SLPlugin_SOURCE_FILES} ) -buildscripts_block(SLPlugin) if (WINDOWS) set_target_properties(SLPlugin diff --git a/indra/llprimitive/CMakeLists.txt b/indra/llprimitive/CMakeLists.txt index 12c6882844..dd2e806dda 100644 --- a/indra/llprimitive/CMakeLists.txt +++ b/indra/llprimitive/CMakeLists.txt @@ -71,7 +71,6 @@ set_source_files_properties(${llprimitive_HEADER_FILES} list(APPEND llprimitive_SOURCE_FILES ${llprimitive_HEADER_FILES}) add_library (llprimitive ${llprimitive_SOURCE_FILES}) -buildscripts_block(llprimitive) target_link_libraries(llprimitive ${LLCOMMON_LIBRARIES} diff --git a/indra/llrender/CMakeLists.txt b/indra/llrender/CMakeLists.txt index de5f24758c..07a0d8c402 100644 --- a/indra/llrender/CMakeLists.txt +++ b/indra/llrender/CMakeLists.txt @@ -91,7 +91,6 @@ if (BUILD_HEADLESS) add_library (llrenderheadless ${llrender_SOURCE_FILES} ) - buildscripts_block(llrenderheadless) set_property(TARGET llrenderheadless PROPERTY COMPILE_DEFINITIONS LL_MESA=1 LL_MESA_HEADLESS=1 @@ -111,7 +110,6 @@ if (BUILD_HEADLESS) endif (BUILD_HEADLESS) add_library (llrender ${llrender_SOURCE_FILES}) -buildscripts_block(llrender) if (SDL_FOUND) set_property(TARGET llrender diff --git a/indra/llui/CMakeLists.txt b/indra/llui/CMakeLists.txt index 41a79d5752..8054eb3619 100644 --- a/indra/llui/CMakeLists.txt +++ b/indra/llui/CMakeLists.txt @@ -269,7 +269,6 @@ set_source_files_properties(llurlentry.cpp list(APPEND llui_SOURCE_FILES ${llui_HEADER_FILES}) add_library (llui ${llui_SOURCE_FILES}) -buildscripts_block(llui) # Libraries on which this library depends, needed for Linux builds # Sort by high-level to low-level target_link_libraries(llui diff --git a/indra/llvfs/CMakeLists.txt b/indra/llvfs/CMakeLists.txt index a9d602d333..67dce8c073 100644 --- a/indra/llvfs/CMakeLists.txt +++ b/indra/llvfs/CMakeLists.txt @@ -64,7 +64,6 @@ set_source_files_properties(${llvfs_HEADER_FILES} list(APPEND llvfs_SOURCE_FILES ${llvfs_HEADER_FILES}) add_library (llvfs ${llvfs_SOURCE_FILES}) -buildscripts_block(llvfs) set(vfs_BOOST_LIBRARIES ${BOOST_FILESYSTEM_LIBRARY} diff --git a/indra/llwindow/CMakeLists.txt b/indra/llwindow/CMakeLists.txt index d7ab3bfebb..0743fd899f 100644 --- a/indra/llwindow/CMakeLists.txt +++ b/indra/llwindow/CMakeLists.txt @@ -175,7 +175,6 @@ if (BUILD_HEADLESS) ${llwindow_SOURCE_FILES} ${llwindowheadless_SOURCE_FILES} ) - buildscripts_block(llwindowheadless) set_property(TARGET llwindowheadless PROPERTY COMPILE_DEFINITIONS LL_MESA=1 LL_MESA_HEADLESS=1 ) @@ -192,7 +191,6 @@ endif (llwindow_HEADER_FILES) ${llwindow_SOURCE_FILES} ${viewer_SOURCE_FILES} ) - buildscripts_block(llwindow) if (SDL_FOUND) set_property(TARGET llwindow diff --git a/indra/llxml/CMakeLists.txt b/indra/llxml/CMakeLists.txt index cb2d0f5c76..17400a203e 100644 --- a/indra/llxml/CMakeLists.txt +++ b/indra/llxml/CMakeLists.txt @@ -40,7 +40,6 @@ set_source_files_properties(${llxml_HEADER_FILES} list(APPEND llxml_SOURCE_FILES ${llxml_HEADER_FILES}) add_library (llxml ${llxml_SOURCE_FILES}) -buildscripts_block(llxml) # Libraries on which this library depends, needed for Linux builds # Sort by high-level to low-level target_link_libraries( llxml diff --git a/indra/mac_crash_logger/CMakeLists.txt b/indra/mac_crash_logger/CMakeLists.txt index f62bab5673..f6c4dfb59d 100644 --- a/indra/mac_crash_logger/CMakeLists.txt +++ b/indra/mac_crash_logger/CMakeLists.txt @@ -58,7 +58,6 @@ list(APPEND mac_crash_logger_SOURCE_FILES ${mac_crash_logger_RESOURCE_FILES}) add_executable(mac-crash-logger MACOSX_BUNDLE ${mac_crash_logger_SOURCE_FILES}) -buildscripts_block(mac-crash-logger) set_target_properties(mac-crash-logger PROPERTIES diff --git a/indra/media_plugins/base/CMakeLists.txt b/indra/media_plugins/base/CMakeLists.txt index 8ab535e14c..7f2b82ffdd 100644 --- a/indra/media_plugins/base/CMakeLists.txt +++ b/indra/media_plugins/base/CMakeLists.txt @@ -49,5 +49,4 @@ set(media_plugin_base_HEADER_FILES add_library(media_plugin_base ${media_plugin_base_SOURCE_FILES} ) -buildscripts_block(media_plugin_base) diff --git a/indra/media_plugins/cef/CMakeLists.txt b/indra/media_plugins/cef/CMakeLists.txt index dedc47e341..ce6278963d 100644 --- a/indra/media_plugins/cef/CMakeLists.txt +++ b/indra/media_plugins/cef/CMakeLists.txt @@ -82,7 +82,6 @@ add_library(media_plugin_cef SHARED ${media_plugin_cef_SOURCE_FILES} ) -buildscripts_block(media_plugin_cef) #add_dependencies(media_plugin_cef # ${MEDIA_PLUGIN_BASE_LIBRARIES} diff --git a/indra/media_plugins/example/CMakeLists.txt b/indra/media_plugins/example/CMakeLists.txt index 95d3d5b5a2..eb067a7f6e 100644 --- a/indra/media_plugins/example/CMakeLists.txt +++ b/indra/media_plugins/example/CMakeLists.txt @@ -48,7 +48,6 @@ add_library(media_plugin_example SHARED ${media_plugin_example_SOURCE_FILES} ) -buildscripts_block(media_plugin_example) target_link_libraries(media_plugin_example ${LLPLUGIN_LIBRARIES} diff --git a/indra/media_plugins/gstreamer010/CMakeLists.txt b/indra/media_plugins/gstreamer010/CMakeLists.txt index 18b4b761cf..571eb57b24 100644 --- a/indra/media_plugins/gstreamer010/CMakeLists.txt +++ b/indra/media_plugins/gstreamer010/CMakeLists.txt @@ -57,7 +57,6 @@ add_library(media_plugin_gstreamer010 SHARED ${media_plugin_gstreamer010_SOURCE_FILES} ) -buildscripts_block(media_plugin_gstreamer010) target_link_libraries(media_plugin_gstreamer010 ${LLPLUGIN_LIBRARIES} diff --git a/indra/media_plugins/libvlc/CMakeLists.txt b/indra/media_plugins/libvlc/CMakeLists.txt index 7946e7ccfc..97392bbe08 100644 --- a/indra/media_plugins/libvlc/CMakeLists.txt +++ b/indra/media_plugins/libvlc/CMakeLists.txt @@ -49,7 +49,6 @@ add_library(media_plugin_libvlc SHARED ${media_plugin_libvlc_SOURCE_FILES} ) -buildscripts_block(media_plugin_libvlc) target_link_libraries(media_plugin_libvlc ${LLPLUGIN_LIBRARIES} diff --git a/indra/newview/CMakeLists.txt b/indra/newview/CMakeLists.txt index 560c9d0737..e573b927d7 100644 --- a/indra/newview/CMakeLists.txt +++ b/indra/newview/CMakeLists.txt @@ -1722,7 +1722,6 @@ add_executable(${VIEWER_BINARY_NAME} MACOSX_BUNDLE ${viewer_SOURCE_FILES} ) -buildscripts_block(${VIEWER_BINARY_NAME}) if (SDL_FOUND) set_property(TARGET ${VIEWER_BINARY_NAME} @@ -1915,7 +1914,6 @@ if (WINDOWS) ${CMAKE_CFG_INTDIR}/touched.bat windows-setup-build-all ) - buildscripts_block(llpackage) # temporarily disable packaging of event_host until hg subrepos get # sorted out on the parabuild cluster... #${CMAKE_CURRENT_BINARY_DIR}/${CMAKE_CFG_INTDIR}/event_host.tar.bz2) @@ -2255,7 +2253,6 @@ if (PACKAGE AND (RELEASE_CRASH_REPORTING OR NON_RELEASE_CRASH_REPORTING) AND VIE VERBATIM) add_custom_target(generate_symbols DEPENDS "${VIEWER_SYMBOL_FILE}" ${VIEWER_BINARY_NAME} "${VIEWER_COPY_MANIFEST}") - buildscripts_block(generate_symbols) add_dependencies(generate_symbols ${VIEWER_BINARY_NAME}) if (WINDOWS OR LINUX) add_dependencies(generate_symbols "${VIEWER_COPY_MANIFEST}") @@ -2288,7 +2285,6 @@ if (PACKAGE AND (RELEASE_CRASH_REPORTING OR NON_RELEASE_CRASH_REPORTING) AND VIE COMMENT "Packing viewer PDB into ${VIEWER_SYMBOL_FILE_CYGWIN}" ) add_custom_target(generate_symbols DEPENDS "${VIEWER_SYMBOL_FILE}" ${VIEWER_BINARY_NAME}) - buildscripts_block(generate_symbols) add_dependencies(generate_symbols ${VIEWER_BINARY_NAME}) endif (WINDOWS) if (DARWIN) @@ -2300,7 +2296,6 @@ if (PACKAGE AND (RELEASE_CRASH_REPORTING OR NON_RELEASE_CRASH_REPORTING) AND VIE COMMENT "Generating ${VIEWER_APP_DSYM}" ) add_custom_target(dsym_generate DEPENDS "${VIEWER_APP_DSYM}") - buildscripts_block(dsym_generate) add_dependencies(dsym_generate ${VIEWER_BINARY_NAME}) add_custom_command(OUTPUT "${VIEWER_SYMBOL_FILE}" # See above comments about "tar ...j" @@ -2315,7 +2310,6 @@ if (PACKAGE AND (RELEASE_CRASH_REPORTING OR NON_RELEASE_CRASH_REPORTING) AND VIE COMMENT "Packing dSYM into ${VIEWER_SYMBOL_FILE}" ) add_custom_target(dsym_tarball DEPENDS "${VIEWER_SYMBOL_FILE}") - buildscripts_block(dsym_tarball) add_dependencies(dsym_tarball dsym_generate) add_custom_command(OUTPUT "${VIEWER_APP_XCARCHIVE}" COMMAND "zip" @@ -2343,7 +2337,6 @@ if (PACKAGE AND (RELEASE_CRASH_REPORTING OR NON_RELEASE_CRASH_REPORTING) AND VIE "${VIEWER_APP_XCARCHIVE}" "${CMAKE_CURRENT_BINARY_DIR}/dsym.stamp" ) - buildscripts_block(generate_symbols) add_dependencies(generate_symbols dsym_tarball dsym_xcarchive) endif (DARWIN) if (LINUX) diff --git a/indra/test/CMakeLists.txt b/indra/test/CMakeLists.txt index 11ec2226ea..8344cead57 100644 --- a/indra/test/CMakeLists.txt +++ b/indra/test/CMakeLists.txt @@ -81,7 +81,6 @@ set_source_files_properties(${test_HEADER_FILES} list(APPEND test_SOURCE_FILES ${test_HEADER_FILES}) add_executable(lltest ${test_SOURCE_FILES}) -buildscripts_block(lltest) target_link_libraries(lltest ${LLDATABASE_LIBRARIES} diff --git a/indra/viewer_components/login/CMakeLists.txt b/indra/viewer_components/login/CMakeLists.txt index 79706e0df4..3bedeb7292 100644 --- a/indra/viewer_components/login/CMakeLists.txt +++ b/indra/viewer_components/login/CMakeLists.txt @@ -42,7 +42,6 @@ list(APPEND add_library(lllogin ${login_SOURCE_FILES} ) -buildscripts_block(lllogin) target_link_libraries(lllogin ${LLMESSAGE_LIBRARIES} diff --git a/indra/win_crash_logger/CMakeLists.txt b/indra/win_crash_logger/CMakeLists.txt index 9d651fcbc9..144d037a31 100644 --- a/indra/win_crash_logger/CMakeLists.txt +++ b/indra/win_crash_logger/CMakeLists.txt @@ -71,7 +71,6 @@ list(APPEND find_library(DXGUID_LIBRARY dxguid ${DIRECTX_LIBRARY_DIR}) add_executable(windows-crash-logger WIN32 ${win_crash_logger_SOURCE_FILES}) -buildscripts_block(windows-crash-logger) target_link_libraries(windows-crash-logger ${BREAKPAD_EXCEPTION_HANDLER_LIBRARIES} -- cgit v1.3 From fc8b4ec587d8a05579244940e30b81519a1ebf91 Mon Sep 17 00:00:00 2001 From: Nat Goodspeed Date: Wed, 26 Sep 2018 16:50:58 -0400 Subject: DRTVWR-447: Finish pulling in new viewer-release. --- autobuild.xml | 54 ++++++++++++++++++++++++++++++++++++++++++++++ indra/llcommon/llerror.cpp | 27 ++++++++++++++++------- 2 files changed, 73 insertions(+), 8 deletions(-) (limited to 'indra/llcommon') diff --git a/autobuild.xml b/autobuild.xml index 3107d77548..f615a52ba8 100644 --- a/autobuild.xml +++ b/autobuild.xml @@ -225,6 +225,60 @@ version 1.57 + bugsplat + + copyright + Copyright 2003-2017, BugSplat + description + Bugsplat crash reporting package + license + Proprietary + license_file + LICENSES/BUGSPLAT_LICENSE.txt + name + bugsplat + platforms + + darwin64 + + archive + + hash + 7a7bd828233e8a2b0e9c022f6219e6e7 + url + http://s3-proxy.lindenlab.com/private-builds-secondlife-com/ct2/23730/182106/bugsplat-1.0.6.519145-darwin64-519145.tar.bz2 + + name + darwin64 + + windows + + archive + + hash + a3938332a11215e6909d67d1b9be5259 + url + http://s3-proxy.lindenlab.com/private-builds-secondlife-com/ct2/23732/182120/bugsplat-3.6.0.4.519145-windows-519145.tar.bz2 + + name + windows + + windows64 + + archive + + hash + 453d624d87a80779f59cfb1880613d90 + url + http://s3-proxy.lindenlab.com/private-builds-secondlife-com/ct2/23731/182115/bugsplat-3.6.0.4.519145-windows64-519145.tar.bz2 + + name + windows64 + + + version + 1.0.6.519145 + chardet copyright diff --git a/indra/llcommon/llerror.cpp b/indra/llcommon/llerror.cpp index 06c7aef8ab..6dfb4bf028 100644 --- a/indra/llcommon/llerror.cpp +++ b/indra/llcommon/llerror.cpp @@ -368,6 +368,7 @@ namespace public: std::ostringstream messageStream; bool messageStreamInUse; + std::string mFatalMessage; void addCallSite(LLError::CallSite&); void invalidateCallSites(); @@ -666,11 +667,16 @@ namespace LLError s->mCrashFunction = f; } - FatalFunction getFatalFunction() - { + FatalFunction getFatalFunction() + { SettingsConfigPtr s = Settings::getInstance()->getSettingsConfig(); - return s->mCrashFunction; - } + return s->mCrashFunction; + } + + std::string getFatalMessage() + { + return Globals::getInstance()->mFatalMessage; + } void setTimeFunction(TimeFunction f) { @@ -1256,12 +1262,17 @@ namespace LLError } addEscapedMessage(message_stream, message); + std::string message_line(message_stream.str()); - writeToRecorders(site, message_stream.str()); - - if (site.mLevel == LEVEL_ERROR && s->mCrashFunction) + writeToRecorders(site, message_line); + + if (site.mLevel == LEVEL_ERROR) { - s->mCrashFunction(message_stream.str()); + g->mFatalMessage = message_line; + if (s->mCrashFunction) + { + s->mCrashFunction(message_line); + } } } } -- cgit v1.3 From ec6487f3a70a5067f6d8fc601437160bb4fa753f Mon Sep 17 00:00:00 2001 From: Nat Goodspeed Date: Thu, 27 Sep 2018 14:57:03 -0400 Subject: DRTVWR-474: Make LLEventMailDrop pass all saved events to listener. Previously, LLEventMailDrop would send only the first queued event to a newly-connected listener. If you wanted to flush all queued events, you'd have to "pump" the queue by repeatedly disconnecting and reconnecting -- with no good way to know when you'd caught up. The new behavior makes LLEventMailDrop resemble a multi-valued future: a rendezvous between producer and consumer that, once connected, pushes values rather than requiring them to be pulled (as with a simple queue) -- regardless of the relative order in which post() and listen() are called. --- indra/llcommon/llevents.cpp | 23 +++++++++++++++-------- indra/llcommon/llevents.h | 20 +++++++++++++------- 2 files changed, 28 insertions(+), 15 deletions(-) (limited to 'indra/llcommon') diff --git a/indra/llcommon/llevents.cpp b/indra/llcommon/llevents.cpp index dce97b5411..eedd8c92b5 100644 --- a/indra/llcommon/llevents.cpp +++ b/indra/llcommon/llevents.cpp @@ -545,10 +545,8 @@ bool LLEventStream::post(const LLSD& event) *****************************************************************************/ bool LLEventMailDrop::post(const LLSD& event) { - bool posted = false; - - if (!mSignal->empty()) - posted = LLEventStream::post(event); + // forward the call to our base class + bool posted = LLEventStream::post(event); if (!posted) { // if the event was not handled we will save it for later so that it can @@ -564,16 +562,25 @@ LLBoundListener LLEventMailDrop::listen_impl(const std::string& name, const NameList& after, const NameList& before) { - if (!mEventHistory.empty()) + // Before actually connecting this listener for subsequent post() calls, + // first feed each of the saved events, in order, to the new listener. + // Remove any that this listener consumes -- Effective STL, Item 9. + for (auto hi(mEventHistory.begin()), hend(mEventHistory.end()); hi != hend; ) { - if (listener(mEventHistory.front())) + if (listener(*hi)) { - mEventHistory.pop_front(); + // new listener consumed this event, erase it + hi = mEventHistory.erase(hi); + } + else + { + // listener did not consume this event, just move along + ++hi; } } + // let base class perform the actual connection return LLEventStream::listen_impl(name, listener, after, before); - } diff --git a/indra/llcommon/llevents.h b/indra/llcommon/llevents.h index 1d51c660ed..5d60c63810 100644 --- a/indra/llcommon/llevents.h +++ b/indra/llcommon/llevents.h @@ -650,15 +650,21 @@ public: * LLEventMailDrop *****************************************************************************/ /** - * LLEventMailDrop is a specialization of LLEventStream. Events are posted normally, - * however if no listeners return that they have handled the event it is placed in - * a queue. Subsequent attaching listeners will receive stored events from the queue - * until a listener indicates that the event has been handled. In order to receive - * multiple events from a mail drop the listener must disconnect and reconnect. + * LLEventMailDrop is a specialization of LLEventStream. Events are posted + * normally, however if no listener returns that it has handled the event + * (returns true), it is placed in a queue. Subsequent attaching listeners + * will receive stored events from the queue until some listener indicates + * that the event has been handled. + * + * LLEventMailDrop completely decouples the timing of post() calls from + * listen() calls: every event posted to an LLEventMailDrop is eventually seen + * by all listeners, until some listener consumes it. The caveat is that each + * event *must* eventually reach a listener that will consume it, else the + * queue will grow to arbitrary length. * * @NOTE: When using an LLEventMailDrop (or LLEventQueue) with a LLEventTimeout or - * LLEventFilter attaching the filter downstream using Timeout's constructor will - * cause the MailDrop to discharge any of it's stored events. The timeout should + * LLEventFilter attaching the filter downstream, using Timeout's constructor will + * cause the MailDrop to discharge any of its stored events. The timeout should * instead be connected upstream using its listen() method. * See llcoro::suspendUntilEventOnWithTimeout() for an example. */ -- cgit v1.3 From b1955d4247a4d28a3a4c259036390ff632e80008 Mon Sep 17 00:00:00 2001 From: Nat Goodspeed Date: Wed, 3 Oct 2018 14:00:05 -0400 Subject: DRTVWR-474: Do NOT autokill updater process on viewer termination. The updater is required to survive beyond termination of the viewer that launched it so it can launch the next installer, or a replacement viewer. Having the old viewer forcibly terminate it on shutdown would be counter- productive. Introduce a third LLLeap::create() overload taking LLProcess::Params, which gives access to autokill, cwd and other options previously unsupported by LLLeap. Reimplement the existing create() overloads in terms of this new one, since LLLeapImpl::LLLeapImpl() is already based on LLProcess::Params anyway. Use LLProcess::Params in LLAppViewer::init() to specify the updater process, setting autokill=false. Refactoring LLLeapImpl() apparently involved engaging an LLInitParam::Block feature never before used: had to drag operator() into Multiple from its base class TypedParam (as has been done in other TypedParam subclasses). --- indra/llcommon/llinitparam.h | 3 +++ indra/llcommon/llleap.cpp | 51 +++++++++++++++++++++++++++---------------- indra/llcommon/llleap.h | 14 ++++++++++++ indra/newview/llappviewer.cpp | 33 ++++++++++++++-------------- 4 files changed, 65 insertions(+), 36 deletions(-) (limited to 'indra/llcommon') diff --git a/indra/llcommon/llinitparam.h b/indra/llcommon/llinitparam.h index f1f4226c40..7f5b9b4ac2 100644 --- a/indra/llcommon/llinitparam.h +++ b/indra/llcommon/llinitparam.h @@ -2115,6 +2115,9 @@ namespace LLInitParam typedef typename super_t::iterator iterator; typedef typename super_t::const_iterator const_iterator; + using super_t::operator(); + using super_t::operator const container_t&; + explicit Multiple(const char* name = "") : super_t(DERIVED_BLOCK::getBlockDescriptor(), name, container_t(), &validate, RANGE::minCount, RANGE::maxCount) {} diff --git a/indra/llcommon/llleap.cpp b/indra/llcommon/llleap.cpp index c87d2a3e58..cf8f8cc6a5 100644 --- a/indra/llcommon/llleap.cpp +++ b/indra/llcommon/llleap.cpp @@ -47,9 +47,9 @@ class LLLeapImpl: public LLLeap LOG_CLASS(LLLeap); public: // Called only by LLLeap::create() - LLLeapImpl(const std::string& desc, const std::vector& plugin): + LLLeapImpl(const LLProcess::Params& cparams): // We might reassign mDesc in the constructor body if it's empty here. - mDesc(desc), + mDesc(cparams.desc), // We expect multiple LLLeapImpl instances. Definitely tweak // mDonePump's name for uniqueness. mDonePump("LLLeap", true), @@ -67,17 +67,17 @@ public: // this class or method name. mListener(new LLLeapListener(boost::bind(&LLLeapImpl::connect, this, _1, _2))) { - // Rule out empty vector - if (plugin.empty()) + // Rule out unpopulated Params block + if (! cparams.executable.isProvided()) { LLTHROW(Error("no plugin command")); } // Don't leave desc empty either, but in this case, if we weren't // given one, we'll fake one. - if (desc.empty()) + if (mDesc.empty()) { - mDesc = LLProcess::basename(plugin[0]); + mDesc = LLProcess::basename(cparams.executable); // how about a toLower() variant that returns the transformed string?! std::string desclower(mDesc); LLStringUtil::toLower(desclower); @@ -87,9 +87,9 @@ public: // notice Python specially: we provide Python LLSD serialization // support, so there's a pretty good reason to implement plugins // in that language. - if (plugin.size() >= 2 && (desclower == "python" || desclower == "python.exe")) + if (cparams.args.size() && (desclower == "python" || desclower == "python.exe")) { - mDesc = LLProcess::basename(plugin[1]); + mDesc = LLProcess::basename(cparams.args()[0]); } } @@ -97,14 +97,10 @@ public: mDonePump.listen("LLLeap", boost::bind(&LLLeapImpl::bad_launch, this, _1)); // Okay, launch child. - LLProcess::Params params; + // Get a modifiable copy of params block to set files and postend. + LLProcess::Params params(cparams); + // copy our deduced mDesc back into the params block params.desc = mDesc; - std::vector::const_iterator pi(plugin.begin()), pend(plugin.end()); - params.executable = *pi++; - for ( ; pi != pend; ++pi) - { - params.args.add(*pi); - } params.files.add(LLProcess::FileParam("pipe")); // stdin params.files.add(LLProcess::FileParam("pipe")); // stdout params.files.add(LLProcess::FileParam("pipe")); // stderr @@ -429,17 +425,17 @@ private: boost::scoped_ptr mListener; }; -// This must follow the declaration of LLLeapImpl, so it may as well be last. -LLLeap* LLLeap::create(const std::string& desc, const std::vector& plugin, bool exc) +// These must follow the declaration of LLLeapImpl, so they may as well be last. +LLLeap* LLLeap::create(const LLProcess::Params& params, bool exc) { // If caller is willing to permit exceptions, just instantiate. if (exc) - return new LLLeapImpl(desc, plugin); + return new LLLeapImpl(params); // Caller insists on suppressing LLLeap::Error. Very well, catch it. try { - return new LLLeapImpl(desc, plugin); + return new LLLeapImpl(params); } catch (const LLLeap::Error&) { @@ -447,6 +443,23 @@ LLLeap* LLLeap::create(const std::string& desc, const std::vector& } } +LLLeap* LLLeap::create(const std::string& desc, const std::vector& plugin, bool exc) +{ + LLProcess::Params params; + params.desc = desc; + std::vector::const_iterator pi(plugin.begin()), pend(plugin.end()); + // could validate here, but let's rely on LLLeapImpl's constructor + if (pi != pend) + { + params.executable = *pi++; + } + for ( ; pi != pend; ++pi) + { + params.args.add(*pi); + } + return create(params, exc); +} + LLLeap* LLLeap::create(const std::string& desc, const std::string& plugin, bool exc) { // Use LLStringUtil::getTokens() to parse the command line diff --git a/indra/llcommon/llleap.h b/indra/llcommon/llleap.h index 8aac8a64c5..7cecdf2f8f 100644 --- a/indra/llcommon/llleap.h +++ b/indra/llcommon/llleap.h @@ -14,6 +14,7 @@ #include "llinstancetracker.h" #include "llexception.h" +#include "llprocess.h" #include #include @@ -61,6 +62,19 @@ public: static LLLeap* create(const std::string& desc, const std::string& plugin, bool exc=true); + /** + * Pass an LLProcess::Params instance to specify desc, executable, args et al. + * + * Note that files and postend are set implicitly; any values you set in + * those fields will be disregarded. + * + * Pass exc=false to suppress LLLeap::Error exception. Obviously in that + * case the caller cannot discover the nature of the error, merely that an + * error of some kind occurred (because create() returned NULL). Either + * way, the error is logged. + */ + static LLLeap* create(const LLProcess::Params& params, bool exc=true); + /** * Exception thrown for invalid create() arguments, e.g. no plugin * program. This is more resiliant than an LL_ERRS failure, because the diff --git a/indra/newview/llappviewer.cpp b/indra/newview/llappviewer.cpp index 776fc85a2d..bc4ce19f77 100644 --- a/indra/newview/llappviewer.cpp +++ b/indra/newview/llappviewer.cpp @@ -1130,30 +1130,35 @@ bool LLAppViewer::init() gGLActive = FALSE; - std::vector updater + LLProcess::Params updater; + updater.desc = "updater process"; + // Because it's the updater, it MUST persist beyond the lifespan of the + // viewer itself. + updater.autokill = false; #if LL_WINDOWS - { gDirUtilp->getExpandedFilename(LL_PATH_EXECUTABLE, "updater.exe") }; + updater.executable = gDirUtilp->getExpandedFilename(LL_PATH_EXECUTABLE, "updater.exe"); #elif LL_DARWIN // explicitly run the system Python interpreter on updater.py - { "python", gDirUtilp->add(gDirUtilp->getAppRODataDir(), "updater", "updater.py") }; + updater.executable = "python"; + updater.args.add(gDirUtilp->add(gDirUtilp->getAppRODataDir(), "updater", "updater.py")); #else - { gDirUtilp->getExpandedFilename(LL_PATH_EXECUTABLE, "updater") }; + updater.executable = gDirUtilp->getExpandedFilename(LL_PATH_EXECUTABLE, "updater"); #endif // add LEAP mode command-line argument to whichever of these we selected - updater.push_back("leap"); + updater.args.add("leap"); // UpdaterServiceSettings - updater.push_back(stringize(gSavedSettings.getU32("UpdaterServiceSetting"))); + updater.args.add(stringize(gSavedSettings.getU32("UpdaterServiceSetting"))); // channel - updater.push_back(LLVersionInfo::getChannel()); + updater.args.add(LLVersionInfo::getChannel()); // testok - updater.push_back(stringize(gSavedSettings.getBOOL("UpdaterWillingToTest"))); + updater.args.add(stringize(gSavedSettings.getBOOL("UpdaterWillingToTest"))); // UpdaterServiceURL - updater.push_back(gSavedSettings.getString("UpdaterServiceURL")); + updater.args.add(gSavedSettings.getString("UpdaterServiceURL")); // ForceAddressSize - updater.push_back(stringize(gSavedSettings.getU32("ForceAddressSize"))); + updater.args.add(stringize(gSavedSettings.getU32("ForceAddressSize"))); // Run the updater. An exception from launching the updater should bother us. - LLLeap::create("updater process", updater, true); + LLLeap::create(updater, true); // Iterate over --leap command-line options. But this is a bit tricky: if // there's only one, it won't be an array at all. @@ -3923,12 +3928,6 @@ void LLAppViewer::requestQuit() gAgentAvatarp->updateAvatarRezMetrics(true); // force a last packet to be sent. } - // Try to send last batch of avatar rez metrics. - if (!gDisconnected && isAgentAvatarValid()) - { - gAgentAvatarp->updateAvatarRezMetrics(true); // force a last packet to be sent. - } - LLHUDEffectSpiral *effectp = (LLHUDEffectSpiral*)LLHUDManager::getInstance()->createViewerEffect(LLHUDObject::LL_HUD_EFFECT_POINT, TRUE); effectp->setPositionGlobal(gAgent.getPositionGlobal()); effectp->setColor(LLColor4U(gAgent.getEffectColor())); -- cgit v1.3 From 05068186c349294caf4fef3c970f9d75a9f30460 Mon Sep 17 00:00:00 2001 From: Nat Goodspeed Date: Thu, 4 Oct 2018 16:35:38 -0400 Subject: DRTVWR-474: Make login coroutine sync with updater process on failure. Specifically, introduce an LLEventMailDrop("LoginSync"). When the updater detects that an update is required, it will post to that rendezvous point. When login.cgi responds with login failure, make the login coroutine wait (a few seconds) for that ping from the updater. If we receive that ping and if it contains a "reply" key, make the fail.login listener respond to the updater with an indication of whether to proceed with update. If both login.cgi and the updater concur that an update is required, produce a new confirmation message for the user and then (once user responds) tell the updater to proceed. Otherwise, produce the usual login-failure message and tell the updater never mind. Introduce LLCoro::OverrideConsuming to provide temporary save/restore of the set_consuming() / get_consuming() flag. It's a good idea to set the consuming flag when retrieving data from an LLEventMailDrop. --- indra/llcommon/llcoros.h | 20 +++++++ indra/newview/lllogininstance.cpp | 63 ++++++++++++++++++---- indra/newview/lllogininstance.h | 6 ++- .../newview/skins/default/xui/en/notifications.xml | 13 ++++- indra/viewer_components/login/lllogin.cpp | 56 +++++++++++++++++-- 5 files changed, 142 insertions(+), 16 deletions(-) (limited to 'indra/llcommon') diff --git a/indra/llcommon/llcoros.h b/indra/llcommon/llcoros.h index 8fb27af6a4..c551413811 100644 --- a/indra/llcommon/llcoros.h +++ b/indra/llcommon/llcoros.h @@ -169,6 +169,26 @@ public: static void set_consuming(bool consuming); static bool get_consuming(); + /** + * RAII control of the consuming flag + */ + class OverrideConsuming + { + public: + OverrideConsuming(bool consuming): + mPrevConsuming(get_consuming()) + { + set_consuming(consuming); + } + ~OverrideConsuming() + { + set_consuming(mPrevConsuming); + } + + private: + bool mPrevConsuming; + }; + /** * Please do NOT directly use boost::dcoroutines::future! It is essential * to maintain the "current" coroutine at every context switch. This diff --git a/indra/newview/lllogininstance.cpp b/indra/newview/lllogininstance.cpp index bc93fa2c20..126c6be388 100644 --- a/indra/newview/lllogininstance.cpp +++ b/indra/newview/lllogininstance.cpp @@ -253,14 +253,12 @@ bool LLLoginInstance::handleLoginEvent(const LLSD& event) mLoginState = event["state"].asString(); mResponseData = event["data"]; - + if(event.has("transfer_rate")) { mTransferRate = event["transfer_rate"].asReal(); } - - // Call the method registered in constructor, if any, for more specific // handling mDispatcher.try_call(event); @@ -276,6 +274,14 @@ void LLLoginInstance::handleLoginFailure(const LLSD& event) // Login has failed. // Figure out why and respond... LLSD response = event["data"]; + LLSD updater = response["updater"]; + + // Always provide a response to the updater, if in fact the updater + // contacted us, if in fact the ping contains a 'reply' key. Most code + // paths tell it not to proceed with updating. + ResponsePtr resp(std::make_shared + (LLSDMap("update", false), updater)); + std::string reason_response = response["reason"].asString(); std::string message_response = response["message"].asString(); LL_DEBUGS("LLLogin") << "reason " << reason_response @@ -328,17 +334,44 @@ void LLLoginInstance::handleLoginFailure(const LLSD& event) } else if(reason_response == "update") { - // This shouldn't happen - the viewer manager should have forced an update; - // possibly the user ran the viewer directly and bypassed the update check + // This can happen if the user clicked Login quickly, before we heard + // back from the Viewer Version Manager, but login failed because + // login.cgi is insisting on a required update. We were called with an + // event that bundles both the login.cgi 'response' and the + // synchronization event from the 'updater'. std::string required_version = response["message_args"]["VERSION"]; LL_WARNS("LLLogin") << "Login failed because an update to version " << required_version << " is required." << LL_ENDL; if (gViewerWindow) gViewerWindow->setShowProgress(FALSE); - LLSD data(LLSD::emptyMap()); - data["VERSION"] = required_version; - LLNotificationsUtil::add("RequiredUpdate", data, LLSD::emptyMap(), boost::bind(&LLLoginInstance::handleLoginDisallowed, this, _1, _2)); + LLSD args(LLSDMap("VERSION", required_version)); + if (updater.isUndefined()) + { + // If the updater failed to shake hands, better advise the user to + // download the update him/herself. + LLNotificationsUtil::add( + "RequiredUpdate", + args, + updater, + boost::bind(&LLLoginInstance::handleLoginDisallowed, this, _1, _2)); + } + else + { + // If we've heard from the updater that an update is required, + // then display the prompt that assures the user we'll take care + // of it. This is the one case in which we bind 'resp': + // instead of destroying our Response object (and thus sending a + // negative reply to the updater) as soon as we exit this + // function, bind our shared_ptr so it gets passed into + // syncWithUpdater. That ensures that the response is delayed + // until the user has responded to the notification. + LLNotificationsUtil::add( + "PauseForUpdate", + args, + updater, + boost::bind(&LLLoginInstance::syncWithUpdater, this, resp, _1, _2)); + } } else if( reason_response == "key" || reason_response == "presence" @@ -361,6 +394,19 @@ void LLLoginInstance::handleLoginFailure(const LLSD& event) } } +void LLLoginInstance::syncWithUpdater(ResponsePtr resp, const LLSD& notification, const LLSD& response) +{ + LL_INFOS("LLLogin") << "LLLoginInstance::syncWithUpdater" << LL_ENDL; + // 'resp' points to an instance of LLEventAPI::Response that will be + // destroyed as soon as we return and the notification response functor is + // unregistered. Modify it so that it tells the updater to go ahead and + // perform the update. Naturally, if we allowed the user a choice as to + // whether to proceed or not, this assignment would reflect the user's + // selection. + (*resp)["update"] = true; + attemptComplete(); +} + void LLLoginInstance::handleLoginDisallowed(const LLSD& notification, const LLSD& response) { attemptComplete(); @@ -420,7 +466,6 @@ bool LLLoginInstance::handleTOSResponse(bool accepted, const std::string& key) return true; } - std::string construct_start_string() { std::string start; diff --git a/indra/newview/lllogininstance.h b/indra/newview/lllogininstance.h index 651ad10afb..b759b43474 100644 --- a/indra/newview/lllogininstance.h +++ b/indra/newview/lllogininstance.h @@ -28,8 +28,10 @@ #define LL_LLLOGININSTANCE_H #include "lleventdispatcher.h" +#include "lleventapi.h" #include #include +#include // std::shared_ptr #include "llsecapi.h" class LLLogin; class LLEventStream; @@ -68,6 +70,7 @@ public: LLNotificationsInterface& getNotificationsInterface() const { return *mNotifications; } private: + typedef std::shared_ptr ResponsePtr; void constructAuthParams(LLPointer user_credentials); void updateApp(bool mandatory, const std::string& message); bool updateDialogCallback(const LLSD& notification, const LLSD& response); @@ -77,7 +80,8 @@ private: void handleLoginSuccess(const LLSD& event); void handleDisconnect(const LLSD& event); void handleIndeterminate(const LLSD& event); - void handleLoginDisallowed(const LLSD& notification, const LLSD& response); + void handleLoginDisallowed(const LLSD& notification, const LLSD& response); + void syncWithUpdater(ResponsePtr resp, const LLSD& notification, const LLSD& response); bool handleTOSResponse(bool v, const std::string& key); diff --git a/indra/newview/skins/default/xui/en/notifications.xml b/indra/newview/skins/default/xui/en/notifications.xml index 9eaa5330c3..5f9b8adc89 100644 --- a/indra/newview/skins/default/xui/en/notifications.xml +++ b/indra/newview/skins/default/xui/en/notifications.xml @@ -3841,7 +3841,6 @@ Finished download of raw terrain file to: name="RequiredUpdate" type="alertmodal"> Version [VERSION] is required for login. -This should have been updated for you but apparently was not. Please download from https://secondlife.com/support/downloads/ confirm + +Version [VERSION] is required for login. +Click OK to download and install. + confirm + + + Date: Thu, 11 Oct 2018 14:17:52 -0400 Subject: Modify logging so that the in-viewer console and stderr do not escape line breaks Improve the implementation so that escaping is computed only once --- indra/llcommon/llerror.cpp | 149 ++++++++++++++++++++---------- indra/llcommon/llerrorcontrol.h | 19 +++- indra/llcommon/tests/llerror_test.cpp | 68 +++++++------- indra/newview/app_settings/logcontrol.xml | 1 - indra/newview/app_settings/settings.xml | 11 --- indra/newview/llappviewer.cpp | 7 +- indra/newview/llviewerwindow.cpp | 3 + indra/test/test.cpp | 1 - 8 files changed, 152 insertions(+), 107 deletions(-) (limited to 'indra/llcommon') diff --git a/indra/llcommon/llerror.cpp b/indra/llcommon/llerror.cpp index 6dfb4bf028..668ea1f7d2 100644 --- a/indra/llcommon/llerror.cpp +++ b/indra/llcommon/llerror.cpp @@ -119,8 +119,6 @@ namespace { { LL_INFOS() << "Error setting log file to " << filename << LL_ENDL; } - mWantsTime = true; - mWantsTags = true; } ~RecordToFile() @@ -146,7 +144,7 @@ namespace { public: RecordToStderr(bool timestamp) : mUseANSI(ANSI_PROBE) { - mWantsTime = timestamp; + this->showMultiline(true); } virtual void recordMessage(LLError::ELevel level, @@ -207,7 +205,13 @@ namespace { class RecordToFixedBuffer : public LLError::Recorder { public: - RecordToFixedBuffer(LLLineBuffer* buffer) : mBuffer(buffer) { } + RecordToFixedBuffer(LLLineBuffer* buffer) + : mBuffer(buffer) + { + this->showMultiline(true); + this->showTags(false); + this->showLocation(false); + } virtual void recordMessage(LLError::ELevel level, const std::string& message) @@ -224,7 +228,11 @@ namespace { { public: RecordToWinDebug() - {} + { + this->showMultiline(true); + this->showTags(false); + this->showLocation(false); + } virtual void recordMessage(LLError::ELevel level, const std::string& message) @@ -411,8 +419,6 @@ namespace LLError public: virtual ~SettingsConfig(); - bool mPrintLocation; - LLError::ELevel mDefaultLevel; LevelMap mFunctionLevelMap; @@ -453,7 +459,6 @@ namespace LLError SettingsConfig::SettingsConfig() : LLRefCount(), - mPrintLocation(false), mDefaultLevel(LLError::LEVEL_DEBUG), mFunctionLevelMap(), mClassLevelMap(), @@ -655,12 +660,6 @@ namespace LLError commonInit(user_dir, app_dir, log_to_stderr); } - void setPrintLocation(bool print) - { - SettingsConfigPtr s = Settings::getInstance()->getSettingsConfig(); - s->mPrintLocation = print; - } - void setFatalFunction(const FatalFunction& f) { SettingsConfigPtr s = Settings::getInstance()->getSettingsConfig(); @@ -775,7 +774,6 @@ namespace LLError s->mTagLevelMap.clear(); s->mUniqueLogMessages.clear(); - setPrintLocation(config["print-location"]); setDefaultLevel(decodeLevel(config["default-level"])); LLSD sets = config["settings"]; @@ -798,11 +796,12 @@ namespace LLError namespace LLError { Recorder::Recorder() - : mWantsTime(false), - mWantsTags(false), - mWantsLevel(true), - mWantsLocation(false), - mWantsFunctionName(true) + : mWantsTime(true) + , mWantsTags(true) + , mWantsLevel(true) + , mWantsLocation(true) + , mWantsFunctionName(true) + , mWantsMultiline(false) { } @@ -839,6 +838,42 @@ namespace LLError return mWantsFunctionName; } + // virtual + bool Recorder::wantsMultiline() + { + return mWantsMultiline; + } + + void Recorder::showTime(bool show) + { + mWantsTime = show; + } + + void Recorder::showTags(bool show) + { + mWantsTags = show; + } + + void Recorder::showLevel(bool show) + { + mWantsLevel = show; + } + + void Recorder::showLocation(bool show) + { + mWantsLocation = show; + } + + void Recorder::showFunctionName(bool show) + { + mWantsFunctionName = show; + } + + void Recorder::showMultiline(bool show) + { + mWantsMultiline = show; + } + void addRecorder(RecorderPtr recorder) { if (!recorder) @@ -871,17 +906,15 @@ namespace LLError s->mFileRecorder.reset(); s->mFileRecorderFileName.clear(); - if (file_name.empty()) - { - return; - } - - RecorderPtr recordToFile(new RecordToFile(file_name)); - if (boost::dynamic_pointer_cast(recordToFile)->okay()) + if (!file_name.empty()) { - s->mFileRecorderFileName = file_name; - s->mFileRecorder = recordToFile; - addRecorder(recordToFile); + RecorderPtr recordToFile(new RecordToFile(file_name)); + if (boost::dynamic_pointer_cast(recordToFile)->okay()) + { + s->mFileRecorderFileName = file_name; + s->mFileRecorder = recordToFile; + addRecorder(recordToFile); + } } } @@ -892,14 +925,12 @@ namespace LLError removeRecorder(s->mFixedBufferRecorder); s->mFixedBufferRecorder.reset(); - if (!fixedBuffer) + if (fixedBuffer) { - return; - } - - RecorderPtr recordToFixedBuffer(new RecordToFixedBuffer(fixedBuffer)); - s->mFixedBufferRecorder = recordToFixedBuffer; - addRecorder(recordToFixedBuffer); + RecorderPtr recordToFixedBuffer(new RecordToFixedBuffer(fixedBuffer)); + s->mFixedBufferRecorder = recordToFixedBuffer; + addRecorder(recordToFixedBuffer); + } } std::string logFileName() @@ -911,8 +942,9 @@ namespace LLError namespace { - void addEscapedMessage(std::ostream& out, const std::string& message) + std::string escapedMessageLines(const std::string& message) { + std::ostringstream out; size_t written_out = 0; size_t all_content = message.length(); size_t escape_char_index; // always relative to start of message @@ -948,13 +980,16 @@ namespace // write whatever was left out << message.substr(written_out, std::string::npos); } + return out.str(); } - void writeToRecorders(const LLError::CallSite& site, const std::string& escaped_message, bool show_location = true, bool show_time = true, bool show_tags = true, bool show_level = true, bool show_function = true) + void writeToRecorders(const LLError::CallSite& site, const std::string& message) { LLError::ELevel level = site.mLevel; LLError::SettingsConfigPtr s = LLError::Settings::getInstance()->getSettingsConfig(); - + + std::string escaped_message; + for (Recorders::const_iterator i = s->mRecorders.begin(); i != s->mRecorders.end(); ++i) @@ -969,7 +1004,7 @@ namespace } message_stream << " "; - if (show_level && r->wantsLevel()) + if (r->wantsLevel()) { message_stream << site.mLevelString; } @@ -981,19 +1016,30 @@ namespace } message_stream << " "; - if (r->wantsLocation() || level == LLError::LEVEL_ERROR || s->mPrintLocation) + if (r->wantsLocation() || level == LLError::LEVEL_ERROR) { message_stream << site.mLocationString; } message_stream << " "; - if (show_function && r->wantsFunctionName()) + if (r->wantsFunctionName()) { message_stream << site.mFunctionString; } message_stream << " : "; - message_stream << escaped_message; + if (r->wantsMultiline()) + { + message_stream << message; + } + else + { + if (escaped_message.empty()) + { + escaped_message = escapedMessageLines(message); + } + message_stream << escaped_message; + } r->recordMessage(level, message_stream.str()); } @@ -1236,10 +1282,11 @@ namespace LLError delete out; } - std::ostringstream message_stream; if (site.mPrintOnce) { + std::ostringstream message_stream; + std::map::iterator messageIter = s->mUniqueLogMessages.find(message); if (messageIter != s->mUniqueLogMessages.end()) { @@ -1259,19 +1306,18 @@ namespace LLError message_stream << "ONCE: "; s->mUniqueLogMessages[message] = 1; } + message_stream << message; + message = message_stream.str(); } - addEscapedMessage(message_stream, message); - std::string message_line(message_stream.str()); - - writeToRecorders(site, message_line); + writeToRecorders(site, message); if (site.mLevel == LEVEL_ERROR) { - g->mFatalMessage = message_line; + g->mFatalMessage = message; if (s->mCrashFunction) { - s->mCrashFunction(message_line); + s->mCrashFunction(message); } } } @@ -1579,3 +1625,4 @@ bool debugLoggingEnabled(const std::string& tag) } + diff --git a/indra/llcommon/llerrorcontrol.h b/indra/llcommon/llerrorcontrol.h index ddbcdc94a0..a6278b3e50 100644 --- a/indra/llcommon/llerrorcontrol.h +++ b/indra/llcommon/llerrorcontrol.h @@ -148,13 +148,22 @@ namespace LLError bool wantsLevel(); bool wantsLocation(); bool wantsFunctionName(); + bool wantsMultiline(); + + void showTime(bool show); + void showTags(bool show); + void showLevel(bool show); + void showLocation(bool show); + void showFunctionName(bool show); + void showMultiline(bool show); protected: - bool mWantsTime, - mWantsTags, - mWantsLevel, - mWantsLocation, - mWantsFunctionName; + bool mWantsTime; + bool mWantsTags; + bool mWantsLevel; + bool mWantsLocation; + bool mWantsFunctionName; + bool mWantsMultiline; }; typedef boost::shared_ptr RecorderPtr; diff --git a/indra/llcommon/tests/llerror_test.cpp b/indra/llcommon/tests/llerror_test.cpp index ce0dbce075..bd0357e4bf 100644 --- a/indra/llcommon/tests/llerror_test.cpp +++ b/indra/llcommon/tests/llerror_test.cpp @@ -78,8 +78,12 @@ namespace tut class TestRecorder : public LLError::Recorder { public: - TestRecorder() { mWantsTime = false; mWantsTags = true; } - virtual ~TestRecorder() { } + TestRecorder() + { + showTime(false); + } + virtual ~TestRecorder() + {} virtual void recordMessage(LLError::ELevel level, const std::string& message) @@ -90,8 +94,6 @@ namespace tut int countMessages() { return (int) mMessages.size(); } void clearMessages() { mMessages.clear(); } - void setWantsTime(bool t) { mWantsTime = t; } - std::string message(int n) { std::ostringstream test_name; @@ -139,9 +141,14 @@ namespace tut } void setWantsTime(bool t) - { - boost::dynamic_pointer_cast(mRecorder)->setWantsTime(t); - } + { + boost::dynamic_pointer_cast(mRecorder)->showTime(t); + } + + void setWantsMultiline(bool t) + { + boost::dynamic_pointer_cast(mRecorder)->showMultiline(t); + } std::string message(int n) { @@ -378,27 +385,6 @@ namespace } } -namespace tut -{ - template<> template<> - void ErrorTestObject::test<5>() - // file and line information in log messages - { - std::string location = writeReturningLocation(); - // expecting default to not print location information - - LLError::setPrintLocation(true); - writeReturningLocation(); - - LLError::setPrintLocation(false); - writeReturningLocation(); - - ensure_message_does_not_contain(0, location); - ensure_message_field_equals(1, LOCATION_FIELD, location); - ensure_message_does_not_contain(2, location); - } -} - /* The following helper functions and class members all log a simple message from some particular function scope. Each function takes a bool argument that indicates if it should log its own name or not (in the manner that @@ -583,7 +569,6 @@ namespace tut // special handling of LL_ERRS() calls void ErrorTestObject::test<8>() { - LLError::setPrintLocation(false); std::string location = errorReturningLocation(); ensure_message_field_equals(0, LOCATION_FIELD, location); @@ -630,15 +615,15 @@ namespace tut // output order void ErrorTestObject::test<10>() { - LLError::setPrintLocation(true); LLError::setTimeFunction(roswell); setWantsTime(true); + std::string location, function; writeReturningLocationAndFunction(location, function); ensure_equals("order is time level tags location function message", - message(0), + message(0), roswell() + " INFO " + "# " /* no tag */ + location + " " + function + " : " + "apple"); } @@ -658,7 +643,7 @@ namespace tut LLError::setTimeFunction(roswell); LLError::RecorderPtr anotherRecorder(new TestRecorder()); - boost::dynamic_pointer_cast(anotherRecorder)->setWantsTime(true); + boost::dynamic_pointer_cast(anotherRecorder)->showTime(true); LLError::addRecorder(anotherRecorder); LL_INFOS() << "baz" << LL_ENDL; @@ -896,6 +881,25 @@ namespace tut } } +namespace tut +{ + template<> template<> + void ErrorTestObject::test<19>() + // backslash, return, and newline are not escaped with backslashes + { + LLError::setDefaultLevel(LLError::LEVEL_DEBUG); + setWantsMultiline(true); + writeMsgNeedsEscaping(); // but should not be now + ensure_message_field_equals(0, MSG_FIELD, "backslash\\"); + ensure_message_field_equals(1, MSG_FIELD, "newline\nafternewline"); + ensure_message_field_equals(2, MSG_FIELD, "return\rafterreturn"); + ensure_message_field_equals(3, MSG_FIELD, "backslash\\backslash\\"); + ensure_message_field_equals(4, MSG_FIELD, "backslash\\newline\nanothernewline\nafternewline"); + ensure_message_field_equals(5, MSG_FIELD, "backslash\\returnnewline\r\n\\afterbackslash"); + ensure_message_count(6); + } +} + /* Tests left: handling of classes without LOG_CLASS diff --git a/indra/newview/app_settings/logcontrol.xml b/indra/newview/app_settings/logcontrol.xml index 71445ea541..8ced81fdb3 100644 --- a/indra/newview/app_settings/logcontrol.xml +++ b/indra/newview/app_settings/logcontrol.xml @@ -2,7 +2,6 @@ default-level INFO - print-location true settings diff --git a/indra/newview/app_settings/settings.xml b/indra/newview/app_settings/settings.xml index 8e8cce5787..44aa22b387 100644 --- a/indra/newview/app_settings/settings.xml +++ b/indra/newview/app_settings/settings.xml @@ -13980,17 +13980,6 @@ Value 1 - VerboseLogs - - Comment - Display source file and line number for each log item for debugging purposes - Persist - 1 - Type - Boolean - Value - 0 - VertexShaderEnable Comment diff --git a/indra/newview/llappviewer.cpp b/indra/newview/llappviewer.cpp index dd82aa735f..b3f09a73a2 100644 --- a/indra/newview/llappviewer.cpp +++ b/indra/newview/llappviewer.cpp @@ -885,11 +885,6 @@ bool LLAppViewer::init() mNumSessions++; gSavedSettings.setS32("NumSessions", mNumSessions); - if (gSavedSettings.getBOOL("VerboseLogs")) - { - LLError::setPrintLocation(true); - } - // LLKeyboard relies on LLUI to know what some accelerator keys are called. LLKeyboard::setStringTranslatorFunc( LLTrans::getKeyboardString ); @@ -1702,7 +1697,7 @@ bool LLAppViewer::cleanup() release_start_screen(); // just in case - LLError::logToFixedBuffer(NULL); + LLError::logToFixedBuffer(NULL); // stop the fixed buffer recorder LL_INFOS() << "Cleaning Up" << LL_ENDL; diff --git a/indra/newview/llviewerwindow.cpp b/indra/newview/llviewerwindow.cpp index 01ec703fe6..873d011acc 100644 --- a/indra/newview/llviewerwindow.cpp +++ b/indra/newview/llviewerwindow.cpp @@ -306,6 +306,9 @@ private: RecordToChatConsole::RecordToChatConsole(): mRecorder(new RecordToChatConsoleRecorder()) { + mRecorder->showTags(false); + mRecorder->showLocation(false); + mRecorder->showMultiline(true); } //////////////////////////////////////////////////////////////////////////// diff --git a/indra/test/test.cpp b/indra/test/test.cpp index 80c84d9bea..9d6e9539cb 100644 --- a/indra/test/test.cpp +++ b/indra/test/test.cpp @@ -535,7 +535,6 @@ int main(int argc, char **argv) LLError::setDefaultLevel(LLError::LEVEL_DEBUG); } LLError::setFatalFunction(wouldHaveCrashed); - LLError::setPrintLocation(true); std::string test_app_name(argv[0]); std::string test_log = test_app_name + ".log"; LLFile::remove(test_log); -- cgit v1.3 From 00a839d66590de1204af5fa295f66abcff87e477 Mon Sep 17 00:00:00 2001 From: Oz Linden Date: Tue, 16 Oct 2018 16:18:31 -0400 Subject: renumber the new test to replace the one that was removed --- indra/llcommon/tests/llerror_test.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'indra/llcommon') diff --git a/indra/llcommon/tests/llerror_test.cpp b/indra/llcommon/tests/llerror_test.cpp index bd0357e4bf..e7084fffc6 100644 --- a/indra/llcommon/tests/llerror_test.cpp +++ b/indra/llcommon/tests/llerror_test.cpp @@ -884,7 +884,7 @@ namespace tut namespace tut { template<> template<> - void ErrorTestObject::test<19>() + void ErrorTestObject::test<5>() // backslash, return, and newline are not escaped with backslashes { LLError::setDefaultLevel(LLError::LEVEL_DEBUG); -- cgit v1.3 From cd9d051b9024e4e0fc16a4aca28601d2a88a4045 Mon Sep 17 00:00:00 2001 From: Nat Goodspeed Date: Wed, 17 Oct 2018 16:42:59 -0400 Subject: DRTVWR-447: Move test<5> and writeMsgNeedsEscaping() into sequence. --- indra/llcommon/tests/llerror_test.cpp | 66 +++++++++++++++++------------------ 1 file changed, 33 insertions(+), 33 deletions(-) (limited to 'indra/llcommon') diff --git a/indra/llcommon/tests/llerror_test.cpp b/indra/llcommon/tests/llerror_test.cpp index e7084fffc6..8e1f4c14ac 100644 --- a/indra/llcommon/tests/llerror_test.cpp +++ b/indra/llcommon/tests/llerror_test.cpp @@ -498,6 +498,39 @@ namespace } } +namespace +{ + void writeMsgNeedsEscaping() + { + LL_DEBUGS("WriteTag") << "backslash\\" << LL_ENDL; + LL_INFOS("WriteTag") << "newline\nafternewline" << LL_ENDL; + LL_WARNS("WriteTag") << "return\rafterreturn" << LL_ENDL; + + LL_DEBUGS("WriteTag") << "backslash\\backslash\\" << LL_ENDL; + LL_INFOS("WriteTag") << "backslash\\newline\nanothernewline\nafternewline" << LL_ENDL; + LL_WARNS("WriteTag") << "backslash\\returnnewline\r\n\\afterbackslash" << LL_ENDL; + } +}; + +namespace tut +{ + template<> template<> + void ErrorTestObject::test<5>() + // backslash, return, and newline are not escaped with backslashes + { + LLError::setDefaultLevel(LLError::LEVEL_DEBUG); + setWantsMultiline(true); + writeMsgNeedsEscaping(); // but should not be now + ensure_message_field_equals(0, MSG_FIELD, "backslash\\"); + ensure_message_field_equals(1, MSG_FIELD, "newline\nafternewline"); + ensure_message_field_equals(2, MSG_FIELD, "return\rafterreturn"); + ensure_message_field_equals(3, MSG_FIELD, "backslash\\backslash\\"); + ensure_message_field_equals(4, MSG_FIELD, "backslash\\newline\nanothernewline\nafternewline"); + ensure_message_field_equals(5, MSG_FIELD, "backslash\\returnnewline\r\n\\afterbackslash"); + ensure_message_count(6); + } +} + namespace tut { template<> template<> @@ -820,20 +853,6 @@ namespace tut } } -namespace -{ - void writeMsgNeedsEscaping() - { - LL_DEBUGS("WriteTag") << "backslash\\" << LL_ENDL; - LL_INFOS("WriteTag") << "newline\nafternewline" << LL_ENDL; - LL_WARNS("WriteTag") << "return\rafterreturn" << LL_ENDL; - - LL_DEBUGS("WriteTag") << "backslash\\backslash\\" << LL_ENDL; - LL_INFOS("WriteTag") << "backslash\\newline\nanothernewline\nafternewline" << LL_ENDL; - LL_WARNS("WriteTag") << "backslash\\returnnewline\r\n\\afterbackslash" << LL_ENDL; - } -}; - namespace tut { template<> template<> @@ -881,25 +900,6 @@ namespace tut } } -namespace tut -{ - template<> template<> - void ErrorTestObject::test<5>() - // backslash, return, and newline are not escaped with backslashes - { - LLError::setDefaultLevel(LLError::LEVEL_DEBUG); - setWantsMultiline(true); - writeMsgNeedsEscaping(); // but should not be now - ensure_message_field_equals(0, MSG_FIELD, "backslash\\"); - ensure_message_field_equals(1, MSG_FIELD, "newline\nafternewline"); - ensure_message_field_equals(2, MSG_FIELD, "return\rafterreturn"); - ensure_message_field_equals(3, MSG_FIELD, "backslash\\backslash\\"); - ensure_message_field_equals(4, MSG_FIELD, "backslash\\newline\nanothernewline\nafternewline"); - ensure_message_field_equals(5, MSG_FIELD, "backslash\\returnnewline\r\n\\afterbackslash"); - ensure_message_count(6); - } -} - /* Tests left: handling of classes without LOG_CLASS -- cgit v1.3 From 4e894eb2a7ed6651c54890cd20106bfacd61ef0a Mon Sep 17 00:00:00 2001 From: Nat Goodspeed Date: Tue, 11 Dec 2018 20:48:20 -0500 Subject: SL-10153: Improve ll_convert_string_to_wide() and its converse. Instead of returning a wchar_t* and requiring the caller to delete it later, return a std::basic_string that's self-cleaning. If the caller wants a wchar_t*, s/he can call c_str() on the returned string. Default the code_page parameter to CP_UTF8, since we try to be really consistent about using UTF-8 encoding for all our internal std::strings. --- indra/llcommon/llstring.cpp | 32 ++++++++++++++++++++++---------- indra/llcommon/llstring.h | 10 ++++++---- 2 files changed, 28 insertions(+), 14 deletions(-) (limited to 'indra/llcommon') diff --git a/indra/llcommon/llstring.cpp b/indra/llcommon/llstring.cpp index 9a02fecd72..42390c8a7b 100644 --- a/indra/llcommon/llstring.cpp +++ b/indra/llcommon/llstring.cpp @@ -30,6 +30,7 @@ #include "llerror.h" #include "llfasttimer.h" #include "llsd.h" +#include #if LL_WINDOWS #include "llwin32headerslean.h" @@ -672,6 +673,11 @@ namespace snprintf_hack } } +std::string ll_convert_wide_to_string(const wchar_t* in) +{ + return ll_convert_wide_to_string(in, CP_UTF8); +} + std::string ll_convert_wide_to_string(const wchar_t* in, unsigned int code_page) { std::string out; @@ -709,7 +715,12 @@ std::string ll_convert_wide_to_string(const wchar_t* in, unsigned int code_page) return out; } -wchar_t* ll_convert_string_to_wide(const std::string& in, unsigned int code_page) +std::basic_string ll_convert_string_to_wide(const std::string& in) +{ + return ll_convert_string_to_wide(in, CP_UTF8); +} + +std::basic_string ll_convert_string_to_wide(const std::string& in, unsigned int code_page) { // From review: // We can preallocate a wide char buffer that is the same length (in wchar_t elements) as the utf8 input, @@ -719,24 +730,25 @@ wchar_t* ll_convert_string_to_wide(const std::string& in, unsigned int code_page // but we *are* seeing string operations taking a bunch of time, especially when constructing widgets. // int output_str_len = MultiByteToWideChar(code_page, 0, in.c_str(), in.length(), NULL, 0); - // reserve place to NULL terminator - int output_str_len = in.length(); - wchar_t* w_out = new wchar_t[output_str_len + 1]; + // reserve an output buffer that will be destroyed on exit, with a place + // to put NULL terminator + std::vector w_out(in.length() + 1); - memset(w_out, 0, output_str_len + 1); - int real_output_str_len = MultiByteToWideChar (code_page, 0, in.c_str(), in.length(), w_out, output_str_len); + memset(&w_out[0], 0, w_out.size()); + int real_output_str_len = MultiByteToWideChar(code_page, 0, in.c_str(), in.length(), + &w_out[0], w_out.size() - 1); //looks like MultiByteToWideChar didn't add null terminator to converted string, see EXT-4858. w_out[real_output_str_len] = 0; - return w_out; + // construct string from our temporary output buffer + return {&w_out[0]}; } std::string ll_convert_string_to_utf8_string(const std::string& in) { - wchar_t* w_mesg = ll_convert_string_to_wide(in, CP_ACP); - std::string out_utf8(ll_convert_wide_to_string(w_mesg, CP_UTF8)); - delete[] w_mesg; + auto w_mesg = ll_convert_string_to_wide(in, CP_ACP); + std::string out_utf8(ll_convert_wide_to_string(w_mesg.c_str(), CP_UTF8)); return out_utf8; } diff --git a/indra/llcommon/llstring.h b/indra/llcommon/llstring.h index 68ee9db46b..7c3e9f952d 100644 --- a/indra/llcommon/llstring.h +++ b/indra/llcommon/llstring.h @@ -635,16 +635,18 @@ using snprintf_hack::snprintf; * This replaces the unsafe W2A macro from ATL. */ LL_COMMON_API std::string ll_convert_wide_to_string(const wchar_t* in, unsigned int code_page); +LL_COMMON_API std::string ll_convert_wide_to_string(const wchar_t* in); // default CP_UTF8 /** * Converts a string to wide string. - * - * It will allocate memory for result string with "new []". Don't forget to release it with "delete []". */ -LL_COMMON_API wchar_t* ll_convert_string_to_wide(const std::string& in, unsigned int code_page); +LL_COMMON_API std::basic_string ll_convert_string_to_wide(const std::string& in, + unsigned int code_page); +LL_COMMON_API std::basic_string ll_convert_string_to_wide(const std::string& in); + // default CP_UTF8 /** - * Converts incoming string into urf8 string + * Converts incoming string into utf8 string * */ LL_COMMON_API std::string ll_convert_string_to_utf8_string(const std::string& in); -- cgit v1.3 From 9ffcafb64b4483c315d00e88ffc1438bce1f7915 Mon Sep 17 00:00:00 2001 From: Nat Goodspeed Date: Fri, 14 Dec 2018 10:48:43 -0500 Subject: SL-10153: Introduce ll_convert, windows_message() templates. Add ll_convert template, used as (e.g.): ll_convert(value_of_some_other_string_type); There is no generic template implementation -- the template exists solely to provide generic aliases for a bewildering family of llstring.h string- conversion functions with highly-specific names. There's a generic implementation, though, for the degenerate case where FROM and TO are identical. Add ll_convert<> specialization aliases for most of the string-conversion functions declared in llstring.h, including the Windows-specific ones involving llutf16string and std::wstring. Add a mini-lecture in llstring.h about appropriate use of string types on Windows. Add LL_WCHAR_T_NATIVE llpreprocessor.h macro so we can detect whether to provide separate conversions for llutf16string and std::wstring, or whether those would collide because the types are identical. Add inline ll_convert_wide_to_string(const std::wstring&) overloads so caller isn't required to call arg.c_str(), which naturally permits an ll_convert alias. Add ll_convert_wide_to_wstring(), ll_convert_wstring_to_wide() as placeholders for converting between Windows std::wstring and Linden LLWString, with corresponding ll_convert aliases. We don't yet have library code to perform such conversions officially; for now, just copy characters. Add LLStringUtil::getenv(key) and getoptenv(key) functions. The latter returns boost::optional in case the caller needs to detect absence of a given environment variable rather than simply accepting a default value. Naturally getenv(), which accepts a default, is implemented using getoptenv(). getoptenv(), in turn, is implemented using an underlying llstring_getoptenv(). On Windows, llstring_getoptenv() returns boost::optional (based on GetEnvironmentVariableW()), whereas elsewhere, llstring_getoptenv() returns boost::optional (based on classic Posix getenv()). The beauty of generic ll_convert is that the portable LLStringUtilBase:: getoptenv() template can call the platform-specific llstring_getoptenv() and transparently perform whatever conversion is necessary to return the desired string_type. Add windows_message(error) template, with an overload that implicitly calls GetLastError(). We provide a single concrete windows_message() implementation because that's what we get from Windows FormatMessageW() -- everything else is a generic conversion to the desired target string type. This obviates llprocess.cpp's previous WindowsErrorString() implementation -- reimplement using windows_message(). --- indra/llcommon/llpreprocessor.h | 21 +++++ indra/llcommon/llprocess.cpp | 27 +----- indra/llcommon/llstring.cpp | 125 +++++++++++++++++++++++++++- indra/llcommon/llstring.h | 176 ++++++++++++++++++++++++++++++++++++++-- indra/llcommon/stdtypes.h | 7 +- 5 files changed, 323 insertions(+), 33 deletions(-) (limited to 'indra/llcommon') diff --git a/indra/llcommon/llpreprocessor.h b/indra/llcommon/llpreprocessor.h index ef015fdce4..e8f9981437 100644 --- a/indra/llcommon/llpreprocessor.h +++ b/indra/llcommon/llpreprocessor.h @@ -101,6 +101,9 @@ #endif +// Although thread_local is now a standard storage class, we can't just +// #define LL_THREAD_LOCAL as thread_local because the *usage* is different. +// We'll have to take the time to change LL_THREAD_LOCAL declarations by hand. #if LL_WINDOWS # define LL_THREAD_LOCAL __declspec(thread) #else @@ -177,6 +180,24 @@ #define LL_DLLIMPORT #endif // LL_WINDOWS +#if ! defined(LL_WINDOWS) +#define LL_WCHAR_T_NATIVE 1 +#else // LL_WINDOWS +// https://docs.microsoft.com/en-us/cpp/preprocessor/predefined-macros +// _WCHAR_T_DEFINED is defined if wchar_t is provided at all. +// Specifically, it has value 1 if wchar_t is an intrinsic type, else empty. +// _NATIVE_WCHAR_T_DEFINED has value 1 if wchar_t is intrinsic, else undefined. +// For years we have compiled with /Zc:wchar_t-, meaning that wchar_t is a +// typedef for unsigned short (in stddef.h). Lore has it that one of our +// proprietary binary-only libraries has traditionally been built that way and +// therefore EVERYTHING ELSE requires it. Therefore, in a typical Linden +// Windows build, _WCHAR_T_DEFINED is defined but empty, while +// _NATIVE_WCHAR_T_DEFINED is undefined. +# if defined(_NATIVE_WCHAR_T_DEFINED) +# define LL_WCHAR_T_NATIVE 1 +# endif // _NATIVE_WCHAR_T_DEFINED +#endif // LL_WINDOWS + #if LL_COMMON_LINK_SHARED // CMake automagically defines llcommon_EXPORTS only when building llcommon // sources, and only when llcommon is a shared library (i.e. when diff --git a/indra/llcommon/llprocess.cpp b/indra/llcommon/llprocess.cpp index 5753efdc59..1fa53f322b 100644 --- a/indra/llcommon/llprocess.cpp +++ b/indra/llcommon/llprocess.cpp @@ -1205,30 +1205,9 @@ static LLProcess::Status interpret_status(int status) /// GetLastError()/FormatMessage() boilerplate static std::string WindowsErrorString(const std::string& operation) { - int result = GetLastError(); - - LPTSTR error_str = 0; - if (FormatMessage( FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM, - NULL, - result, - 0, - (LPTSTR)&error_str, - 0, - NULL) - != 0) - { - // convert from wide-char string to multi-byte string - char message[256]; - wcstombs(message, error_str, sizeof(message)); - message[sizeof(message)-1] = 0; - LocalFree(error_str); - // convert to std::string to trim trailing whitespace - std::string mbsstr(message); - mbsstr.erase(mbsstr.find_last_not_of(" \t\r\n")); - return STRINGIZE(operation << " failed (" << result << "): " << mbsstr); - } - return STRINGIZE(operation << " failed (" << result - << "), but FormatMessage() did not explain"); + auto result = GetLastError(); + return STRINGIZE(operation << " failed (" << result << "): " + << windows_message(result)); } /***************************************************************************** diff --git a/indra/llcommon/llstring.cpp b/indra/llcommon/llstring.cpp index 42390c8a7b..f931103ba6 100644 --- a/indra/llcommon/llstring.cpp +++ b/indra/llcommon/llstring.cpp @@ -53,6 +53,40 @@ std::string ll_safe_string(const char* in, S32 maxlen) return std::string(); } +boost::optional llstring_getoptenv(const std::string& key) +{ + auto wkey = ll_convert_string_to_wide(key); + // Take a wild guess as to how big the buffer should be. + std::vector buffer(1024); + auto n = GetEnvironmentVariableW(wkey.c_str(), &buffer[0], buffer.size()); + // If our initial guess was too short, n will indicate the size (in + // wchar_t's) that buffer should have been, including the terminating nul. + if (n > (buffer.size() - 1)) + { + // make it big enough + buffer.resize(n); + // and try again + n = GetEnvironmentVariableW(wkey.c_str(), &buffer[0], buffer.size()); + } + // did that (ultimately) succeed? + if (n) + { + // great, return populated boost::optional + return { &buffer[0] }; + } + + // not successful + auto last_error = GetLastError(); + // Don't bother warning for NOT_FOUND; that's an expected case + if (last_error != ERROR_ENVVAR_NOT_FOUND) + { + LL_WARNS() << "GetEnvironmentVariableW('" << key << "') failed: " + << windows_message(last_error) << LL_ENDL; + } + // return empty boost::optional + return {}; +} + bool is_char_hex(char hex) { if((hex >= '0') && (hex <= '9')) @@ -715,12 +749,12 @@ std::string ll_convert_wide_to_string(const wchar_t* in, unsigned int code_page) return out; } -std::basic_string ll_convert_string_to_wide(const std::string& in) +std::wstring ll_convert_string_to_wide(const std::string& in) { return ll_convert_string_to_wide(in, CP_UTF8); } -std::basic_string ll_convert_string_to_wide(const std::string& in, unsigned int code_page) +std::wstring ll_convert_string_to_wide(const std::string& in, unsigned int code_page) { // From review: // We can preallocate a wide char buffer that is the same length (in wchar_t elements) as the utf8 input, @@ -745,6 +779,24 @@ std::basic_string ll_convert_string_to_wide(const std::string& in, unsi return {&w_out[0]}; } +LLWString ll_convert_wide_to_wstring(const std::wstring& in) +{ + // This function, like its converse, is a placeholder, encapsulating a + // guilty little hack: the only "official" way nat has found to convert + // between std::wstring (16 bits on Windows) and LLWString (UTF-32) is + // by using iconv, which we've avoided so far. It kinda sorta works to + // just copy individual characters... + // The point is that if/when we DO introduce some more official way to + // perform such conversions, we should only have to call it here. + return { in.begin(), in.end() }; +} + +std::wstring ll_convert_wstring_to_wide(const LLWString& in) +{ + // See comments in ll_convert_wide_to_wstring() + return { in.begin(), in.end() }; +} + std::string ll_convert_string_to_utf8_string(const std::string& in) { auto w_mesg = ll_convert_string_to_wide(in, CP_ACP); @@ -752,7 +804,74 @@ std::string ll_convert_string_to_utf8_string(const std::string& in) return out_utf8; } -#endif // LL_WINDOWS + +namespace +{ + +void HeapFree_deleter(void* ptr) +{ + // instead of LocalFree(), per https://stackoverflow.com/a/31541205 + HeapFree(GetProcessHeap(), NULL, ptr); +} + +} // anonymous namespace + +template<> +std::wstring windows_message(DWORD error) +{ + // derived from https://stackoverflow.com/a/455533 + wchar_t* rawptr = nullptr; + auto okay = FormatMessageW( + // use system message tables for GetLastError() codes + FORMAT_MESSAGE_FROM_SYSTEM | + // internally allocate buffer and return its pointer + FORMAT_MESSAGE_ALLOCATE_BUFFER | + // you cannot pass insertion parameters (thanks Gandalf) + FORMAT_MESSAGE_IGNORE_INSERTS | + // ignore line breaks in message definition text + FORMAT_MESSAGE_MAX_WIDTH_MASK, + NULL, // lpSource, unused with FORMAT_MESSAGE_FROM_SYSTEM + error, // dwMessageId + MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), // dwLanguageId + (LPWSTR)&rawptr, // lpBuffer: force-cast wchar_t** to wchar_t* + 0, // nSize, unused with FORMAT_MESSAGE_ALLOCATE_BUFFER + NULL); // Arguments, unused + + // make a unique_ptr from rawptr so it gets cleaned up properly + std::unique_ptr bufferptr(rawptr, HeapFree_deleter); + + if (okay && bufferptr) + { + // got the message, return it ('okay' is length in characters) + return { bufferptr.get(), okay }; + } + + // did not get the message, synthesize one + auto format_message_error = GetLastError(); + std::wostringstream out; + out << L"GetLastError() " << error << L" (FormatMessageW() failed with " + << format_message_error << L")"; + return out.str(); +} + +#else // ! LL_WINDOWS + +boost::optional llstring_getoptenv(const std::string& key) +{ + auto found = getenv(key.c_str()); + if (found) + { + // return populated boost::optional + return { found }; + } + else + { + // return empty boost::optional + return {}; + } +} + +#endif // ! LL_WINDOWS long LLStringOps::sPacificTimeOffset = 0; long LLStringOps::sLocalTimeOffset = 0; diff --git a/indra/llcommon/llstring.h b/indra/llcommon/llstring.h index 7c3e9f952d..2dccc7cbdf 100644 --- a/indra/llcommon/llstring.h +++ b/indra/llcommon/llstring.h @@ -27,6 +27,7 @@ #ifndef LL_LLSTRING_H #define LL_LLSTRING_H +#include #include #include //#include @@ -337,6 +338,19 @@ public: const string_type& string, const string_type& substr); + /** + * get environment string value with proper Unicode handling + * (key is always UTF-8) + * detect absence by return value == dflt + */ + static string_type getenv(const std::string& key, const string_type& dflt=""); + /** + * get optional environment string value with proper Unicode handling + * (key is always UTF-8) + * detect absence by (! return value) + */ + static boost::optional getoptenv(const std::string& key); + static void addCRLF(string_type& string); static void removeCRLF(string_type& string); static void removeWindowsCR(string_type& string); @@ -496,6 +510,37 @@ LL_COMMON_API bool iswindividual(llwchar elem); * Unicode support */ +/// generic conversion aliases +template +struct ll_convert_impl +{ + // Don't even provide a generic implementation. We specialize for every + // combination we do support. + TO operator()(const FROM& in) const; +}; + +// Use a function template to get the nice ll_convert(from_value) API. +template +TO ll_convert(const FROM& in) +{ + return ll_convert_impl()(in); +} + +// degenerate case +template +struct ll_convert_impl +{ + T operator()(const T& in) const { return in; } +}; + +// specialize ll_convert_impl to return EXPR +#define ll_convert_alias(TO, FROM, EXPR) \ +template<> \ +struct ll_convert_impl \ +{ \ + TO operator()(const FROM& in) const { return EXPR; } \ +} + // Make the incoming string a utf8 string. Replaces any unknown glyph // with the UNKNOWN_CHARACTER. Once any unknown glyph is found, the rest // of the data may not be recovered. @@ -503,30 +548,83 @@ LL_COMMON_API std::string rawstr_to_utf8(const std::string& raw); // // We should never use UTF16 except when communicating with Win32! +// https://docs.microsoft.com/en-us/cpp/cpp/char-wchar-t-char16-t-char32-t +// nat 2018-12-14: I consider the whole llutf16string thing a mistake, because +// the Windows APIs we want to call are all defined in terms of wchar_t* +// (or worse, LPCTSTR). +// https://docs.microsoft.com/en-us/windows/desktop/winprog/windows-data-types + +// While there is no point coding for an ASCII-only world (! defined(UNICODE)), +// use of U16 and llutf16string for Windows APIs locks in /Zc:wchar_t-. Going +// forward, we should code in terms of wchar_t and std::wstring so as to +// support either setting of /Zc:wchar_t. + +// The first link above states that char can be used to hold ASCII or any +// multi-byte character set, and distinguishes wchar_t (UTF-16LE), char16_t +// (UTF-16) and char32_t (UTF-32). Nonetheless, within this code base: +// * char and std::string always hold UTF-8 (of which ASCII is a subset). It +// is a BUG if they are used to pass strings in any other multi-byte +// encoding. +// * wchar_t and std::wstring should be our interface to Windows wide-string +// APIs, and therefore hold UTF-16LE. +// * U16 and llutf16string are the previous but DEPRECATED UTF-16LE type. Do +// not introduce new uses of U16 or llutf16string for string data. +// * llwchar and LLWString hold UTF-32 strings. +// * Do not introduce char16_t or std::u16string. +// * Do not introduce char32_t or std::u32string. // +// This typedef may or may not be identical to std::wstring, depending on +// LL_WCHAR_T_NATIVE. typedef std::basic_string llutf16string; +#if ! defined(LL_WCHAR_T_NATIVE) +// wchar_t is identical to U16, and std::wstring is identical to llutf16string. +// Defining an ll_convert alias involving llutf16string would collide with the +// comparable preferred alias involving std::wstring. (In this scenario, if +// you pass llutf16string, it will engage the std::wstring specialization.) +#define ll_convert_u16_alias(TO, FROM, EXPR) // nothing +#else +// wchar_t is a distinct native type, so llutf16string is also a distinct +// type, and there IS a point to converting separately to/from llutf16string. +// (But why? Windows APIs are still defined in terms of wchar_t, and +// in this scenario llutf16string won't work for them!) +#define ll_convert_u16_alias(TO, FROM, EXPR) ll_convert_alias(TO, FROM, EXPR) + +// converting between std::wstring and llutf16string involves copying chars +// enclose the brace-initialization expression in parens to protect the comma +// from macro-argument parsing +ll_convert_alias(llutf16string, std::wstring, ({ in.begin(), in.end() })); +ll_convert_alias(std::wstring, llutf16string, ({ in.begin(), in.end() })); +#endif + LL_COMMON_API LLWString utf16str_to_wstring(const llutf16string &utf16str, S32 len); LL_COMMON_API LLWString utf16str_to_wstring(const llutf16string &utf16str); +ll_convert_u16_alias(LLWString, llutf16string, utf16str_to_wstring(in)); LL_COMMON_API llutf16string wstring_to_utf16str(const LLWString &utf32str, S32 len); LL_COMMON_API llutf16string wstring_to_utf16str(const LLWString &utf32str); +ll_convert_u16_alias(llutf16string, LLWString, wstring_to_utf16str(in)); LL_COMMON_API llutf16string utf8str_to_utf16str ( const std::string& utf8str, S32 len); LL_COMMON_API llutf16string utf8str_to_utf16str ( const std::string& utf8str ); +ll_convert_u16_alias(llutf16string, std::string, utf8str_to_utf16str(in)); LL_COMMON_API LLWString utf8str_to_wstring(const std::string &utf8str, S32 len); LL_COMMON_API LLWString utf8str_to_wstring(const std::string &utf8str); // Same function, better name. JC inline LLWString utf8string_to_wstring(const std::string& utf8_string) { return utf8str_to_wstring(utf8_string); } +// best name of all +ll_convert_alias(LLWString, std::string, utf8string_to_wstring(in)); // LL_COMMON_API S32 wchar_to_utf8chars(llwchar inchar, char* outchars); LL_COMMON_API std::string wstring_to_utf8str(const LLWString &utf32str, S32 len); LL_COMMON_API std::string wstring_to_utf8str(const LLWString &utf32str); +ll_convert_alias(std::string, LLWString, wstring_to_utf8str(in)); LL_COMMON_API std::string utf16str_to_utf8str(const llutf16string &utf16str, S32 len); LL_COMMON_API std::string utf16str_to_utf8str(const llutf16string &utf16str); +ll_convert_u16_alias(std::string, llutf16string, utf16str_to_utf8str(in)); #if LL_WINDOWS inline std::string wstring_to_utf8str(const llutf16string &utf16str) { return utf16str_to_utf8str(utf16str);} @@ -636,14 +734,36 @@ using snprintf_hack::snprintf; */ LL_COMMON_API std::string ll_convert_wide_to_string(const wchar_t* in, unsigned int code_page); LL_COMMON_API std::string ll_convert_wide_to_string(const wchar_t* in); // default CP_UTF8 +inline std::string ll_convert_wide_to_string(const std::wstring& in, unsigned int code_page) +{ + return ll_convert_wide_to_string(in.c_str(), code_page); +} +inline std::string ll_convert_wide_to_string(const std::wstring& in) +{ + return ll_convert_wide_to_string(in.c_str()); +} +ll_convert_alias(std::string, std::wstring, ll_convert_wide_to_string(in)); /** * Converts a string to wide string. */ -LL_COMMON_API std::basic_string ll_convert_string_to_wide(const std::string& in, - unsigned int code_page); -LL_COMMON_API std::basic_string ll_convert_string_to_wide(const std::string& in); - // default CP_UTF8 +LL_COMMON_API std::wstring ll_convert_string_to_wide(const std::string& in, + unsigned int code_page); +LL_COMMON_API std::wstring ll_convert_string_to_wide(const std::string& in); + // default CP_UTF8 +ll_convert_alias(std::wstring, std::string, ll_convert_string_to_wide(in)); + +/** + * Convert a Windows wide string to our LLWString + */ +LL_COMMON_API LLWString ll_convert_wide_to_wstring(const std::wstring& in); +ll_convert_alias(LLWString, std::wstring, ll_convert_wide_to_wstring(in)); + +/** + * Convert LLWString to Windows wide string + */ +LL_COMMON_API std::wstring ll_convert_wstring_to_wide(const LLWString& in); +ll_convert_alias(std::wstring, LLWString, ll_convert_wstring_to_wide(in)); /** * Converts incoming string into utf8 string @@ -651,8 +771,39 @@ LL_COMMON_API std::basic_string ll_convert_string_to_wide(const std::st */ LL_COMMON_API std::string ll_convert_string_to_utf8_string(const std::string& in); +/// Get Windows message string for passed GetLastError() code +// VS 2013 doesn't let us forward-declare this template, which is what we +// started with, so the implementation could reference the specialization we +// haven't yet declared. Somewhat weirdly, just stating the generic +// implementation in terms of the specialization works, even in this order... + +// the general case is just a conversion from the sole implementation +// Microsoft says DWORD is a typedef for unsigned long +// https://docs.microsoft.com/en-us/windows/desktop/winprog/windows-data-types +// so rather than drag windows.h into everybody's include space... +template +STRING windows_message(unsigned long error) +{ + return ll_convert(windows_message(error)); +} + +/// There's only one real implementation +template<> +LL_COMMON_API std::wstring windows_message(unsigned long error); + +/// Get Windows message string, implicitly calling GetLastError() +template +STRING windows_message() { return windows_message(GetLastError()); } + //@} -#endif // LL_WINDOWS + +LL_COMMON_API boost::optional llstring_getoptenv(const std::string& key); + +#else // ! LL_WINDOWS + +LL_COMMON_API boost::optional llstring_getoptenv(const std::string& key); + +#endif // ! LL_WINDOWS /** * Many of the 'strip' and 'replace' methods of LLStringUtilBase need @@ -1595,6 +1746,21 @@ bool LLStringUtilBase::endsWith( return (idx == (string.size() - substr.size())); } +// static +template +auto LLStringUtilBase::getoptenv(const std::string& key) -> boost::optional +{ + auto found{llstring_getoptenv(key)}; + return found? { ll_convert(*found) } : {}; +} + +// static +template +auto LLStringUtilBase::getenv(const std::string& key, const string_type& dflt) -> string_type +{ + auto found{getoptenv(key)}; + return found? *found : dflt; +} template BOOL LLStringUtilBase::convertToBOOL(const string_type& string, BOOL& value) diff --git a/indra/llcommon/stdtypes.h b/indra/llcommon/stdtypes.h index bf3f3f9ee8..6c9871e76c 100644 --- a/indra/llcommon/stdtypes.h +++ b/indra/llcommon/stdtypes.h @@ -37,7 +37,12 @@ typedef signed int S32; typedef unsigned int U32; #if LL_WINDOWS -// Windows wchar_t is 16-bit +// https://docs.microsoft.com/en-us/cpp/build/reference/zc-wchar-t-wchar-t-is-native-type +// https://docs.microsoft.com/en-us/cpp/cpp/fundamental-types-cpp +// Windows wchar_t is 16-bit, whichever way /Zc:wchar_t is set. In effect, +// Windows wchar_t is always a typedef, either for unsigned short or __wchar_t. +// (__wchar_t, available either way, is Microsoft's native 2-byte wchar_t type.) +// In any case, llwchar should be a UTF-32 type. typedef U32 llwchar; #else typedef wchar_t llwchar; -- cgit v1.3 From 132e708fec50fd756b822925313456c70a4ff27f Mon Sep 17 00:00:00 2001 From: Nat Goodspeed Date: Fri, 14 Dec 2018 12:01:51 -0500 Subject: SL-10153: Fix previous commit for non-Windows systems. Move Windows-flavored llstring_getoptenv() to Windows-specific section of llstring.cpp. boost::optional type must be stated explicitly to initialize with a value. On platforms where llwchar is the same as wchar_t, LLWString is the same as std::wstring, so ll_convert specializations for std::wstring would duplicate those for LLWString. Defend against that. The compilers we use don't like 'return condition? { expr } : {}', in which we hope to construct and return an instance of the declared return type without having to restate the type. It works to use an explicit 'if' statement. --- indra/llcommon/llstring.cpp | 70 ++++++++++++++++++++++----------------------- indra/llcommon/llstring.h | 30 +++++++++++++------ 2 files changed, 57 insertions(+), 43 deletions(-) (limited to 'indra/llcommon') diff --git a/indra/llcommon/llstring.cpp b/indra/llcommon/llstring.cpp index f931103ba6..0174c411b4 100644 --- a/indra/llcommon/llstring.cpp +++ b/indra/llcommon/llstring.cpp @@ -53,40 +53,6 @@ std::string ll_safe_string(const char* in, S32 maxlen) return std::string(); } -boost::optional llstring_getoptenv(const std::string& key) -{ - auto wkey = ll_convert_string_to_wide(key); - // Take a wild guess as to how big the buffer should be. - std::vector buffer(1024); - auto n = GetEnvironmentVariableW(wkey.c_str(), &buffer[0], buffer.size()); - // If our initial guess was too short, n will indicate the size (in - // wchar_t's) that buffer should have been, including the terminating nul. - if (n > (buffer.size() - 1)) - { - // make it big enough - buffer.resize(n); - // and try again - n = GetEnvironmentVariableW(wkey.c_str(), &buffer[0], buffer.size()); - } - // did that (ultimately) succeed? - if (n) - { - // great, return populated boost::optional - return { &buffer[0] }; - } - - // not successful - auto last_error = GetLastError(); - // Don't bother warning for NOT_FOUND; that's an expected case - if (last_error != ERROR_ENVVAR_NOT_FOUND) - { - LL_WARNS() << "GetEnvironmentVariableW('" << key << "') failed: " - << windows_message(last_error) << LL_ENDL; - } - // return empty boost::optional - return {}; -} - bool is_char_hex(char hex) { if((hex >= '0') && (hex <= '9')) @@ -854,6 +820,40 @@ std::wstring windows_message(DWORD error) return out.str(); } +boost::optional llstring_getoptenv(const std::string& key) +{ + auto wkey = ll_convert_string_to_wide(key); + // Take a wild guess as to how big the buffer should be. + std::vector buffer(1024); + auto n = GetEnvironmentVariableW(wkey.c_str(), &buffer[0], buffer.size()); + // If our initial guess was too short, n will indicate the size (in + // wchar_t's) that buffer should have been, including the terminating nul. + if (n > (buffer.size() - 1)) + { + // make it big enough + buffer.resize(n); + // and try again + n = GetEnvironmentVariableW(wkey.c_str(), &buffer[0], buffer.size()); + } + // did that (ultimately) succeed? + if (n) + { + // great, return populated boost::optional + return boost::optional(&buffer[0]); + } + + // not successful + auto last_error = GetLastError(); + // Don't bother warning for NOT_FOUND; that's an expected case + if (last_error != ERROR_ENVVAR_NOT_FOUND) + { + LL_WARNS() << "GetEnvironmentVariableW('" << key << "') failed: " + << windows_message(last_error) << LL_ENDL; + } + // return empty boost::optional + return {}; +} + #else // ! LL_WINDOWS boost::optional llstring_getoptenv(const std::string& key) @@ -862,7 +862,7 @@ boost::optional llstring_getoptenv(const std::string& key) if (found) { // return populated boost::optional - return { found }; + return boost::optional(found); } else { diff --git a/indra/llcommon/llstring.h b/indra/llcommon/llstring.h index 2dccc7cbdf..87cb35c59c 100644 --- a/indra/llcommon/llstring.h +++ b/indra/llcommon/llstring.h @@ -583,19 +583,24 @@ typedef std::basic_string llutf16string; // comparable preferred alias involving std::wstring. (In this scenario, if // you pass llutf16string, it will engage the std::wstring specialization.) #define ll_convert_u16_alias(TO, FROM, EXPR) // nothing -#else +#else // defined(LL_WCHAR_T_NATIVE) // wchar_t is a distinct native type, so llutf16string is also a distinct // type, and there IS a point to converting separately to/from llutf16string. // (But why? Windows APIs are still defined in terms of wchar_t, and // in this scenario llutf16string won't work for them!) #define ll_convert_u16_alias(TO, FROM, EXPR) ll_convert_alias(TO, FROM, EXPR) -// converting between std::wstring and llutf16string involves copying chars -// enclose the brace-initialization expression in parens to protect the comma -// from macro-argument parsing -ll_convert_alias(llutf16string, std::wstring, ({ in.begin(), in.end() })); -ll_convert_alias(std::wstring, llutf16string, ({ in.begin(), in.end() })); -#endif +#if LL_WINDOWS +// LL_WCHAR_T_NATIVE is defined on non-Windows systems because, in fact, +// wchar_t is native. Everywhere but Windows, we use it for llwchar (see +// stdtypes.h). That makes LLWString identical to std::wstring, so these +// aliases for std::wstring would collide with those for LLWString. Only +// define on Windows, where converting between std::wstring and llutf16string +// means copying chars. +ll_convert_alias(llutf16string, std::wstring, llutf16string(in.begin(), in.end())); +ll_convert_alias(std::wstring, llutf16string, std::wstring(in.begin(), in.end())); +#endif // LL_WINDOWS +#endif // defined(LL_WCHAR_T_NATIVE) LL_COMMON_API LLWString utf16str_to_wstring(const llutf16string &utf16str, S32 len); LL_COMMON_API LLWString utf16str_to_wstring(const llutf16string &utf16str); @@ -1751,7 +1756,16 @@ template auto LLStringUtilBase::getoptenv(const std::string& key) -> boost::optional { auto found{llstring_getoptenv(key)}; - return found? { ll_convert(*found) } : {}; + if (found) + { + // return populated boost::optional + return { ll_convert(*found) }; + } + else + { + // empty boost::optional + return {}; + } } // static -- cgit v1.3 From c4096f670c7b3d43f8a5c1f65ef7e02033b0329d Mon Sep 17 00:00:00 2001 From: Nat Goodspeed Date: Fri, 14 Dec 2018 15:38:13 -0500 Subject: SL-10153: Review and rationalize fetching paths from environment. Use LLStringUtil::getenv() or getoptenv() whenever we fetch a string that will be used as a pathname. Use LLFile::tmpdir() instead of getenv("TEMP"). As an added extra-special bonus, finally clean up $TMP/llcontrol-test-zzzzzz directories that have been accumulating every time we run a local build! --- indra/llcommon/llfile.cpp | 19 +++++---- indra/llcommon/tests/llleap_test.cpp | 7 ++-- indra/llcommon/tests/llprocess_test.cpp | 5 ++- indra/llcommon/tests/llsdserialize_test.cpp | 7 ++-- indra/llmessage/tests/commtest.h | 8 +--- indra/llmessage/tests/llhttpclient_test.cpp | 9 +++-- indra/llrender/llfontgl.cpp | 41 ++++++++------------ indra/llvfs/lldir_linux.cpp | 33 ++++++++-------- indra/llvfs/lldir_solaris.cpp | 60 ++++++++++++----------------- indra/llvfs/lldir_win32.cpp | 26 ++++++------- indra/llxml/tests/llcontrol_test.cpp | 39 ++++++++----------- indra/newview/llexternaleditor.cpp | 7 ++-- indra/newview/llwebprofile.cpp | 4 +- 13 files changed, 116 insertions(+), 149 deletions(-) (limited to 'indra/llcommon') diff --git a/indra/llcommon/llfile.cpp b/indra/llcommon/llfile.cpp index fc203f78e1..8355b1e797 100644 --- a/indra/llcommon/llfile.cpp +++ b/indra/llcommon/llfile.cpp @@ -30,6 +30,7 @@ #if LL_WINDOWS #include "llwin32headerslean.h" #include // Windows errno +#include #else #include #endif @@ -134,8 +135,10 @@ int warnif(const std::string& desc, const std::string& filename, int rc, int acc { // Only do any of this stuff (before LL_ENDL) if it will be logged. LL_DEBUGS("LLFile") << empty; - const char* TEMP = getenv("TEMP"); - if (! TEMP) + // would be nice to use LLDir for this, but dependency goes the + // wrong way + const char* TEMP = LLFile::tmpdir(); + if (! (TEMP && *TEMP)) { LL_CONT << "No $TEMP, not running 'handle'"; } @@ -341,17 +344,13 @@ const char *LLFile::tmpdir() #if LL_WINDOWS sep = '\\'; - DWORD len = GetTempPathW(0, L""); - llutf16string utf16path; - utf16path.resize(len + 1); - len = GetTempPathW(static_cast(utf16path.size()), &utf16path[0]); - utf8path = utf16str_to_utf8str(utf16path); + std::vector utf16path(MAX_PATH + 1); + GetTempPathW(utf16path.size(), &utf16path[0]); + utf8path = ll_convert_wide_to_string(&utf16path[0]); #else sep = '/'; - char *env = getenv("TMPDIR"); - - utf8path = env ? env : "/tmp/"; + utf8path = LLStringUtil::getenv("TMPDIR", "/tmp/"); #endif if (utf8path[utf8path.size() - 1] != sep) { diff --git a/indra/llcommon/tests/llleap_test.cpp b/indra/llcommon/tests/llleap_test.cpp index c387da6c48..45648536c4 100644 --- a/indra/llcommon/tests/llleap_test.cpp +++ b/indra/llcommon/tests/llleap_test.cpp @@ -26,6 +26,7 @@ #include "wrapllerrs.h" #include "llevents.h" #include "llprocess.h" +#include "llstring.h" #include "stringize.h" #include "StringVec.h" #include @@ -198,14 +199,12 @@ namespace tut // basename. reader_module(LLProcess::basename( reader.getName().substr(0, reader.getName().length()-3))), - pPYTHON(getenv("PYTHON")), - PYTHON(pPYTHON? pPYTHON : "") + PYTHON(LLStringUtil::getenv("PYTHON")) { - ensure("Set PYTHON to interpreter pathname", pPYTHON); + ensure("Set PYTHON to interpreter pathname", !PYTHON.empty()); } NamedExtTempFile reader; const std::string reader_module; - const char* pPYTHON; const std::string PYTHON; }; typedef test_group llleap_group; diff --git a/indra/llcommon/tests/llprocess_test.cpp b/indra/llcommon/tests/llprocess_test.cpp index b27e125d2e..5c87cdabd9 100644 --- a/indra/llcommon/tests/llprocess_test.cpp +++ b/indra/llcommon/tests/llprocess_test.cpp @@ -34,6 +34,7 @@ #include "stringize.h" #include "llsdutil.h" #include "llevents.h" +#include "llstring.h" #include "wrapllerrs.h" #if defined(LL_WINDOWS) @@ -142,8 +143,8 @@ struct PythonProcessLauncher mDesc(desc), mScript("py", script) { - const char* PYTHON(getenv("PYTHON")); - tut::ensure("Set $PYTHON to the Python interpreter", PYTHON); + auto PYTHON(LLStringUtil::getenv("PYTHON")); + tut::ensure("Set $PYTHON to the Python interpreter", !PYTHON.empty()); mParams.desc = desc + " script"; mParams.executable = PYTHON; diff --git a/indra/llcommon/tests/llsdserialize_test.cpp b/indra/llcommon/tests/llsdserialize_test.cpp index 745e3a168c..6ac974e659 100644 --- a/indra/llcommon/tests/llsdserialize_test.cpp +++ b/indra/llcommon/tests/llsdserialize_test.cpp @@ -41,6 +41,7 @@ typedef U32 uint32_t; #include #include #include "llprocess.h" +#include "llstring.h" #endif #include "boost/range.hpp" @@ -1705,8 +1706,8 @@ namespace tut template void python(const std::string& desc, const CONTENT& script, int expect=0) { - const char* PYTHON(getenv("PYTHON")); - ensure("Set $PYTHON to the Python interpreter", PYTHON); + auto PYTHON(LLStringUtil::getenv("PYTHON")); + ensure("Set $PYTHON to the Python interpreter", !PYTHON.empty()); NamedTempFile scriptfile("py", script); @@ -1714,7 +1715,7 @@ namespace tut std::string q("\""); std::string qPYTHON(q + PYTHON + q); std::string qscript(q + scriptfile.getName() + q); - int rc = _spawnl(_P_WAIT, PYTHON, qPYTHON.c_str(), qscript.c_str(), NULL); + int rc = _spawnl(_P_WAIT, PYTHON.c_str(), qPYTHON.c_str(), qscript.c_str(), NULL); if (rc == -1) { char buffer[256]; diff --git a/indra/llmessage/tests/commtest.h b/indra/llmessage/tests/commtest.h index 7c8f27bbd2..0359eba803 100644 --- a/indra/llmessage/tests/commtest.h +++ b/indra/llmessage/tests/commtest.h @@ -34,6 +34,7 @@ #include "llsd.h" #include "llhost.h" #include "llexception.h" +#include "llstring.h" #include "stringize.h" #include #include @@ -46,12 +47,7 @@ struct CommtestError: public LLException static bool query_verbose() { - const char* cbose = getenv("INTEGRATION_TEST_VERBOSE"); - if (! cbose) - { - cbose = "1"; - } - std::string strbose(cbose); + std::string strbose(LLStringUtil::getenv("INTEGRATION_TEST_VERBOSE", "1")); return (! (strbose == "0" || strbose == "off" || strbose == "false" || strbose == "quiet")); } diff --git a/indra/llmessage/tests/llhttpclient_test.cpp b/indra/llmessage/tests/llhttpclient_test.cpp index 9356a14f1f..78faa66a0d 100644 --- a/indra/llmessage/tests/llhttpclient_test.cpp +++ b/indra/llmessage/tests/llhttpclient_test.cpp @@ -41,6 +41,7 @@ #include "llpumpio.h" #include "lliosocket.h" +#include "llstring.h" #include "stringize.h" #include "llcleanup.h" @@ -50,13 +51,13 @@ namespace tut { public: HTTPClientTestData(): - PORT(getenv("PORT")), + PORT(LLStringUtil::getenv("PORT")), // Turning NULL PORT into empty string doesn't make things work; // that's just to keep this initializer from blowing up. We test // PORT separately in the constructor body. - local_server(STRINGIZE("http://127.0.0.1:" << (PORT? PORT : "") << "/")) + local_server(STRINGIZE("http://127.0.0.1:" << PORT << "/")) { - ensure("Set environment variable PORT to local test server port", PORT); + ensure("Set environment variable PORT to local test server port", !PORT.empty()); apr_pool_create(&mPool, NULL); LLCurl::initClass(false); mClientPump = new LLPumpIO(mPool); @@ -87,7 +88,7 @@ namespace tut } } - const char* const PORT; + const std::string PORT; const std::string local_server; private: diff --git a/indra/llrender/llfontgl.cpp b/indra/llrender/llfontgl.cpp index cf0a117567..bb56988422 100644 --- a/indra/llrender/llfontgl.cpp +++ b/indra/llrender/llfontgl.cpp @@ -1063,33 +1063,24 @@ LLFontGL* LLFontGL::getFontDefault() // static std::string LLFontGL::getFontPathSystem() { - std::string system_path; - - // Try to figure out where the system's font files are stored. - char *system_root = NULL; -#if LL_WINDOWS - system_root = getenv("SystemRoot"); /* Flawfinder: ignore */ - if (!system_root) - { - LL_WARNS() << "SystemRoot not found, attempting to load fonts from default path." << LL_ENDL; - } +#if LL_DARWIN + // HACK for Mac OS X + return "/System/Library/Fonts/"; + +#elif LL_WINDOWS + wchar_t *pwstr = NULL; + HRESULT okay = SHGetKnownFolderPath(FOLDERID_Fonts, 0, NULL, &pwstr); + if (SUCCEEDED(okay) && pwstr) + { + std::string fontpath(ll_convert_wide_to_string(pwstr)); + // SHGetKnownFolderPath() contract requires us to free pwstr + CoTaskMemFree(pwstr); + return fontpath; + } #endif - if (system_root) - { - system_path = llformat("%s/fonts/", system_root); - } - else - { -#if LL_WINDOWS - // HACK for windows 98/Me - system_path = "/WINDOWS/FONTS/"; -#elif LL_DARWIN - // HACK for Mac OS X - system_path = "/System/Library/Fonts/"; -#endif - } - return system_path; + LL_WARNS() << "Could not determine system fonts path" << LL_ENDL; + return {}; } diff --git a/indra/llvfs/lldir_linux.cpp b/indra/llvfs/lldir_linux.cpp index 2cd06b81f8..80ad05345a 100644 --- a/indra/llvfs/lldir_linux.cpp +++ b/indra/llvfs/lldir_linux.cpp @@ -29,6 +29,7 @@ #include "lldir_linux.h" #include "llerror.h" #include "llrand.h" +#include "llstring.h" #include #include #include @@ -40,28 +41,24 @@ static std::string getCurrentUserHome(char* fallback) { const uid_t uid = getuid(); struct passwd *pw; - char *result_cstr = fallback; - + pw = getpwuid(uid); if ((pw != NULL) && (pw->pw_dir != NULL)) { - result_cstr = (char*) pw->pw_dir; + return pw->pw_dir; + } + + LL_INFOS() << "Couldn't detect home directory from passwd - trying $HOME" << LL_ENDL; + auto home_env = LLStringUtil::getoptenv("HOME"); + if (home_env) + { + return *home_env; } else { - LL_INFOS() << "Couldn't detect home directory from passwd - trying $HOME" << LL_ENDL; - const char *const home_env = getenv("HOME"); /* Flawfinder: ignore */ - if (home_env) - { - result_cstr = (char*) home_env; - } - else - { - LL_WARNS() << "Couldn't detect home directory! Falling back to " << fallback << LL_ENDL; - } + LL_WARNS() << "Couldn't detect home directory! Falling back to " << fallback << LL_ENDL; + return fallback; } - - return std::string(result_cstr); } @@ -156,18 +153,18 @@ void LLDir_Linux::initAppDirs(const std::string &app_name, if (!app_read_only_data_dir.empty()) { mAppRODataDir = app_read_only_data_dir; - mSkinBaseDir = mAppRODataDir + mDirDelimiter + "skins"; + mSkinBaseDir = add(mAppRODataDir, "skins"); } mAppName = app_name; std::string upper_app_name(app_name); LLStringUtil::toUpper(upper_app_name); - char* app_home_env = getenv((upper_app_name + "_USER_DIR").c_str()); /* Flawfinder: ignore */ + auto app_home_env(LLStringUtil::getoptenv(upper_app_name + "_USER_DIR")); if (app_home_env) { // user has specified own userappdir i.e. $SECONDLIFE_USER_DIR - mOSUserAppDir = app_home_env; + mOSUserAppDir = *app_home_env; } else { diff --git a/indra/llvfs/lldir_solaris.cpp b/indra/llvfs/lldir_solaris.cpp index d3536a12ee..f18560ff20 100644 --- a/indra/llvfs/lldir_solaris.cpp +++ b/indra/llvfs/lldir_solaris.cpp @@ -29,6 +29,7 @@ #include "lldir_solaris.h" #include "llerror.h" #include "llrand.h" +#include "llstring.h" #include #include #include @@ -41,30 +42,28 @@ static std::string getCurrentUserHome(char* fallback) { + // fwiw this exactly duplicates getCurrentUserHome() in lldir_linux.cpp... + // we should either derive both from LLDir_Posix or just axe Solaris. const uid_t uid = getuid(); struct passwd *pw; - char *result_cstr = fallback; - + pw = getpwuid(uid); if ((pw != NULL) && (pw->pw_dir != NULL)) { - result_cstr = (char*) pw->pw_dir; + return pw->pw_dir; + } + + LL_INFOS() << "Couldn't detect home directory from passwd - trying $HOME" << LL_ENDL; + auto home_env = LLStringUtil::getoptenv("HOME"); + if (home_env) + { + return *home_env; } else { - LL_INFOS() << "Couldn't detect home directory from passwd - trying $HOME" << LL_ENDL; - const char *const home_env = getenv("HOME"); /* Flawfinder: ignore */ - if (home_env) - { - result_cstr = (char*) home_env; - } - else - { - LL_WARNS() << "Couldn't detect home directory! Falling back to " << fallback << LL_ENDL; - } + LL_WARNS() << "Couldn't detect home directory! Falling back to " << fallback << LL_ENDL; + return fallback; } - - return std::string(result_cstr); } @@ -135,27 +134,15 @@ LLDir_Solaris::LLDir_Solaris() //NOTE: Why force people to cd into the package directory? // Look for SECONDLIFE env variable and use it, if set. - char *dcf = getenv("SECONDLIFE"); - if(dcf != NULL){ - (void)strcpy(path, dcf); - (void)strcat(path, "/bin"); //NOTE: make sure we point at the bin - mExecutableDir = strdup(path); + auto SECONDLIFE(LLDirUtil::getoptenv("SECONDLIFE")); + if(SECONDLIFE){ + mExecutableDir = add(*SECONDLIFE, "bin"); //NOTE: make sure we point at the bin }else{ - // plunk a null at last '/' to get exec dir - char *s = execpath + strlen(execpath) -1; - while(*s != '/' && s != execpath){ - --s; - } - - if(s != execpath){ - *s = (char)NULL; - - mExecutableDir = strdup(execpath); - LL_INFOS() << "mExecutableDir = [" << mExecutableDir << "]" << LL_ENDL; - } + mExecutableDir = getDirName(execpath); + LL_INFOS() << "mExecutableDir = [" << mExecutableDir << "]" << LL_ENDL; } - - mLLPluginDir = mExecutableDir + mDirDelimiter + "llplugin"; + + mLLPluginDir = add(mExecutableDir, "llplugin"); // *TODO: don't use /tmp, use $HOME/.secondlife/tmp or something. mTempDir = "/tmp"; @@ -175,17 +162,18 @@ void LLDir_Solaris::initAppDirs(const std::string &app_name, if (!app_read_only_data_dir.empty()) { mAppRODataDir = app_read_only_data_dir; + mSkinBaseDir = add(mAppRODataDir, "skins"); } mAppName = app_name; std::string upper_app_name(app_name); LLStringUtil::toUpper(upper_app_name); - char* app_home_env = getenv((upper_app_name + "_USER_DIR").c_str()); /* Flawfinder: ignore */ + auto app_home_env(LLStringUtil::getoptenv(upper_app_name + "_USER_DIR")); if (app_home_env) { // user has specified own userappdir i.e. $SECONDLIFE_USER_DIR - mOSUserAppDir = app_home_env; + mOSUserAppDir = *app_home_env; } else { diff --git a/indra/llvfs/lldir_win32.cpp b/indra/llvfs/lldir_win32.cpp index fc4680bbfb..acf734f16b 100644 --- a/indra/llvfs/lldir_win32.cpp +++ b/indra/llvfs/lldir_win32.cpp @@ -30,6 +30,7 @@ #include "lldir_win32.h" #include "llerror.h" +#include "llstring.h" #include "stringize.h" #include "llfile.h" #include @@ -55,17 +56,17 @@ namespace { switch (state) { + boost::optional prelog_name; + case prst::INIT: // assume we failed, until we succeed state = prst::SKIP; - // can't initialize within one case of a switch statement - const char* prelog_name; - prelog_name = getenv("PRELOG"); + prelog_name = LLDirUtil::getoptenv("PRELOG"); if (! prelog_name) // no PRELOG variable set, carry on return; - prelogf = new std::ofstream(prelog_name, std::ios_base::app); + prelogf = new llofstream(*prelog_name, std::ios_base::app); if (! (prelogf && prelogf->is_open())) // can't complain to anybody; how? return; @@ -95,13 +96,11 @@ LLDir_Win32::LLDir_Win32() WCHAR w_str[MAX_PATH]; // Application Data is where user settings go. We rely on $APPDATA being - // correct; in fact the VMP makes a point of setting it properly, since - // Windows itself botches the job for non-ASCII usernames (MAINT-8087). - // Try using wide-character getenv()?? - wchar_t *APPDATA = _wgetenv(L"APPDATA"); + // correct. + auto APPDATA = LLStringUtil::getoptenv("APPDATA"); if (APPDATA) { - mOSUserDir = ll_convert_wide_to_string(APPDATA, CP_UTF8); + mOSUserDir = *APPDATA; } PRELOG("APPDATA='" << mOSUserDir << "'"); // On Windows, we could have received a plain-ASCII pathname in which @@ -118,7 +117,7 @@ LLDir_Win32::LLDir_Win32() if (SUCCEEDED(okay) && pwstr) { // But of course, only update mOSUserDir if SHGetKnownFolderPath() works. - mOSUserDir = ll_convert_wide_to_string(pwstr, CP_UTF8); + mOSUserDir = ll_convert_wide_to_string(pwstr); // Not only that: update our environment so that child processes // will see a reasonable value as well. _wputenv_s(L"APPDATA", pwstr); @@ -136,11 +135,10 @@ LLDir_Win32::LLDir_Win32() // // We used to store the cache in AppData\Roaming, and the installer // cleans up that version on upgrade. JC - // Again, try using wide-character getenv(). - wchar_t *LOCALAPPDATA = _wgetenv(L"LOCALAPPDATA"); + auto LOCALAPPDATA = LLStringUtil::getoptenv("LOCALAPPDATA"); if (LOCALAPPDATA) { - mOSCacheDir = ll_convert_wide_to_string(LOCALAPPDATA, CP_UTF8); + mOSCacheDir = *LOCALAPPDATA; } PRELOG("LOCALAPPDATA='" << mOSCacheDir << "'"); // Windows really does not deal well with pathnames containing non-ASCII @@ -155,7 +153,7 @@ LLDir_Win32::LLDir_Win32() if (SUCCEEDED(okay) && pwstr) { // But of course, only update mOSCacheDir if SHGetKnownFolderPath() works. - mOSCacheDir = ll_convert_wide_to_string(pwstr, CP_UTF8); + mOSCacheDir = ll_convert_wide_to_string(pwstr); // Update our environment so that child processes will see a // reasonable value as well. _wputenv_s(L"LOCALAPPDATA", pwstr); diff --git a/indra/llxml/tests/llcontrol_test.cpp b/indra/llxml/tests/llcontrol_test.cpp index 2b691ffbb1..f7e43d6def 100644 --- a/indra/llxml/tests/llcontrol_test.cpp +++ b/indra/llxml/tests/llcontrol_test.cpp @@ -27,43 +27,31 @@ #include "linden_common.h" #include "llsdserialize.h" +#include "llfile.h" +#include "stringize.h" #include "../llcontrol.h" #include "../test/lltut.h" +#include +#include namespace tut { - struct control_group { - LLControlGroup* mCG; + std::unique_ptr mCG; std::string mTestConfigDir; std::string mTestConfigFile; + std::vector mCleanups; static bool mListenerFired; control_group() { - mCG = new LLControlGroup("foo"); + mCG.reset(new LLControlGroup("foo")); LLUUID random; random.generate(); // generate temp dir - std::ostringstream oStr; - -#ifdef LL_WINDOWS - char* tmp_dir = getenv("TMP"); - if(tmp_dir) - { - oStr << tmp_dir << "/llcontrol-test-" << random << "/"; - } - else - { - oStr << "c:/tmp/llcontrol-test-" << random << "/"; - } -#else - oStr << "/tmp/llcontrol-test-" << random << "/"; -#endif - - mTestConfigDir = oStr.str(); + mTestConfigDir = STRINGIZE(LLFile::tmpdir() << "llcontrol-test-" << random << "/"); mTestConfigFile = mTestConfigDir + "settings.xml"; LLFile::mkdir(mTestConfigDir); LLSD config; @@ -76,7 +64,12 @@ namespace tut ~control_group() { //Remove test files - delete mCG; + for (auto filename : mCleanups) + { + LLFile::remove(filename); + } + LLFile::remove(mTestConfigFile); + LLFile::rmdir(mTestConfigDir); } void writeSettingsFile(const LLSD& config) { @@ -118,6 +111,7 @@ namespace tut ensure_equals("value of changed setting", mCG->getU32("TestSetting"), 13); LLControlGroup test_cg("foo2"); std::string temp_test_file = (mTestConfigDir + "setting_llsd_temp.xml"); + mCleanups.push_back(temp_test_file); mCG->saveToFile(temp_test_file.c_str(), TRUE); results = test_cg.loadFromFile(temp_test_file.c_str()); ensure("number of changed settings loaded", (results == 1)); @@ -139,6 +133,7 @@ namespace tut ensure_equals("value of changed setting", mCG->getU32("TestSetting"), 13); LLControlGroup test_cg("foo3"); std::string temp_test_file = (mTestConfigDir + "setting_llsd_persist_temp.xml"); + mCleanups.push_back(temp_test_file); mCG->saveToFile(temp_test_file.c_str(), TRUE); results = test_cg.loadFromFile(temp_test_file.c_str()); //If we haven't changed any settings, then we shouldn't have any settings to load @@ -153,7 +148,7 @@ namespace tut ensure("number of settings", (results == 1)); mCG->getControl("TestSetting")->getSignal()->connect(boost::bind(&this->handleListenerTest)); mCG->setU32("TestSetting", 13); - ensure("listener fired on changed setting", mListenerFired); + ensure("listener fired on changed setting", mListenerFired); } } diff --git a/indra/newview/llexternaleditor.cpp b/indra/newview/llexternaleditor.cpp index df9c848cb8..776bbf78c2 100644 --- a/indra/newview/llexternaleditor.cpp +++ b/indra/newview/llexternaleditor.cpp @@ -31,6 +31,7 @@ #include "llui.h" #include "llprocess.h" #include "llsdutil.h" +#include "llstring.h" #include // static @@ -188,12 +189,12 @@ std::string LLExternalEditor::findCommand( cmd = LLUI::sSettingGroups["config"]->getString(sSetting); LL_INFOS() << "Using setting" << LL_ENDL; } - else // otherwise use the path specified by the environment variable + else // otherwise use the path specified by the environment variable { - char* env_var_val = getenv(env_var.c_str()); + auto env_var_val(LLStringUtil::getoptenv(env_var)); if (env_var_val) { - cmd = env_var_val; + cmd = *env_var_val; LL_INFOS() << "Using env var " << env_var << LL_ENDL; } } diff --git a/indra/newview/llwebprofile.cpp b/indra/newview/llwebprofile.cpp index 81d4e30a7a..8dcef2c7cd 100644 --- a/indra/newview/llwebprofile.cpp +++ b/indra/newview/llwebprofile.cpp @@ -33,6 +33,7 @@ #include "llimagepng.h" #include "llsdserialize.h" +#include "llstring.h" // newview #include "llpanelprofile.h" // for getProfileURL(). FIXME: move the method to LLAvatarActions @@ -264,6 +265,5 @@ void LLWebProfile::reportImageUploadStatus(bool ok) std::string LLWebProfile::getAuthCookie() { // This is needed to test image uploads on Linux viewer built with OpenSSL 1.0.0 (0.9.8 works fine). - const char* debug_cookie = getenv("LL_SNAPSHOT_COOKIE"); - return debug_cookie ? debug_cookie : sAuthCookie; + return LLStringUtil::getenv("LL_SNAPSHOT_COOKIE", sAuthCookie); } -- cgit v1.3 From 3c53f8abded5da7e9743b743170538a1ede5635a Mon Sep 17 00:00:00 2001 From: Nat Goodspeed Date: Fri, 14 Dec 2018 16:00:09 -0500 Subject: SL-10153: VS 2013 isn't so fond of ?: involving std::string. --- indra/llcommon/llstring.h | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) (limited to 'indra/llcommon') diff --git a/indra/llcommon/llstring.h b/indra/llcommon/llstring.h index 87cb35c59c..8d2c8d79d7 100644 --- a/indra/llcommon/llstring.h +++ b/indra/llcommon/llstring.h @@ -1773,7 +1773,14 @@ template auto LLStringUtilBase::getenv(const std::string& key, const string_type& dflt) -> string_type { auto found{getoptenv(key)}; - return found? *found : dflt; + if (found) + { + return *found; + } + else + { + return dflt; + } } template -- cgit v1.3 From 4a136572857fcf5d5fd21789a777bbde67c1076d Mon Sep 17 00:00:00 2001 From: Nat Goodspeed Date: Sat, 15 Dec 2018 09:13:24 -0500 Subject: SL-10153: auto name{expression} declares an initializer_list instead of a variable of type decltype(expression). Using SHGetKnownFolderPath(FOLDERID_Fonts) in LLFontGL::getFontPathSystem() requires new Windows #include files. A variable with a constructor can't be declared within the braces of a switch statement, even outside any of its case clauses. --- indra/llcommon/llstring.h | 4 ++-- indra/llrender/llfontgl.cpp | 6 ++++++ indra/llvfs/lldir_win32.cpp | 6 +++--- 3 files changed, 11 insertions(+), 5 deletions(-) (limited to 'indra/llcommon') diff --git a/indra/llcommon/llstring.h b/indra/llcommon/llstring.h index 8d2c8d79d7..30bec3a6f8 100644 --- a/indra/llcommon/llstring.h +++ b/indra/llcommon/llstring.h @@ -1755,7 +1755,7 @@ bool LLStringUtilBase::endsWith( template auto LLStringUtilBase::getoptenv(const std::string& key) -> boost::optional { - auto found{llstring_getoptenv(key)}; + auto found(llstring_getoptenv(key)); if (found) { // return populated boost::optional @@ -1772,7 +1772,7 @@ auto LLStringUtilBase::getoptenv(const std::string& key) -> boost::optional auto LLStringUtilBase::getenv(const std::string& key, const string_type& dflt) -> string_type { - auto found{getoptenv(key)}; + auto found(getoptenv(key)); if (found) { return *found; diff --git a/indra/llrender/llfontgl.cpp b/indra/llrender/llfontgl.cpp index bb56988422..9b43680949 100644 --- a/indra/llrender/llfontgl.cpp +++ b/indra/llrender/llfontgl.cpp @@ -44,6 +44,12 @@ // Third party library includes #include +#if LL_WINDOWS +#include +#include +#include +#endif // LL_WINDOWS + const S32 BOLD_OFFSET = 1; // static class members diff --git a/indra/llvfs/lldir_win32.cpp b/indra/llvfs/lldir_win32.cpp index acf734f16b..b3b3afb37e 100644 --- a/indra/llvfs/lldir_win32.cpp +++ b/indra/llvfs/lldir_win32.cpp @@ -54,15 +54,15 @@ namespace void prelog(const std::string& message) { + boost::optional prelog_name; + switch (state) { - boost::optional prelog_name; - case prst::INIT: // assume we failed, until we succeed state = prst::SKIP; - prelog_name = LLDirUtil::getoptenv("PRELOG"); + prelog_name = LLStringUtil::getoptenv("PRELOG"); if (! prelog_name) // no PRELOG variable set, carry on return; -- cgit v1.3