diff options
| -rw-r--r-- | indra/newview/CMakeLists.txt | 3 | ||||
| -rw-r--r-- | indra/newview/llappviewer.cpp | 5 | ||||
| -rw-r--r-- | indra/newview/llappviewerwin32.cpp | 55 | ||||
| -rw-r--r-- | indra/newview/llstartup.cpp | 1 | ||||
| -rw-r--r-- | indra/newview/llviewermessage.cpp | 4 | ||||
| -rw-r--r-- | indra/newview/llwindebug.cpp | 906 | ||||
| -rw-r--r-- | indra/newview/llwindebug.h | 75 | 
7 files changed, 0 insertions, 1049 deletions
diff --git a/indra/newview/CMakeLists.txt b/indra/newview/CMakeLists.txt index f2bed843c9..4571aa1074 100644 --- a/indra/newview/CMakeLists.txt +++ b/indra/newview/CMakeLists.txt @@ -1055,7 +1055,6 @@ set(viewer_HEADER_FILES      llwearabletype.h      llweb.h      llwind.h -    llwindebug.h      llwlanimator.h      llwldaycycle.h      llwlparammanager.h @@ -1130,12 +1129,10 @@ 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 56486c788b..e9ec0b8b77 100644 --- a/indra/newview/llappviewer.cpp +++ b/indra/newview/llappviewer.cpp @@ -104,7 +104,6 @@  #include <boost/bind.hpp>  #if LL_WINDOWS -	#include "llwindebug.h"  #	include <share.h> // For _SH_DENYWR in initMarkerFile  #else  #   include <sys/file.h> // For initMarkerFile support @@ -3288,10 +3287,6 @@ void LLAppViewer::badNetworkHandler()  	mPurgeOnExit = TRUE; -#if LL_WINDOWS -	// Generates the minidump. -	LLWinDebug::generateCrashStacks(NULL); -#endif  	LLAppViewer::handleSyncViewerCrash();  	LLAppViewer::handleViewerCrash(); diff --git a/indra/newview/llappviewerwin32.cpp b/indra/newview/llappviewerwin32.cpp index 4bee8d9ac5..88d8dba8af 100644 --- a/indra/newview/llappviewerwin32.cpp +++ b/indra/newview/llappviewerwin32.cpp @@ -57,8 +57,6 @@  #include "llweb.h"  #include "llsecondlifeurls.h" -#include "llwindebug.h" -  #include "llviewernetwork.h"  #include "llmd5.h"  #include "llfindlocale.h" @@ -81,51 +79,6 @@ extern "C" {  const std::string LLAppViewerWin32::sWindowClass = "Second Life"; -LONG WINAPI viewer_windows_exception_handler(struct _EXCEPTION_POINTERS *exception_infop) -{ -    // *NOTE:Mani - this code is stolen from LLApp, where its never actually used. -	//OSMessageBox("Attach Debugger Now", "Error", OSMB_OK); -    // *TODO: Translate the signals/exceptions into cross-platform stuff -	// Windows implementation -    _tprintf( _T("Entering Windows Exception Handler...\n") ); -	llinfos << "Entering Windows Exception Handler..." << llendl; - -	// Make sure the user sees something to indicate that the app crashed. -	LONG retval; - -	if (LLApp::isError()) -	{ -	    _tprintf( _T("Got another fatal signal while in the error handler, die now!\n") ); -		llwarns << "Got another fatal signal while in the error handler, die now!" << llendl; - -		retval = EXCEPTION_EXECUTE_HANDLER; -		return retval; -	} - -	// Generate a minidump if we can. -	// Before we wake the error thread... -	// Which will start the crash reporting. -	LLWinDebug::generateCrashStacks(exception_infop); -	 -	// Flag status to error, so thread_error starts its work -	LLApp::setError(); - -	// Block in the exception handler until the app has stopped -	// This is pretty sketchy, but appears to work just fine -	while (!LLApp::isStopped()) -	{ -		ms_sleep(10); -	} - -	// -	// At this point, we always want to exit the app.  There's no graceful -	// recovery for an unhandled exception. -	//  -	// Just kill the process. -	retval = EXCEPTION_EXECUTE_HANDLER;	 -	return retval; -} -  // Create app mutex creates a unique global windows object.   // If the object can be created it returns true, otherwise  // it returns false. The false result can be used to determine  @@ -191,8 +144,6 @@ int APIENTRY WINMAIN(HINSTANCE hInstance,  	gIconResource = MAKEINTRESOURCE(IDI_LL_ICON);  	LLAppViewerWin32* viewer_app_ptr = new LLAppViewerWin32(lpCmdLine); - -	LLWinDebug::initExceptionHandler(viewer_windows_exception_handler);   	viewer_app_ptr->setErrorHandler(LLAppViewer::handleViewerCrash); @@ -405,12 +356,6 @@ bool LLAppViewerWin32::cleanup()  bool LLAppViewerWin32::initLogging()  { -	// Remove the crash stack log from previous executions. -	// Since we've started logging a new instance of the app, we can assume  -	// *NOTE: This should happen before the we send a 'previous instance froze' -	// crash report, but it must happen after we initialize the DirUtil. -	LLWinDebug::clearCrashStacks(); -  	return LLAppViewer::initLogging();  } diff --git a/indra/newview/llstartup.cpp b/indra/newview/llstartup.cpp index a84bb98a90..e43b3b84c8 100644 --- a/indra/newview/llstartup.cpp +++ b/indra/newview/llstartup.cpp @@ -199,7 +199,6 @@  #include "llstartuplistener.h"  #if LL_WINDOWS -#include "llwindebug.h"  #include "lldxhardware.h"  #endif diff --git a/indra/newview/llviewermessage.cpp b/indra/newview/llviewermessage.cpp index fb87e2d3b9..c677406223 100644 --- a/indra/newview/llviewermessage.cpp +++ b/indra/newview/llviewermessage.cpp @@ -110,10 +110,6 @@  #include <boost/algorithm/string/split.hpp> //  #include <boost/regex.hpp> -#if LL_WINDOWS // For Windows specific error handler -#include "llwindebug.h"	// For the invalid message handler -#endif -  #include "llnotificationmanager.h" //  #if LL_MSVC diff --git a/indra/newview/llwindebug.cpp b/indra/newview/llwindebug.cpp deleted file mode 100644 index 9f8585f163..0000000000 --- a/indra/newview/llwindebug.cpp +++ /dev/null @@ -1,906 +0,0 @@ -/**  - * @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 <tchar.h> -#include <tlhelp32.h> -#include "llwindebug.h" -#include "llviewercontrol.h" -#include "lldir.h" -#include "llsd.h" -#include "llsdserialize.h" - -#pragma warning(disable: 4200)	//nonstandard extension used : zero-sized array in struct/union -#pragma warning(disable: 4100)	//unreferenced formal parameter - - -/* -LLSD Block for Windows Dump Information -<llsd> -  <map> -    <key>Platform</key> -    <string></string> -    <key>Process</key> -    <string></string> -    <key>Module</key> -    <string></string> -    <key>DateModified</key> -    <string></string> -    <key>ExceptionCode</key> -    <string></string> -    <key>ExceptionRead/WriteAddress</key> -    <string></string> -    <key>Instruction</key> -    <string></string> -    <key>Registers</key> -    <map> -      <!-- Continued for all registers --> -      <key>EIP</key> -      <string>...</string> -      <!-- ... --> -    </map> -    <key>Call Stack</key> -    <array> -      <!-- One map per stack frame --> -      <map> -	<key>ModuleName</key> -	<string></string> -	<key>ModuleBaseAddress</key> -	<string></string> -	<key>ModuleOffsetAddress</key> -	<string></string> -	<key>Parameters</key> -	<array> -	  <string></string> -	</array> -      </map> -      <!-- ... --> -    </array> -  </map> -</llsd> - -*/ - - -extern void (*gCrashCallback)(void); - -// 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; - -#undef UNICODE - -static LPTOP_LEVEL_EXCEPTION_FILTER gFilterFunc = NULL; - -HMODULE	hDbgHelp; - -// Tool Help functions. -typedef	HANDLE (WINAPI * CREATE_TOOL_HELP32_SNAPSHOT)(DWORD dwFlags, DWORD th32ProcessID); -typedef	BOOL (WINAPI * MODULE32_FIRST)(HANDLE hSnapshot, LPMODULEENTRY32 lpme); -typedef	BOOL (WINAPI * MODULE32_NEST)(HANDLE hSnapshot, LPMODULEENTRY32 lpme); - -CREATE_TOOL_HELP32_SNAPSHOT	CreateToolhelp32Snapshot_; -MODULE32_FIRST	Module32First_; -MODULE32_NEST	Module32Next_; - -#define	DUMP_SIZE_MAX	8000	//max size of our dump -#define	CALL_TRACE_MAX	((DUMP_SIZE_MAX - 2000) / (MAX_PATH + 40))	//max number of traced calls -#define	NL				L"\r\n"	//new line - - -typedef struct STACK -{ -	STACK *	Ebp; -	PBYTE	Ret_Addr; -	DWORD	Param[0]; -} STACK, * PSTACK; - -BOOL WINAPI Get_Module_By_Ret_Addr(PBYTE Ret_Addr, LPWSTR Module_Name, PBYTE & Module_Addr); -void WINAPI Get_Call_Stack(const EXCEPTION_RECORD* exception_record,  -						   const CONTEXT* context_record,  -						   LLSD& info); - -void printError( CHAR* msg ) -{ -  DWORD eNum; -  TCHAR sysMsg[256]; -  TCHAR* p; - -  eNum = GetLastError( ); -  FormatMessage( FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS, -         NULL, eNum, -         MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), // Default language -         sysMsg, 256, NULL ); - -  // Trim the end of the line and terminate it with a null -  p = sysMsg; -  while( ( *p > 31 ) || ( *p == 9 ) ) -    ++p; -  do { *p-- = 0; } while( ( p >= sysMsg ) && -                          ( ( *p == '.' ) || ( *p < 33 ) ) ); - -  // Display the message -  printf( "\n  WARNING: %s failed with error %d (%s)", msg, eNum, sysMsg ); -} - -BOOL GetProcessThreadIDs(DWORD process_id, std::vector<DWORD>& thread_ids)  -{  -  HANDLE hThreadSnap = INVALID_HANDLE_VALUE;  -  THREADENTRY32 te32;  -  -  // Take a snapshot of all running threads   -  hThreadSnap = CreateToolhelp32Snapshot( TH32CS_SNAPTHREAD, 0 );  -  if( hThreadSnap == INVALID_HANDLE_VALUE )  -    return( FALSE );  -  -  // Fill in the size of the structure before using it.  -  te32.dwSize = sizeof(THREADENTRY32 );  -  -  // Retrieve information about the first thread, -  // and exit if unsuccessful -  if( !Thread32First( hThreadSnap, &te32 ) )  -  { -    printError( "Thread32First" );  // Show cause of failure -    CloseHandle( hThreadSnap );     // Must clean up the snapshot object! -    return( FALSE ); -  } - -  // Now walk the thread list of the system, -  // and display information about each thread -  // associated with the specified process -  do  -  {  -    if( te32.th32OwnerProcessID == process_id ) -    { -      thread_ids.push_back(te32.th32ThreadID);  -    } -  } while( Thread32Next(hThreadSnap, &te32 ) );  - -//  Don't forget to clean up the snapshot object. -  CloseHandle( hThreadSnap ); -  return( TRUE ); -} - -BOOL GetThreadCallStack(DWORD thread_id, LLSD& info) -{ -    if(GetCurrentThreadId() == thread_id) -    { -        // Early exit for the current thread. -        // Suspending the current thread would be a bad idea. -        // Plus you can't retrieve a valid current thread context. -        return false; -    } - -    HANDLE thread_handle = INVALID_HANDLE_VALUE;  -    thread_handle = OpenThread(THREAD_ALL_ACCESS, FALSE, thread_id); -    if(INVALID_HANDLE_VALUE == thread_handle) -    { -        return FALSE; -    } - -    BOOL result = false; -    if(-1 != SuspendThread(thread_handle)) -    { -        CONTEXT context_struct; -        context_struct.ContextFlags = CONTEXT_FULL; -        if(GetThreadContext(thread_handle, &context_struct)) -        { -            Get_Call_Stack(NULL, &context_struct, info); -            result = true; -        } -        ResumeThread(thread_handle); -    } -    else -    { -        // Couldn't suspend thread. -    } - -    CloseHandle(thread_handle); -    return result; -} - - -//Windows Call Stack Construction idea from  -//http://www.codeproject.com/tools/minidump.asp - -//**************************************************************************************** -BOOL WINAPI Get_Module_By_Ret_Addr(PBYTE Ret_Addr, LPWSTR Module_Name, PBYTE & Module_Addr) -//**************************************************************************************** -// Find module by Ret_Addr (address in the module). -// Return Module_Name (full path) and Module_Addr (start address). -// Return TRUE if found. -{ -	MODULEENTRY32	M = {sizeof(M)}; -	HANDLE	hSnapshot; - -	bool found = false; -	 -	if (CreateToolhelp32Snapshot_) -	{ -		hSnapshot = CreateToolhelp32Snapshot_(TH32CS_SNAPMODULE, 0); -		 -		if ((hSnapshot != INVALID_HANDLE_VALUE) && -			Module32First_(hSnapshot, &M)) -		{ -			do -			{ -				if (DWORD(Ret_Addr - M.modBaseAddr) < M.modBaseSize) -				{ -					lstrcpyn(Module_Name, M.szExePath, MAX_PATH); -					Module_Addr = M.modBaseAddr; -					found = true; -					break; -				} -			} while (Module32Next_(hSnapshot, &M)); -		} - -		CloseHandle(hSnapshot); -	} - -	return found; -} //Get_Module_By_Ret_Addr - -bool has_valid_call_before(PDWORD cur_stack_loc) -{ -	PBYTE p_first_byte = (PBYTE)(*cur_stack_loc - 1); -	PBYTE p_second_byte = (PBYTE)(*cur_stack_loc -2); -	PBYTE p_fifth_byte = (PBYTE)(*cur_stack_loc - 5); -	PBYTE p_sixth_byte = (PBYTE)(*cur_stack_loc - 6); - -	// make sure we can read it -	if(IsBadReadPtr(p_sixth_byte, 6 * sizeof(BYTE))) -	{ -		return false; -	} - -	// check for 9a + 4 bytes -	if(*p_fifth_byte == 0x9A) -	{ -		return true; -	} - -	// Check for E8 + 4 bytes and last byte is 00 or FF -	if(*p_fifth_byte == 0xE8 && (*p_first_byte == 0x00 || *p_first_byte == 0xFF)) -	{ -		return true; -	} -	 -	// the other is six bytes -	if(*p_sixth_byte == 0xFF || *p_second_byte == 0xFF) -	{ -		return true; -	} - -	return false; -} - -PBYTE get_valid_frame(PBYTE esp) -{ -	PDWORD cur_stack_loc = NULL; -	const int max_search = 400; -	WCHAR	module_name[MAX_PATH]; -	PBYTE	module_addr = 0; - -	// round to highest multiple of four -	esp = (esp + (4 - ((int)esp % 4)) % 4); - -	// scroll through stack a few hundred places. -	for (cur_stack_loc = (PDWORD) esp; cur_stack_loc < (PDWORD)esp + max_search; cur_stack_loc += 1) -	{ -		// if you can read the pointer, -		if (IsBadReadPtr(cur_stack_loc, sizeof(PDWORD))) -		{ -			continue; -		} - -		//  check if it's in a module -		if (!Get_Module_By_Ret_Addr((PBYTE)*cur_stack_loc, module_name, module_addr)) -		{ -			continue; -		} - -		// check if the code before the instruction ptr is a call  -		if(!has_valid_call_before(cur_stack_loc)) -		{ -			continue; -		} -		 -		// if these all pass, return that ebp, otherwise continue till we're dead -		return (PBYTE)(cur_stack_loc - 1); -	} - -	return NULL; -} - -bool shouldUseStackWalker(PSTACK Ebp, int max_depth) -{ -	WCHAR	Module_Name[MAX_PATH]; -	PBYTE	Module_Addr = 0; -	int depth = 0; - -	while (depth < max_depth)  -	{ -		if (IsBadReadPtr(Ebp, sizeof(PSTACK)) ||  -			IsBadReadPtr(Ebp->Ebp, sizeof(PSTACK)) || -			Ebp->Ebp < Ebp || -			Ebp->Ebp - Ebp > 0xFFFFFF || -			IsBadCodePtr(FARPROC(Ebp->Ebp->Ret_Addr)) || -			!Get_Module_By_Ret_Addr(Ebp->Ebp->Ret_Addr, Module_Name, Module_Addr)) -		{ -			return true; -		} -		depth++; -		Ebp = Ebp->Ebp; -	} - -	return false; -} - -//****************************************************************** -void WINAPI Get_Call_Stack(const EXCEPTION_RECORD* exception_record,  -						   const CONTEXT* context_record,  -						   LLSD& info) -//****************************************************************** -// Fill Str with call stack info. -// pException can be either GetExceptionInformation() or NULL. -// If pException = NULL - get current call stack. -{ -	LPWSTR	Module_Name = new WCHAR[MAX_PATH]; -	PBYTE	Module_Addr = 0; -	LLSD params; -	PBYTE	Esp = NULL; -	LLSD tmp_info; - -	bool fake_frame = false; -	bool ebp_used = false; -	const int HEURISTIC_MAX_WALK = 20; -	int heuristic_walk_i = 0; -	int Ret_Addr_I = 0; - -	STACK	Stack = {0, 0}; -	PSTACK	Ebp; - -	if (exception_record && context_record)		//fake frame for exception address -	{ -		Stack.Ebp = (PSTACK)(context_record->Ebp); -		Stack.Ret_Addr = (PBYTE)exception_record->ExceptionAddress; -		Ebp = &Stack; -		Esp = (PBYTE) context_record->Esp; -		fake_frame = true; -	} -	else if(context_record) -	{ -        Ebp = (PSTACK)(context_record->Ebp); -		Esp = (PBYTE)(context_record->Esp); -	} -	else -	{ -		Ebp = (PSTACK)&exception_record - 1;	//frame addr of Get_Call_Stack() -		Esp = (PBYTE)&exception_record; - -		// Skip frame of Get_Call_Stack(). -		if (!IsBadReadPtr(Ebp, sizeof(PSTACK))) -			Ebp = Ebp->Ebp;		//caller ebp -	} - -	// Trace CALL_TRACE_MAX calls maximum - not to exceed DUMP_SIZE_MAX. -	// Break trace on wrong stack frame. -	for (Ret_Addr_I = 0; -		heuristic_walk_i < HEURISTIC_MAX_WALK &&  -		Ret_Addr_I < CALL_TRACE_MAX && !IsBadReadPtr(Ebp, sizeof(PSTACK)) && !IsBadCodePtr(FARPROC(Ebp->Ret_Addr)); -		Ret_Addr_I++) -	{ -		// If module with Ebp->Ret_Addr found. -		if (Get_Module_By_Ret_Addr(Ebp->Ret_Addr, Module_Name, Module_Addr)) -		{ -			// Save module's address and full path. -			tmp_info["CallStack"][Ret_Addr_I]["ModuleName"] = ll_convert_wide_to_string(Module_Name); -			tmp_info["CallStack"][Ret_Addr_I]["ModuleAddress"] = (int)Module_Addr; -			tmp_info["CallStack"][Ret_Addr_I]["CallOffset"] = (int)(Ebp->Ret_Addr - Module_Addr); - -			// Save 5 params of the call. We don't know the real number of params. -			if (fake_frame && !Ret_Addr_I)	//fake frame for exception address -				params[0] = "Exception Offset"; -			else if (!IsBadReadPtr(Ebp, sizeof(PSTACK) + 5 * sizeof(DWORD))) -			{ -				for(int j = 0; j < 5; ++j) -				{ -					params[j] = (int)Ebp->Param[j]; -				} -			} -			tmp_info["CallStack"][Ret_Addr_I]["Parameters"] = params; -		} - -		tmp_info["CallStack"][Ret_Addr_I]["ReturnAddress"] = (int)Ebp->Ret_Addr; - -		// get ready for next frame -		// Set ESP to just after return address.  Not the real esp, but just enough after the return address -		if(!fake_frame) { -			Esp = (PBYTE)Ebp + 8; -		}  -		else -		{ -			fake_frame = false; -		} - -		// is next ebp valid? -		// only run if we've never found a good ebp -		// and make sure the one after is valid as well -		if(	!ebp_used &&  -			shouldUseStackWalker(Ebp, 2)) -		{ -			heuristic_walk_i++; -			PBYTE new_ebp = get_valid_frame(Esp); -			if (new_ebp != NULL) -			{ -				Ebp = (PSTACK)new_ebp; -			} -		} -		else -		{ -			ebp_used = true; -			Ebp = Ebp->Ebp; -		} -	} -/* TODO remove or turn this code back on to edit the stack after i see a few raw ones. -Palmer -	// Now go back through and edit out heuristic stacks that could very well be bogus. -	// Leave the top and the last 3 stack chosen by the heuristic, however. -	if(heuristic_walk_i > 2) -	{ -		info["CallStack"][0] = tmp_info["CallStack"][0]; -		std::string ttest = info["CallStack"][0]["ModuleName"]; -		for(int cur_frame = 1;  -			(cur_frame + heuristic_walk_i - 2 < Ret_Addr_I);  -			++cur_frame) -		{ -			// edit out the middle heuristic found frames -			info["CallStack"][cur_frame] = tmp_info["CallStack"][cur_frame + heuristic_walk_i - 2]; -		} -	} -	else -	{ -		info = tmp_info; -	} -*/ -	info = tmp_info; -	info["HeuristicWalkI"] = heuristic_walk_i; -	info["EbpUsed"] = ebp_used; - -} //Get_Call_Stack - -//*********************************** -void WINAPI Get_Version_Str(LLSD& info) -//*********************************** -// Fill Str with Windows version. -{ -	OSVERSIONINFOEX	V = {sizeof(OSVERSIONINFOEX)};	//EX for NT 5.0 and later - -	if (!GetVersionEx((POSVERSIONINFO)&V)) -	{ -		ZeroMemory(&V, sizeof(V)); -		V.dwOSVersionInfoSize = sizeof(OSVERSIONINFO); -		GetVersionEx((POSVERSIONINFO)&V); -	} - -	if (V.dwPlatformId != VER_PLATFORM_WIN32_NT) -		V.dwBuildNumber = LOWORD(V.dwBuildNumber);	//for 9x HIWORD(dwBuildNumber) = 0x04xx - -	info["Platform"] = llformat("Windows:  %d.%d.%d, SP %d.%d, Product Type %d",	//SP - service pack, Product Type - VER_NT_WORKSTATION,... -		V.dwMajorVersion, V.dwMinorVersion, V.dwBuildNumber, V.wServicePackMajor, V.wServicePackMinor, V.wProductType); -} //Get_Version_Str - -//************************************************************* -LLSD WINAPI Get_Exception_Info(PEXCEPTION_POINTERS pException) -//************************************************************* -// Allocate Str[DUMP_SIZE_MAX] and return Str with dump, if !pException - just return call stack in Str. -{ -	LLSD info; -	LPWSTR		Str; -	int			Str_Len; -//	int			i; -	LPWSTR		Module_Name = new WCHAR[MAX_PATH]; -	PBYTE		Module_Addr; -	HANDLE		hFile; -	FILETIME	Last_Write_Time; -	FILETIME	Local_File_Time; -	SYSTEMTIME	T; - -	Str = new WCHAR[DUMP_SIZE_MAX]; -	Str_Len = 0; -	if (!Str) -		return NULL; -	 -	Get_Version_Str(info); -	 -	GetModuleFileName(NULL, Str, MAX_PATH); -	info["Process"] = ll_convert_wide_to_string(Str); -	info["ThreadID"] = (S32)GetCurrentThreadId(); - -	// If exception occurred. -	if (pException) -	{ -		EXCEPTION_RECORD &	E = *pException->ExceptionRecord; -		CONTEXT &			C = *pException->ContextRecord; - -		// If module with E.ExceptionAddress found - save its path and date. -		if (Get_Module_By_Ret_Addr((PBYTE)E.ExceptionAddress, Module_Name, Module_Addr)) -		{ -			info["Module"] = ll_convert_wide_to_string(Module_Name); - -			if ((hFile = CreateFile(Module_Name, GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, -				FILE_ATTRIBUTE_NORMAL, NULL)) != INVALID_HANDLE_VALUE) -			{ -				if (GetFileTime(hFile, NULL, NULL, &Last_Write_Time)) -				{ -					FileTimeToLocalFileTime(&Last_Write_Time, &Local_File_Time); -					FileTimeToSystemTime(&Local_File_Time, &T); - -					info["DateModified"] = llformat("%02d/%02d/%d", T.wMonth, T.wDay, T.wYear); -				} -				CloseHandle(hFile); -			} -		} -		else -		{ -			info["ExceptionAddr"] = (int)E.ExceptionAddress; -		} -		 -		info["ExceptionCode"] = (int)E.ExceptionCode; -		 -		/* -		//TODO: Fix this -		if (E.ExceptionCode == EXCEPTION_ACCESS_VIOLATION) -		{ -			// Access violation type - Write/Read. -			LLSD exception_info; -			exception_info["Type"] = E.ExceptionInformation[0] ? "Write" : "Read"; -			exception_info["Address"] = llformat("%08x", E.ExceptionInformation[1]); -			info["Exception Information"] = exception_info; -		} -		*/ - -		 -		// Save instruction that caused exception. -		/* -		std::string str; -		for (i = 0; i < 16; i++) -			str += llformat(" %02X", PBYTE(E.ExceptionAddress)[i]); -		info["Instruction"] = str; -		*/ -		LLSD registers; -		registers["EAX"] = (int)C.Eax; -		registers["EBX"] = (int)C.Ebx; -		registers["ECX"] = (int)C.Ecx; -		registers["EDX"] = (int)C.Edx; -		registers["ESI"] = (int)C.Esi; -		registers["EDI"] = (int)C.Edi; -		registers["ESP"] = (int)C.Esp; -		registers["EBP"] = (int)C.Ebp; -		registers["EIP"] = (int)C.Eip; -		registers["EFlags"] = (int)C.EFlags; -		info["Registers"] = registers; -	} //if (pException) -	 -	// Save call stack info. -	Get_Call_Stack(pException->ExceptionRecord, pException->ContextRecord, info); - -	return info; -} //Get_Exception_Info - -#define UNICODE - - -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; - -#ifndef _M_IX86 -	#error "The following code only works for x86!" -#endif -LPTOP_LEVEL_EXCEPTION_FILTER WINAPI MyDummySetUnhandledExceptionFilter( -	LPTOP_LEVEL_EXCEPTION_FILTER lpTopLevelExceptionFilter) -{ -	if(lpTopLevelExceptionFilter ==  gFilterFunc) -		return gFilterFunc; - -	llinfos << "Someone tried to set the exception filter. Listing call stack modules" << llendl; -	LLSD cs_info; -	Get_Call_Stack(NULL, NULL, cs_info); -	 -	if(cs_info.has("CallStack") && cs_info["CallStack"].isArray()) -	{ -		LLSD cs = cs_info["CallStack"]; -		for(LLSD::array_iterator i = cs.beginArray();  -			i != cs.endArray();  -			++i) -		{ -			llinfos << "Module: " << (*i)["ModuleName"] << llendl; -		} -	} -	 -	return gFilterFunc; -} - -BOOL PreventSetUnhandledExceptionFilter() -{ -	HMODULE hKernel32 = LoadLibrary(_T("kernel32.dll")); -	if (hKernel32 == NULL)  -		return FALSE; - -	void *pOrgEntry = GetProcAddress(hKernel32, "SetUnhandledExceptionFilter"); -	if(pOrgEntry == NULL)  -		return FALSE; -	 -	unsigned char newJump[ 100 ]; -	DWORD dwOrgEntryAddr = (DWORD)pOrgEntry; -	dwOrgEntryAddr += 5; // add 5 for 5 op-codes for jmp far -	void *pNewFunc = &MyDummySetUnhandledExceptionFilter; -	DWORD dwNewEntryAddr = (DWORD) pNewFunc; -	DWORD dwRelativeAddr = dwNewEntryAddr - dwOrgEntryAddr; - -	newJump[ 0 ] = 0xE9;  // JMP absolute -	memcpy(&newJump[ 1 ], &dwRelativeAddr, sizeof(pNewFunc)); -	SIZE_T bytesWritten; -	BOOL bRet = WriteProcessMemory(GetCurrentProcess(), -	pOrgEntry, newJump, sizeof(pNewFunc) + 1, &bytesWritten); -	return bRet; -} - -// static -void  LLWinDebug::initExceptionHandler(LPTOP_LEVEL_EXCEPTION_FILTER filter_func) -{ -	return; -#if 0 -	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; -	} - -	// Try to get Tool Help library functions. -	HMODULE hKernel32; -	hKernel32 = GetModuleHandle(_T("KERNEL32")); -	CreateToolhelp32Snapshot_ = (CREATE_TOOL_HELP32_SNAPSHOT)GetProcAddress(hKernel32, "CreateToolhelp32Snapshot"); -	Module32First_ = (MODULE32_FIRST)GetProcAddress(hKernel32, "Module32FirstW"); -	Module32Next_ = (MODULE32_NEST)GetProcAddress(hKernel32, "Module32NextW"); - -    PVOID added_filter =  -		AddVectoredExceptionHandler(0, filter_func); - -	if(added_filter == 0) -	{ -		LL_WARNS("AppInit")  -			<< "Failed to add exception handler (" << added_filter << ") !" << LL_ENDL; -	} -	 -	gFilterFunc = filter_func; -#endif -} - -bool LLWinDebug::checkExceptionHandler() -{ -	bool ok = true; - -	RemoveVectoredExceptionHandler(gFilterFunc); -	PVOID filter = AddVectoredExceptionHandler(0, gFilterFunc); - -	if (filter == NULL) -	{ -		ok = FALSE; -		if (gFilterFunc == NULL) -		{ -			LL_WARNS("AppInit") << "Exception handler uninitialized." << LL_ENDL; -		} -		else -		{ -			LL_WARNS("AppInit") << "Failed to add exception handler (" << (void *)gFilterFunc << ")!" << LL_ENDL; -		} -	} - -	return ok; -} - -void LLWinDebug::writeDumpToFile(MINIDUMP_TYPE type, MINIDUMP_EXCEPTION_INFORMATION *ExInfop, const std::string& filename) -{ -	if(f_mdwp == NULL || gDirUtilp == NULL)  -	{ -		return; -		//write_debug("No way to generate a minidump, no MiniDumpWriteDump function!\n"); -	} -	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::generateCrashStacks(struct _EXCEPTION_POINTERS *exception_infop) -{ -	// *NOTE:Mani - This method is no longer the exception handler. -	// Its called from viewer_windows_exception_handler() and other places. - -	//  -	// Let go of a bunch of reserved memory to give library calls etc -	// a chance to execute normally in the case that we ran out of -	// memory. -	// -	LLSD info; -	std::string dump_path = gDirUtilp->getExpandedFilename(LL_PATH_LOGS, -												"SecondLifeException"); -	std::string log_path = dump_path + ".log"; - -	if (exception_infop) -	{ -		// Since there is exception info... Release the hounds. -		gEmergencyMemoryReserve.release(); - -		if(gSavedSettings.getControl("SaveMinidump").notNull() && gSavedSettings.getBOOL("SaveMinidump")) -		{ -			_MINIDUMP_EXCEPTION_INFORMATION ExInfo; - -			ExInfo.ThreadId = ::GetCurrentThreadId(); -			ExInfo.ExceptionPointers = exception_infop; -			ExInfo.ClientPointers = NULL; - -			writeDumpToFile(MiniDumpNormal, &ExInfo, "SecondLife.dmp"); -			writeDumpToFile((MINIDUMP_TYPE)(MiniDumpWithDataSegs | MiniDumpWithIndirectlyReferencedMemory), &ExInfo, "SecondLifePlus.dmp"); -		} - -		info = Get_Exception_Info(exception_infop); -	} - -	LLSD threads; -    std::vector<DWORD> thread_ids; -    GetProcessThreadIDs(GetCurrentProcessId(), thread_ids); - -    for(std::vector<DWORD>::iterator th_itr = thread_ids.begin();  -                th_itr != thread_ids.end(); -                ++th_itr) -    { -        LLSD thread_info; -        if(*th_itr != GetCurrentThreadId()) -        { -            GetThreadCallStack(*th_itr, thread_info); -        } - -        if(thread_info) -        { -            threads[llformat("ID %d", *th_itr)] = thread_info; -        } -    } - -    info["Threads"] = threads; - -	llofstream out_file(log_path); -	LLSDSerialize::toPrettyXML(info, out_file); -	out_file.close(); -} - -void LLWinDebug::clearCrashStacks() -{ -	LLSD info; -	std::string dump_path = gDirUtilp->getExpandedFilename(LL_PATH_LOGS, "SecondLifeException.log"); -	LLFile::remove(dump_path); -} diff --git a/indra/newview/llwindebug.h b/indra/newview/llwindebug.h deleted file mode 100644 index f4a6a2d54d..0000000000 --- a/indra/newview/llwindebug.h +++ /dev/null @@ -1,75 +0,0 @@ -/**  - * @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 <dbghelp.h> - -class LLWinDebug -{ -public: - -	/**  -	* @brief initialize the llwindebug exception filter callback -	*  -	* Hand a windows unhandled exception filter to LLWinDebug -	* This method should only be called to change the -	* exception filter used by llwindebug. -	* -	* Setting filter_func to NULL will clear any custom filters. -	**/ -	static void initExceptionHandler(LPTOP_LEVEL_EXCEPTION_FILTER filter_func); - -	/**  -	* @brief check the status of the exception filter. -	* -	* Resets unhandled exception filter to the filter specified  -	* w/ initExceptionFilter).  -	* Returns false if the exception filter was modified. -	* -	* *NOTE:Mani In the past mozlib has been accused of -	* overriding the exception filter. If the mozlib filter  -	* is required, perhaps we can chain calls from our  -	* filter to mozlib's. -	**/ -	static bool checkExceptionHandler(); - -	static void generateCrashStacks(struct _EXCEPTION_POINTERS *pExceptionInfo = NULL); -	static void clearCrashStacks(); // Delete the crash stack file(s). - -	static void writeDumpToFile(MINIDUMP_TYPE type, MINIDUMP_EXCEPTION_INFORMATION *ExInfop, const std::string& filename); -private: -}; - -#endif // LL_LLWINDEBUG_H  | 
