From 4c31f60bba890e5c320c4bc6fd0ca1c5ce741830 Mon Sep 17 00:00:00 2001 From: Lynx Linden Date: Tue, 22 Jun 2010 18:33:39 +0100 Subject: EXT-7926 FIXED Fixed crash opening About for non-English locales. Calling std::locale("fr_FR.UTF-8") crashes on Linux and Mac. Or rather, it throws an exception when it doesn't know the locale and we didn't handle the exception. I now catch the exception and output an error rather than crash. Note, this happened because of change 703f3bcf7069, which made us actually pass a real locale string instead of just "C". So, we were never actually supporting a locale for LLStringUtil::formatNumber(). There is therefore an open task of making formatNumber() actually respect the locale. I'll report a separate JIRA to capture that task. --- indra/llcommon/llstring.cpp | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) (limited to 'indra/llcommon') diff --git a/indra/llcommon/llstring.cpp b/indra/llcommon/llstring.cpp index f14d947734..f5eb552d99 100644 --- a/indra/llcommon/llstring.cpp +++ b/indra/llcommon/llstring.cpp @@ -994,7 +994,14 @@ void LLStringUtil::formatNumber(std::string& numStr, std::string decimals) convertToS32 (decimals, intDecimals); if (!sLocale.empty()) { - strStream.imbue (std::locale(sLocale.c_str())); + // imbue() throws if the locale is unknown! (EXT-7926) + try + { + strStream.imbue(std::locale(sLocale.c_str())); + } catch (const std::exception &e) + { + LL_WARNS_ONCE("Locale") << "Cannot set locale to " << sLocale << LL_ENDL; + } } if (!intDecimals) -- cgit v1.3 From ccad528d5fb5889e9826ca045de5e7315be5942e Mon Sep 17 00:00:00 2001 From: Lynx Linden Date: Tue, 22 Jun 2010 18:55:04 +0100 Subject: EXT-7926 FIXED Minor typo correction. --- indra/llcommon/llstring.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'indra/llcommon') diff --git a/indra/llcommon/llstring.cpp b/indra/llcommon/llstring.cpp index f5eb552d99..ffdac5d411 100644 --- a/indra/llcommon/llstring.cpp +++ b/indra/llcommon/llstring.cpp @@ -994,7 +994,7 @@ void LLStringUtil::formatNumber(std::string& numStr, std::string decimals) convertToS32 (decimals, intDecimals); if (!sLocale.empty()) { - // imbue() throws if the locale is unknown! (EXT-7926) + // std::locale() throws if the locale is unknown! (EXT-7926) try { strStream.imbue(std::locale(sLocale.c_str())); -- cgit v1.3 From dfc20a824944d372c6978ca7b89289ec542554a9 Mon Sep 17 00:00:00 2001 From: Nat Goodspeed Date: Tue, 22 Jun 2010 14:59:34 -0400 Subject: EXT-7926: Remove unreferenced catch-clause variable (MSVC error). --- indra/llcommon/llstring.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'indra/llcommon') diff --git a/indra/llcommon/llstring.cpp b/indra/llcommon/llstring.cpp index ffdac5d411..1561bda201 100644 --- a/indra/llcommon/llstring.cpp +++ b/indra/llcommon/llstring.cpp @@ -998,7 +998,7 @@ void LLStringUtil::formatNumber(std::string& numStr, std::string decimals) try { strStream.imbue(std::locale(sLocale.c_str())); - } catch (const std::exception &e) + } catch (const std::exception &) { LL_WARNS_ONCE("Locale") << "Cannot set locale to " << sLocale << LL_ENDL; } -- cgit v1.3 From 87082996e6408919591ee3d408918a4425494dc9 Mon Sep 17 00:00:00 2001 From: "Andrew A. de Laix" Date: Tue, 22 Jun 2010 15:19:16 -0700 Subject: Revert to previous implementation of getNodeId. --- indra/llcommon/lluuid.cpp | 116 +++++++++++--------------------------- indra/newview/lllogininstance.cpp | 4 +- 2 files changed, 37 insertions(+), 83 deletions(-) (limited to 'indra/llcommon') diff --git a/indra/llcommon/lluuid.cpp b/indra/llcommon/lluuid.cpp index 583c1e589b..3bab01715a 100644 --- a/indra/llcommon/lluuid.cpp +++ b/indra/llcommon/lluuid.cpp @@ -456,101 +456,53 @@ static void get_random_bytes(void *buf, int nbytes) } #if LL_WINDOWS -// Code copied from http://msdn.microsoft.com/en-us/library/aa365939(VS.85).aspx -// This code grabs the first hardware address, rather than the first interface. -// Using a VPN can cause the first returned interface to be changed. - -const S32 MAC_ADDRESS_BYTES=6; +typedef struct _ASTAT_ +{ + ADAPTER_STATUS adapt; + NAME_BUFFER NameBuff [30]; +}ASTAT, * PASTAT; // static S32 LLUUID::getNodeID(unsigned char *node_id) { + ASTAT Adapter; + NCB Ncb; + UCHAR uRetCode; + LANA_ENUM lenum; + int i; + int retval = 0; - // Declare and initialize variables. - DWORD dwSize = 0; - DWORD dwRetVal = 0; - int i; - -/* variables used for GetIfTable and GetIfEntry */ - MIB_IFTABLE *pIfTable; - MIB_IFROW *pIfRow; + memset( &Ncb, 0, sizeof(Ncb) ); + Ncb.ncb_command = NCBENUM; + Ncb.ncb_buffer = (UCHAR *)&lenum; + Ncb.ncb_length = sizeof(lenum); + uRetCode = Netbios( &Ncb ); - // Allocate memory for our pointers. - pIfTable = (MIB_IFTABLE *) malloc(sizeof (MIB_IFTABLE)); - if (pIfTable == NULL) + for(i=0; i < lenum.length ;i++) { - printf("Error allocating memory needed to call GetIfTable\n"); - return 0; - } + memset( &Ncb, 0, sizeof(Ncb) ); + Ncb.ncb_command = NCBRESET; + Ncb.ncb_lana_num = lenum.lana[i]; - // Before calling GetIfEntry, we call GetIfTable to make - // sure there are entries to get and retrieve the interface index. + uRetCode = Netbios( &Ncb ); - // Make an initial call to GetIfTable to get the - // necessary size into dwSize - if (GetIfTable(pIfTable, &dwSize, 0) == ERROR_INSUFFICIENT_BUFFER) { - free(pIfTable); - pIfTable = (MIB_IFTABLE *) malloc(dwSize); - if (pIfTable == NULL) - { - printf("Error allocating memory\n"); - return 0; - } - } - // Make a second call to GetIfTable to get the actual - // data we want. - if ((dwRetVal = GetIfTable(pIfTable, &dwSize, 0)) == NO_ERROR) - { - if (pIfTable->dwNumEntries > 0) - { - pIfRow = (MIB_IFROW *) malloc(sizeof (MIB_IFROW)); - if (pIfRow == NULL) - { - printf("Error allocating memory\n"); - if (pIfTable != NULL) - { - free(pIfTable); - pIfTable = NULL; - } - return 0; - } + memset( &Ncb, 0, sizeof (Ncb) ); + Ncb.ncb_command = NCBASTAT; + Ncb.ncb_lana_num = lenum.lana[i]; - int limit = MAC_ADDRESS_BYTES; - memcpy(node_id, "\0\0\0\0\0\0", limit); // zero out array of bytes - for (i = 0; i < (int) pIfTable->dwNumEntries; i++) - { - pIfRow->dwIndex = pIfTable->table[i].dwIndex; - if ((dwRetVal = GetIfEntry(pIfRow)) == NO_ERROR) - { - switch (pIfRow->dwType) - { - case IF_TYPE_ETHERNET_CSMACD: - case IF_TYPE_IEEE80211: - limit = min((int) pIfRow->dwPhysAddrLen, limit); - if (pIfRow->dwPhysAddrLen == 0) - break; - memcpy(node_id, (UCHAR *)&pIfRow->bPhysAddr[0], limit); // just incase the PhysAddr is not the expected MAC_Address size - free(pIfTable); - return 1; //return first hardware device found. - break; - - case IF_TYPE_OTHER: - case IF_TYPE_PPP: - case IF_TYPE_SOFTWARE_LOOPBACK: - case IF_TYPE_ISO88025_TOKENRING: - case IF_TYPE_IEEE1394: - case IF_TYPE_ATM: - case IF_TYPE_TUNNEL: - default: - break; - } - } - } + strcpy( (char *)Ncb.ncb_callname, "* " ); /* Flawfinder: ignore */ + Ncb.ncb_buffer = (unsigned char *)&Adapter; + Ncb.ncb_length = sizeof(Adapter); + + uRetCode = Netbios( &Ncb ); + if ( uRetCode == 0 ) + { + memcpy(node_id,Adapter.adapt.adapter_address,6); /* Flawfinder: ignore */ + retval = 1; } } - free(pIfTable); - return 0; + return retval; } #elif LL_DARWIN diff --git a/indra/newview/lllogininstance.cpp b/indra/newview/lllogininstance.cpp index 71604291e1..06f490e8e3 100644 --- a/indra/newview/lllogininstance.cpp +++ b/indra/newview/lllogininstance.cpp @@ -168,7 +168,9 @@ void LLLoginInstance::constructAuthParams(LLPointer user_credentia char hashed_mac_string[MD5HEX_STR_SIZE]; /* Flawfinder: ignore */ LLMD5 hashed_mac; unsigned char MACAddress[MAC_ADDRESS_BYTES]; - LLUUID::getNodeID(MACAddress); + if(LLUUID::getNodeID(MACAddress) == 0) { + llerrs << "Failed to get node id; cannot uniquely identify this machine." << llendl; + } hashed_mac.update( MACAddress, MAC_ADDRESS_BYTES ); hashed_mac.finalize(); hashed_mac.hex_digest(hashed_mac_string); -- cgit v1.3 From 1ec7de1b5760b5fc1ebda1d244784e3bc4596eb1 Mon Sep 17 00:00:00 2001 From: "Andrew A. de Laix" Date: Tue, 29 Jun 2010 14:51:26 -0700 Subject: Generate windows minidump files on crash for developer (not release for download) builds. SL crash reporter still enabled. --- indra/llcommon/llapp.cpp | 4 + indra/newview/CMakeLists.txt | 2 + indra/newview/llappviewer.cpp | 2 +- indra/newview/llappviewerwin32.cpp | 8 ++ indra/newview/llwindebug.cpp | 188 +++++++++++++++++++++++++++++++++++++ indra/newview/llwindebug.h | 49 ++++++++++ 6 files changed, 252 insertions(+), 1 deletion(-) create mode 100644 indra/newview/llwindebug.cpp create mode 100644 indra/newview/llwindebug.h (limited to 'indra/llcommon') diff --git a/indra/llcommon/llapp.cpp b/indra/llcommon/llapp.cpp index 0447ca93f5..8f2fe6c26e 100644 --- a/indra/llcommon/llapp.cpp +++ b/indra/llcommon/llapp.cpp @@ -920,6 +920,10 @@ bool windows_post_minidump_callback(const wchar_t* dump_path, ms_sleep(10); } +#ifndef LL_RELEASE_FOR_DOWNLOAD + return false; +#else return true; +#endif } #endif diff --git a/indra/newview/CMakeLists.txt b/indra/newview/CMakeLists.txt index ce42cb6038..92f701551b 100644 --- a/indra/newview/CMakeLists.txt +++ b/indra/newview/CMakeLists.txt @@ -1150,10 +1150,12 @@ endif (LINUX) if (WINDOWS) list(APPEND viewer_SOURCE_FILES llappviewerwin32.cpp + llwindebug.cpp ) list(APPEND viewer_HEADER_FILES llappviewerwin32.h + llwindebug.h ) # precompiled header configuration diff --git a/indra/newview/llappviewer.cpp b/indra/newview/llappviewer.cpp index 1ed63555b0..1b5b73e3dd 100644 --- a/indra/newview/llappviewer.cpp +++ b/indra/newview/llappviewer.cpp @@ -4133,7 +4133,7 @@ void LLAppViewer::forceErrorBreakpoint() void LLAppViewer::forceErrorBadMemoryAccess() { S32* crash = NULL; - *crash = 0xDEADBEEF; + *crash = 0xDEADBEEF; return; } diff --git a/indra/newview/llappviewerwin32.cpp b/indra/newview/llappviewerwin32.cpp index e3ef04d03d..8c9fd09dcb 100644 --- a/indra/newview/llappviewerwin32.cpp +++ b/indra/newview/llappviewerwin32.cpp @@ -64,6 +64,10 @@ #include "llcommandlineparser.h" #include "lltrans.h" +#ifndef LL_RELEASE_FOR_DOWNLOAD +#include "llwindebug.h" +#endif + // *FIX:Mani - This hack is to fix a linker issue with libndofdev.lib // The lib was compiled under VS2005 - in VS2003 we need to remap assert #ifdef LL_DEBUG @@ -342,6 +346,10 @@ bool LLAppViewerWin32::init() llinfos << "Turning off Windows error reporting." << llendl; disableWinErrorReporting(); +#ifndef LL_RELEASE_FOR_DOWNLOAD + LLWinDebug::instance().init(); +#endif + return LLAppViewer::init(); } diff --git a/indra/newview/llwindebug.cpp b/indra/newview/llwindebug.cpp new file mode 100644 index 0000000000..ba33a56ad0 --- /dev/null +++ b/indra/newview/llwindebug.cpp @@ -0,0 +1,188 @@ +/** + * @file llwindebug.cpp + * @brief Windows debugging functions + * + * $LicenseInfo:firstyear=2004&license=viewergpl$ + * + * Copyright (c) 2004-2009, Linden Research, Inc. + * + * Second Life Viewer Source Code + * The source code in this file ("Source Code") is provided by Linden Lab + * to you under the terms of the GNU General Public License, version 2.0 + * ("GPL"), unless you have obtained a separate licensing agreement + * ("Other License"), formally executed by you and Linden Lab. Terms of + * the GPL can be found in doc/GPL-license.txt in this distribution, or + * online at http://secondlifegrid.net/programs/open_source/licensing/gplv2 + * + * There are special exceptions to the terms and conditions of the GPL as + * it is applied to this Source Code. View the full text of the exception + * in the file doc/FLOSS-exception.txt in this software distribution, or + * online at + * http://secondlifegrid.net/programs/open_source/licensing/flossexception + * + * By copying, modifying or distributing this software, you acknowledge + * that you have read and understood your obligations described above, + * and agree to abide by those obligations. + * + * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO + * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY, + * COMPLETENESS OR PERFORMANCE. + * $/LicenseInfo$ + */ +#include "llviewerprecompiledheaders.h" + +#include "llwindebug.h" +#include "lldir.h" + + +// based on dbghelp.h +typedef BOOL (WINAPI *MINIDUMPWRITEDUMP)(HANDLE hProcess, DWORD dwPid, HANDLE hFile, MINIDUMP_TYPE DumpType, + CONST PMINIDUMP_EXCEPTION_INFORMATION ExceptionParam, + CONST PMINIDUMP_USER_STREAM_INFORMATION UserStreamParam, + CONST PMINIDUMP_CALLBACK_INFORMATION CallbackParam + ); + +MINIDUMPWRITEDUMP f_mdwp = NULL; + + +class LLMemoryReserve { +public: + LLMemoryReserve(); + ~LLMemoryReserve(); + void reserve(); + void release(); +protected: + unsigned char *mReserve; + static const size_t MEMORY_RESERVATION_SIZE; +}; + +LLMemoryReserve::LLMemoryReserve() : + mReserve(NULL) +{ +}; + +LLMemoryReserve::~LLMemoryReserve() +{ + release(); +} + +// I dunno - this just seemed like a pretty good value. +const size_t LLMemoryReserve::MEMORY_RESERVATION_SIZE = 5 * 1024 * 1024; + +void LLMemoryReserve::reserve() +{ + if(NULL == mReserve) + mReserve = new unsigned char[MEMORY_RESERVATION_SIZE]; +}; + +void LLMemoryReserve::release() +{ + delete [] mReserve; + mReserve = NULL; +}; + +static LLMemoryReserve gEmergencyMemoryReserve; + + +LONG NTAPI vectoredHandler(PEXCEPTION_POINTERS exception_infop) +{ + LLWinDebug::instance().generateMinidump(exception_infop); + return EXCEPTION_CONTINUE_SEARCH; +} + +// static +void LLWinDebug::init() +{ + static bool s_first_run = true; + // Load the dbghelp dll now, instead of waiting for the crash. + // Less potential for stack mangling + + if (s_first_run) + { + // First, try loading from the directory that the app resides in. + std::string local_dll_name = gDirUtilp->findFile("dbghelp.dll", gDirUtilp->getWorkingDir(), gDirUtilp->getExecutableDir()); + + HMODULE hDll = NULL; + hDll = LoadLibraryA(local_dll_name.c_str()); + if (!hDll) + { + hDll = LoadLibrary(L"dbghelp.dll"); + } + + if (!hDll) + { + LL_WARNS("AppInit") << "Couldn't find dbghelp.dll!" << LL_ENDL; + } + else + { + f_mdwp = (MINIDUMPWRITEDUMP) GetProcAddress(hDll, "MiniDumpWriteDump"); + + if (!f_mdwp) + { + FreeLibrary(hDll); + hDll = NULL; + } + } + + gEmergencyMemoryReserve.reserve(); + + s_first_run = false; + + // Add this exeption hanlder to save windows style minidump. + AddVectoredExceptionHandler(0, &vectoredHandler); + } +} + +void LLWinDebug::writeDumpToFile(MINIDUMP_TYPE type, MINIDUMP_EXCEPTION_INFORMATION *ExInfop, const std::string& filename) +{ + if(f_mdwp == NULL || gDirUtilp == NULL) + { + return; + } + else + { + std::string dump_path = gDirUtilp->getExpandedFilename(LL_PATH_LOGS, filename); + + HANDLE hFile = CreateFileA(dump_path.c_str(), + GENERIC_WRITE, + FILE_SHARE_WRITE, + NULL, + CREATE_ALWAYS, + FILE_ATTRIBUTE_NORMAL, + NULL); + + if (hFile != INVALID_HANDLE_VALUE) + { + // Write the dump, ignoring the return value + f_mdwp(GetCurrentProcess(), + GetCurrentProcessId(), + hFile, + type, + ExInfop, + NULL, + NULL); + + CloseHandle(hFile); + } + + } +} + +// static +void LLWinDebug::generateMinidump(struct _EXCEPTION_POINTERS *exception_infop) +{ + std::string dump_path = gDirUtilp->getExpandedFilename(LL_PATH_LOGS, + "SecondLifeException"); + if (exception_infop) + { + // Since there is exception info... Release the hounds. + gEmergencyMemoryReserve.release(); + + _MINIDUMP_EXCEPTION_INFORMATION ExInfo; + + ExInfo.ThreadId = ::GetCurrentThreadId(); + ExInfo.ExceptionPointers = exception_infop; + ExInfo.ClientPointers = NULL; + writeDumpToFile((MINIDUMP_TYPE)(MiniDumpWithDataSegs | MiniDumpWithIndirectlyReferencedMemory), &ExInfo, "SecondLife.dmp"); + } +} diff --git a/indra/newview/llwindebug.h b/indra/newview/llwindebug.h new file mode 100644 index 0000000000..809d1b8cc3 --- /dev/null +++ b/indra/newview/llwindebug.h @@ -0,0 +1,49 @@ +/** + * @file llwindebug.h + * @brief LLWinDebug class header file + * + * $LicenseInfo:firstyear=2004&license=viewergpl$ + * + * Copyright (c) 2004-2009, Linden Research, Inc. + * + * Second Life Viewer Source Code + * The source code in this file ("Source Code") is provided by Linden Lab + * to you under the terms of the GNU General Public License, version 2.0 + * ("GPL"), unless you have obtained a separate licensing agreement + * ("Other License"), formally executed by you and Linden Lab. Terms of + * the GPL can be found in doc/GPL-license.txt in this distribution, or + * online at http://secondlifegrid.net/programs/open_source/licensing/gplv2 + * + * There are special exceptions to the terms and conditions of the GPL as + * it is applied to this Source Code. View the full text of the exception + * in the file doc/FLOSS-exception.txt in this software distribution, or + * online at + * http://secondlifegrid.net/programs/open_source/licensing/flossexception + * + * By copying, modifying or distributing this software, you acknowledge + * that you have read and understood your obligations described above, + * and agree to abide by those obligations. + * + * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO + * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY, + * COMPLETENESS OR PERFORMANCE. + * $/LicenseInfo$ + */ + +#ifndef LL_LLWINDEBUG_H +#define LL_LLWINDEBUG_H + +#include "stdtypes.h" +#include + +class LLWinDebug: + public LLSingleton +{ +public: + static void init(); + static void generateMinidump(struct _EXCEPTION_POINTERS *pExceptionInfo = NULL); +private: + static void writeDumpToFile(MINIDUMP_TYPE type, MINIDUMP_EXCEPTION_INFORMATION *ExInfop, const std::string& filename); +}; + +#endif // LL_LLWINDEBUG_H -- cgit v1.3 From 8d6fec5cc10f11a7de0c749ca700d6d1b5a4099a Mon Sep 17 00:00:00 2001 From: "Andrew A. de Laix" Date: Tue, 29 Jun 2010 15:51:17 -0700 Subject: For developer Nix builds, default handle signal after crash report. Linux should generate a core dump; Darwin a mac crash report. --- indra/llcommon/llapp.cpp | 6 ++++++ 1 file changed, 6 insertions(+) (limited to 'indra/llcommon') diff --git a/indra/llcommon/llapp.cpp b/indra/llcommon/llapp.cpp index 8f2fe6c26e..be3b18d9c8 100644 --- a/indra/llcommon/llapp.cpp +++ b/indra/llcommon/llapp.cpp @@ -863,7 +863,13 @@ bool unix_post_minidump_callback(const char *dump_dir, llinfos << "generated minidump: " << LLApp::instance()->getMiniDumpFilename() << llendl; LLApp::runErrorHandler(); + +#ifndef LL_RELEASE_FOR_DOWNLOAD + clear_signals(); + return false; +#else return true; +#endif } #endif // !WINDOWS -- cgit v1.3