From d2bb4dae980a887a30b206875d8f9419901ed66a Mon Sep 17 00:00:00 2001
From: Aura Linden <aura@lindenlab.com>
Date: Fri, 7 Mar 2014 14:58:22 -0800
Subject: [PATCH] Fixes for crash reporter startup race condition, crash
 reporter CPU use, Secondlife.log filehandle, XP Crash.

---
 indra/llcommon/llapp.cpp                      | 25 ++++-----
 indra/llcommon/llfile.cpp                     | 31 +++++++++++
 indra/llcommon/llfile.h                       |  2 +
 indra/llcrashlogger/llcrashlogger.cpp         | 53 +++++++++----------
 indra/llvfs/lldir.cpp                         | 26 ++++++++-
 indra/newview/llappviewer.cpp                 | 20 ++++---
 indra/newview/llappviewerwin32.cpp            | 33 ++++++++++--
 indra/newview/llfloaterspellchecksettings.cpp | 35 +-----------
 indra/newview/llfloaterspellchecksettings.h   |  1 -
 .../win_crash_logger/llcrashloggerwindows.cpp | 35 +++++++-----
 indra/win_crash_logger/win_crash_logger.cpp   |  2 +-
 11 files changed, 160 insertions(+), 103 deletions(-)

diff --git a/indra/llcommon/llapp.cpp b/indra/llcommon/llapp.cpp
index 2c5da5d2a70..5c8fff051f5 100755
--- a/indra/llcommon/llapp.cpp
+++ b/indra/llcommon/llapp.cpp
@@ -342,12 +342,13 @@ void LLApp::setupErrorHandling()
 		std::wstring wpipe_name;
 		wpipe_name =  mCrashReportPipeStr + wstringize(getPid());
 
-		::Sleep(3000);  //HACK hopefully a static wait won't blow up in my face before google fixes their implementation.
 		const std::wstring wdump_path(wstringize(mDumpPath));
 
-		//HACK this for loop is ueless.  Breakpad dumbly returns success when the OOP handler isn't initialized.
-		for (int retries=0;retries<5;++retries)
+		int retries = 30;
+		for (; retries > 0; --retries)
 		{
+			if (mExceptionHandler != 0) delete mExceptionHandler;
+
 			mExceptionHandler = new google_breakpad::ExceptionHandler(
 														wdump_path,		
 														NULL,		//No filter
@@ -357,25 +358,20 @@ void LLApp::setupErrorHandling()
 														MiniDumpNormal, //Generate a 'normal' minidump.
 														wpipe_name.c_str(),
 														NULL);  //No custom client info.
-			if (mExceptionHandler)
+			if (mExceptionHandler->IsOutOfProcess())
 			{
+				LL_INFOS("CRASHREPORT") << "Successfully attached to Out of Process exception handler." << LL_ENDL;
 				break;
 			}
 			else
 			{
+				LL_WARNS("CRASHREPORT") << "Unable to attach to Out of Process exception handler.  " << retries << " retries remaining." << LL_ENDL; 
 				::Sleep(100);  //Wait a tick and try again.
 			}
 		}
-		if (!mExceptionHandler)
-		{
-				llwarns << "Failed to initialize OOP exception handler.  Defaulting to In Process handling" << llendl;
-				mExceptionHandler = new google_breakpad::ExceptionHandler(
-																  wstringize(mDumpPath),		
-																  0,		//dump filename	
-																  windows_post_minidump_callback, 
-																  0, 
-																  google_breakpad::ExceptionHandler::HANDLER_ALL);
-		}
+
+		if (retries == 0) LL_WARNS("CRASHREPORT") << "Unable to attach to Out of Process exception handler." << LL_ENDL;
+
 		if (mExceptionHandler)
 		{
 			mExceptionHandler->set_handle_debug_exceptions(true);
@@ -991,6 +987,7 @@ bool windows_post_minidump_callback(const wchar_t* dump_path,
 	S32 remaining = LLApp::MAX_MINDUMP_PATH_LENGTH;
 	size_t bytesUsed;
 
+	LL_INFOS("MINIDUMPCALLBACK") << "Dump file was generated." << LL_ENDL;
 	bytesUsed = wcstombs(path, dump_path, static_cast<size_t>(remaining));
 	remaining -= bytesUsed;
 	path += bytesUsed;
diff --git a/indra/llcommon/llfile.cpp b/indra/llcommon/llfile.cpp
index c3a0f0bfe04..761d7f430cf 100755
--- a/indra/llcommon/llfile.cpp
+++ b/indra/llcommon/llfile.cpp
@@ -265,6 +265,37 @@ int	LLFile::rename(const std::string& filename, const std::string& newname)
 	return warnif(STRINGIZE("rename to '" << newname << "' from"), filename, rc);
 }
 
+bool LLFile::copy(const std::string from, const std::string to)
+{
+	bool copied = false;
+	LLFILE* in = LLFile::fopen(from, "rb");		/* Flawfinder: ignore */	 	
+	if (in)	 	
+	{	 	
+		LLFILE* out = LLFile::fopen(to, "wb");		/* Flawfinder: ignore */
+		if (out)
+		{
+			char buf[16384];		/* Flawfinder: ignore */ 	
+			size_t readbytes;
+			bool write_ok = true;
+			while(write_ok && (readbytes = fread(buf, 1, 16384, in))) /* Flawfinder: ignore */
+			{
+				if (fwrite(buf, 1, readbytes, out) != readbytes)
+				{
+					LL_WARNS("LLFile") << "Short write" << LL_ENDL; 
+					write_ok = false;
+				}
+			}
+			if ( write_ok )
+			{
+				copied = true;
+			}
+			fclose(out);
+		}
+		fclose(in);
+	}
+	return copied;
+}
+
 int	LLFile::stat(const std::string& filename, llstat* filestatus)
 {
 #if LL_WINDOWS
diff --git a/indra/llcommon/llfile.h b/indra/llcommon/llfile.h
index d59e68367e8..f56b22bf9af 100755
--- a/indra/llcommon/llfile.h
+++ b/indra/llcommon/llfile.h
@@ -75,6 +75,8 @@ class LL_COMMON_API LLFile
 	static	int		rmdir(const std::string& filename);
 	static	int		remove(const std::string& filename);
 	static	int		rename(const std::string& filename,const std::string&	newname);
+	static  bool	copy(const std::string from, const std::string to);
+
 	static	int		stat(const std::string&	filename,llstat*	file_status);
 	static	bool	isdir(const std::string&	filename);
 	static	bool	isfile(const std::string&	filename);
diff --git a/indra/llcrashlogger/llcrashlogger.cpp b/indra/llcrashlogger/llcrashlogger.cpp
index bd34caf241a..e66b7cbba44 100755
--- a/indra/llcrashlogger/llcrashlogger.cpp
+++ b/indra/llcrashlogger/llcrashlogger.cpp
@@ -218,21 +218,10 @@ void LLCrashLogger::gatherFiles()
 	{
 		// Figure out the filename of the second life log
 		LLCurl::setCAFile(gDirUtilp->getCAFile());
-		mFileMap["SecondLifeLog"] = gDirUtilp->getExpandedFilename(LL_PATH_LOGS,"SecondLife.log");
+		mFileMap["SecondLifeLog"] = gDirUtilp->getExpandedFilename(LL_PATH_DUMP,"SecondLife.log");
 		mFileMap["SettingsXml"] = gDirUtilp->getExpandedFilename(LL_PATH_USER_SETTINGS,"settings.xml");
 	}
 
-	if(mCrashInPreviousExec)
-	{
-		// Restarting after freeze.
-		// Replace the log file ext with .old, since the 
-		// instance that launched this process has overwritten
-		// SecondLife.log
-		std::string log_filename = mFileMap["SecondLifeLog"];
-		log_filename.replace(log_filename.size() - 4, 4, ".old");
-		mFileMap["SecondLifeLog"] = log_filename;
-	}
-
 	gatherPlatformSpecificFiles();
 
 	//Use the debug log to reconstruct the URL to send the crash report to
@@ -271,7 +260,7 @@ void LLCrashLogger::gatherFiles()
 		std::ifstream f((*itr).second.c_str());
 		if(!f.is_open())
 		{
-			std::cout << "Can't find file " << (*itr).second << std::endl;
+			LL_INFOS("CRASHREPORT") << "Can't find file " << (*itr).second << LL_ENDL;
 			continue;
 		}
 		std::stringstream s;
@@ -488,6 +477,12 @@ bool LLCrashLogger::sendCrashLogs()
                         else
                         {
                             //mCrashInfo["DebugLog"].erase("MinidumpPath");
+                            //To preserve logfile on clean shutdown move to regular log dir.
+                            std::string curr_log = (*lock)["dumpdir"].asString() + "SecondLife.log";
+                            std::string last_log = gDirUtilp->getExpandedFilename(LL_PATH_LOGS,"SecondLife.log");
+
+                            LLFile::remove(last_log);
+                            LLFile::rename(curr_log, last_log); //Before we blow away the directory, perserve log of previous run.
 
                             mKeyMaster.cleanupProcess((*lock)["dumpdir"].asString());
                         }
@@ -529,11 +524,25 @@ bool LLCrashLogger::init()
 	// Default to the product name "Second Life" (this is overridden by the -name argument)
 	mProductName = "Second Life";
 
+	// Rename current log file to ".old"
+	std::string old_log_file = gDirUtilp->getExpandedFilename(LL_PATH_LOGS, "crashreport.log.old");
+	std::string log_file = gDirUtilp->getExpandedFilename(LL_PATH_LOGS, "crashreport.log");
+
+#if LL_WINDOWS
+	LLAPRFile::remove(old_log_file);
+#endif 
+
+	LLFile::rename(log_file.c_str(), old_log_file.c_str());
+    
+	// Set the log file to crashreport.log
+	LLError::logToFile(log_file);  //NOTE:  Until this line, LL_INFOS LL_WARNS, etc are blown to the ether. 
+
     // Handle locking
-    bool locked = mKeyMaster.requestMaster();  //Request maser locking file.  wait time is defaulted to 300S
+    bool locked = mKeyMaster.requestMaster();  //Request master locking file.  wait time is defaulted to 300S
     
     while (!locked && mKeyMaster.isWaiting())
     {
+		LL_INFOS("CRASHREPORT") << "Waiting for lock." << LL_ENDL;
 #if LL_WINDOWS
 		Sleep(1000);
 #else
@@ -544,22 +553,9 @@ bool LLCrashLogger::init()
     
     if (!locked)
     {
-        llwarns << "Unable to get master lock.  Another crash reporter may be hung." << llendl;
+        LL_WARNS("CRASHREPORT") << "Unable to get master lock.  Another crash reporter may be hung." << LL_ENDL;
         return false;
     }
-    
-    // Rename current log file to ".old"
-	std::string old_log_file = gDirUtilp->getExpandedFilename(LL_PATH_LOGS, "crashreport.log.old");
-	std::string log_file = gDirUtilp->getExpandedFilename(LL_PATH_LOGS, "crashreport.log");
-
-#if LL_WINDOWS
-	LLAPRFile::remove(old_log_file);
-#endif 
-
-	LLFile::rename(log_file.c_str(), old_log_file.c_str());
-    
-	// Set the log file to crashreport.log
-	LLError::logToFile(log_file);
 
     mCrashSettings.declareS32("CrashSubmitBehavior", CRASH_BEHAVIOR_ALWAYS_SEND,
 							  "Controls behavior when viewer crashes "
@@ -587,5 +583,6 @@ bool LLCrashLogger::init()
 // For cleanup code common to all platforms.
 void LLCrashLogger::commonCleanup()
 {
+	LLError::logToFile("");   //close crashreport.log
 	LLProxy::cleanupClass();
 }
diff --git a/indra/llvfs/lldir.cpp b/indra/llvfs/lldir.cpp
index ccdfd2ab3c4..0d65c3f8c33 100755
--- a/indra/llvfs/lldir.cpp
+++ b/indra/llvfs/lldir.cpp
@@ -187,8 +187,30 @@ S32 LLDir::deleteFilesInDir(const std::string &dirname, const std::string &mask)
 
 U32 LLDir::deleteDirAndContents(const std::string& dir_name)
 {
-    //Removes the directory and its contents.  Returns number of files removed.
-    return boost::filesystem::remove_all(dir_name);
+    //Removes the directory and its contents.  Returns number of files deleted.
+	
+	U32 num_deleted = 0;
+
+	try
+	{
+	   boost::filesystem::path dir_path(dir_name);
+	   if (boost::filesystem::exists (dir_path))
+	   {
+	      if (!boost::filesystem::is_empty (dir_path))
+		  {   // Directory has content
+		     num_deleted = boost::filesystem::remove_all (dir_path);
+		  }
+		  else
+		  {   // Directory is empty
+		     boost::filesystem::remove (dir_path);
+		  }
+	   }
+	}
+	catch (boost::filesystem::filesystem_error &er)
+	{ 
+		llwarns << "Failed to delete " << dir_name << " with error " << er.code().message() << llendl;
+	} 
+	return num_deleted;
 }
 
 const std::string LLDir::findFile(const std::string &filename, 
diff --git a/indra/newview/llappviewer.cpp b/indra/newview/llappviewer.cpp
index 537142ebde8..c31c0990c71 100755
--- a/indra/newview/llappviewer.cpp
+++ b/indra/newview/llappviewer.cpp
@@ -1940,7 +1940,6 @@ bool LLAppViewer::cleanup()
 		gDirUtilp->deleteFilesInDir(gDirUtilp->getExpandedFilename(LL_PATH_CACHE,""), "*.*");
 	}
 	
-	removeDumpDir();   
 	writeDebugInfo();
 
 	LLLocationHistory::getInstance()->save();
@@ -2102,6 +2101,14 @@ bool LLAppViewer::cleanup()
 
     llinfos << "Goodbye!" << llendflush;
 
+    //To preserve logfile on clean shutdown move to regular log dir.
+    std::string curr_log = gDirUtilp->getExpandedFilename(LL_PATH_DUMP,"SecondLife.log");
+    std::string last_log = gDirUtilp->getExpandedFilename(LL_PATH_LOGS,"SecondLife.log");
+	LLError::logToFile(""); //Close Secondlife.log
+    LLFile::remove(last_log);
+    LLFile::copy(curr_log, last_log); 
+    removeDumpDir();
+
 	// return 0;
 	return true;
 }
@@ -2191,7 +2198,7 @@ void LLAppViewer::initLoggingAndGetLastDuration()
 	// Get name of the log file
 	std::string log_file = gDirUtilp->getExpandedFilename(LL_PATH_LOGS,
 							     "SecondLife.log");
-	/*
+ 	/*
 	 * Before touching any log files, compute the duration of the last run
 	 * by comparing the ctime of the previous start marker file with the ctime
 	 * of the last log file.
@@ -2237,6 +2244,8 @@ void LLAppViewer::initLoggingAndGetLastDuration()
 	// Rename current log file to ".old"
 	LLFile::rename(log_file, old_log_file);
 
+	log_file = gDirUtilp->getExpandedFilename(LL_PATH_DUMP,
+							     "SecondLife.log");
 	// Set the log file to SecondLife.log
 	LLError::logToFile(log_file);
 	if (!duration_log_msg.empty())
@@ -3505,7 +3514,7 @@ void LLAppViewer::handleViewerCrash()
 		LL_WARNS("MarkerFile") << "No gDirUtilp with which to create error marker file name" << LL_ENDL;
 	}		
 	
-#ifdef LL_WINDOWS //SPATTERS Wild guess that filename for Breakpad is not being returned due to sleep cycle in Crash Reporter.
+#ifdef LL_WINDOWS
 	Sleep(2000);
 #endif 
 
@@ -3514,12 +3523,9 @@ void LLAppViewer::handleViewerCrash()
 	if(minidump_file && minidump_file[0] != 0)
 	{
 		gDebugInfo["Dynamic"]["MinidumpPath"] = minidump_file;
-		//SPATTERS another possibility is that when using OOP it must be initiated by a wrapping program so that when the
-		//viewer crashes, we are from a sibling thread than as a child.   Might be able to request minidump at this point
-		//as a work-around.
 	}
 #ifdef LL_WINDOWS
-	else  //SPATTERS there is no else here in the older code
+	else
 	{
 		getFileList();
 	}
diff --git a/indra/newview/llappviewerwin32.cpp b/indra/newview/llappviewerwin32.cpp
index c861d0a99f3..0e4efa34c75 100644
--- a/indra/newview/llappviewerwin32.cpp
+++ b/indra/newview/llappviewerwin32.cpp
@@ -276,7 +276,7 @@ int APIENTRY WINMAIN(HINSTANCE hInstance,
 	viewer_app_ptr->setErrorHandler(LLAppViewer::handleViewerCrash);
 
 #if LL_SEND_CRASH_REPORTS 
-	::SetUnhandledExceptionFilter(catchallCrashHandler);
+	// ::SetUnhandledExceptionFilter(catchallCrashHandler); 
 #endif
 
 	// Set a debug info flag to indicate if multiple instances are running.
@@ -698,8 +698,35 @@ void LLAppViewerWin32::initCrashReporting(bool reportFreeze)
 	{
 		logdir = logdir.substr(0,end+1);
 	}
-	std::string arg_str = "\"" + exe_path + "\" -dumpdir \"" + logdir + "\" -procname \"" + appname + "\" -pid " + stringize(LLApp::getPid());
-	_spawnl(_P_NOWAIT, exe_path.c_str(), arg_str.c_str(), NULL);
+	//std::string arg_str = "\"" + exe_path + "\" -dumpdir \"" + logdir + "\" -procname \"" + appname + "\" -pid " + stringize(LLApp::getPid());
+	//_spawnl(_P_NOWAIT, exe_path.c_str(), arg_str.c_str(), NULL);
+	std::string arg_str =  "\"" + exe_path + "\" -dumpdir \"" + logdir + "\" -procname \"" + appname + "\" -pid " + stringize(LLApp::getPid()); 
+
+	STARTUPINFO startInfo={sizeof(startInfo)};
+	PROCESS_INFORMATION processInfo;
+
+	std::wstring exe_wstr;
+	exe_wstr=wstringize(exe_path);
+
+	std::wstring arg_wstr;
+	arg_wstr=wstringize(arg_str);
+
+	LL_INFOS("CrashReport") << "Creating crash reporter process " << exe_path << " with params: " << arg_str << LL_ENDL;
+    if(CreateProcess(exe_wstr.c_str(),     
+                     &arg_wstr[0],                 // Application arguments
+                     0,
+                     0,
+                     FALSE,
+                     CREATE_DEFAULT_ERROR_MODE,
+                     0,
+                     0,                              // Working directory
+                     &startInfo,
+                     &processInfo) == FALSE)
+      // Could not start application -> call 'GetLastError()'
+	{
+        LL_WARNS("CrashReport Launch") << "CreateProcess failed " << GetLastError() << LL_ENDL;
+        return;
+    }
 }
 
 //virtual
diff --git a/indra/newview/llfloaterspellchecksettings.cpp b/indra/newview/llfloaterspellchecksettings.cpp
index 5ecdd119181..54c7b4c37dc 100755
--- a/indra/newview/llfloaterspellchecksettings.cpp
+++ b/indra/newview/llfloaterspellchecksettings.cpp
@@ -307,12 +307,12 @@ void LLFloaterSpellCheckerImport::onBtnOK()
 	else
 	{
 		std::string settings_dic = LLSpellChecker::getDictionaryUserPath() + mDictionaryBasename + ".dic";
-		if ( copyFile( dict_dic, settings_dic ) )
+		if ( LLFile::copy( dict_dic, settings_dic ) )
 		{
 			if (gDirUtilp->fileExists(dict_aff))
 			{
 				std::string settings_aff = LLSpellChecker::getDictionaryUserPath() + mDictionaryBasename + ".aff";
-				if (copyFile( dict_aff, settings_aff ))
+				if ( LLFile::copy( dict_aff, settings_aff ))
 				{
 					imported = true;
 				}
@@ -385,37 +385,6 @@ void LLFloaterSpellCheckerImport::onBtnOK()
 	closeFloater(false);
 }
 
-bool LLFloaterSpellCheckerImport::copyFile(const std::string from, const std::string to)
-{
-	bool copied = false;
-	LLFILE* in = LLFile::fopen(from, "rb");		/* Flawfinder: ignore */	 	
-	if (in)	 	
-	{	 	
-		LLFILE* out = LLFile::fopen(to, "wb");		/* Flawfinder: ignore */
-		if (out)
-		{
-			char buf[16384];		/* Flawfinder: ignore */ 	
-			size_t readbytes;
-			bool write_ok = true;
-			while(write_ok && (readbytes = fread(buf, 1, 16384, in))) /* Flawfinder: ignore */
-			{
-				if (fwrite(buf, 1, readbytes, out) != readbytes)
-				{
-					LL_WARNS("SpellCheck") << "Short write" << LL_ENDL; 
-					write_ok = false;
-				}
-			}
-			if ( write_ok )
-			{
-				copied = true;
-			}
-			fclose(out);
-		}
-	}
-	fclose(in);
-	return copied;
-}
-
 std::string LLFloaterSpellCheckerImport::parseXcuFile(const std::string& file_path) const
 {
 	LLXMLNodePtr xml_root;
diff --git a/indra/newview/llfloaterspellchecksettings.h b/indra/newview/llfloaterspellchecksettings.h
index eded3a9133d..de59d83f242 100755
--- a/indra/newview/llfloaterspellchecksettings.h
+++ b/indra/newview/llfloaterspellchecksettings.h
@@ -58,7 +58,6 @@ class LLFloaterSpellCheckerImport : public LLFloater
 	void onBtnBrowse();
 	void onBtnCancel();
 	void onBtnOK();
-	bool copyFile(const std::string from, const std::string to);
 	std::string parseXcuFile(const std::string& file_path) const;
 
 	std::string mDictionaryDir;
diff --git a/indra/win_crash_logger/llcrashloggerwindows.cpp b/indra/win_crash_logger/llcrashloggerwindows.cpp
index b72f5be853b..e3356f90ba6 100644
--- a/indra/win_crash_logger/llcrashloggerwindows.cpp
+++ b/indra/win_crash_logger/llcrashloggerwindows.cpp
@@ -260,8 +260,7 @@ LLCrashLoggerWindows::~LLCrashLoggerWindows(void)
 bool LLCrashLoggerWindows::getMessageWithTimeout(MSG *msg, UINT to)
 {
     bool res;
-	const int timerID=37;
-    SetTimer(NULL, timerID, to, NULL);
+	UINT_PTR timerID = SetTimer(NULL, NULL, to, NULL);
     res = GetMessage(msg, NULL, 0, 0);
     KillTimer(NULL, timerID);
     if (!res)
@@ -273,7 +272,10 @@ bool LLCrashLoggerWindows::getMessageWithTimeout(MSG *msg, UINT to)
 
 int LLCrashLoggerWindows::processingLoop() {
 	const int millisecs=1000;
-	static int first_connect = 1;
+	int retries = 0;
+	const int max_retries = 60;
+
+	LL_DEBUGS("CRASHREPORT") << "Entering processing loop for OOP server" << LL_ENDL;
 
 	LLSD options = getOptionData( LLApp::PRIORITY_COMMAND_LINE );
 
@@ -290,11 +292,17 @@ int LLCrashLoggerWindows::processingLoop() {
 			DispatchMessage(&msg);
 		}
 
-		if (first_connect )
+		if ( retries < max_retries )  //Wait up to 1 minute for the viewer to say hello.
 		{
-			if ( mClientsConnected > 0) 
+			if (mClientsConnected == 0) 
+			{
+				LL_DEBUGS("CRASHREPORT") << "Waiting for client to connect." << LL_ENDL;
+				++retries;
+			}
+			else
 			{
-				first_connect = 0;
+				LL_INFOS("CRASHREPORT") << "Client has connected!" << LL_ENDL;
+				retries = max_retries;
 			}
 		} 
 		else 
@@ -311,9 +319,7 @@ int LLCrashLoggerWindows::processingLoop() {
     }
     
     llinfos << "session ending.." << llendl;
-    
-    llinfos << "clients connected :" << mClientsConnected << llendl;
-    
+        
 	return 0;
 }
 
@@ -321,16 +327,15 @@ int LLCrashLoggerWindows::processingLoop() {
 void LLCrashLoggerWindows::OnClientConnected(void* context,
 				const google_breakpad::ClientInfo* client_info) 
 {
-	llinfos << "client start. pid = " << client_info->pid() << llendl;
 	sInstance->mClientsConnected++;
+	LL_INFOS("CRASHREPORT") << "Client connected. pid = " << client_info->pid() << " total clients " << sInstance->mClientsConnected << LL_ENDL;
 }
 
 void LLCrashLoggerWindows::OnClientExited(void* context,
 		const google_breakpad::ClientInfo* client_info) 
 {
-	llinfos << "client end. pid = " << client_info->pid() << llendl;
-
 	sInstance->mClientsConnected--;
+	LL_INFOS("CRASHREPORT") << "Client disconnected. pid = " << client_info->pid() << " total clients " << sInstance->mClientsConnected << LL_ENDL;
 }
 
 
@@ -402,19 +407,21 @@ bool LLCrashLoggerWindows::initCrashServer()
 		return false;
 	}
 
+	LL_INFOS("CRASHREPORT") << "Initialized OOP server with pipe named " << stringize(wpipe_name) << LL_ENDL;
 	return true;
 }
 
 bool LLCrashLoggerWindows::init(void)
 {	
-	initCrashServer();
 	bool ok = LLCrashLogger::init();
 	if(!ok) return false;
 
+	initCrashServer();
+
 	/*
 	mbstowcs( gProductName, mProductName.c_str(), LL_ARRAY_SIZE(gProductName) );
 	gProductName[ LL_ARRY_SIZE(gProductName) - 1 ] = 0;
-	swprintf(gProductName, L"Second Life");
+	swprintf(gProductName, L"Second Life"); 
 	*/
 
 	llinfos << "Loading dialogs" << llendl;
diff --git a/indra/win_crash_logger/win_crash_logger.cpp b/indra/win_crash_logger/win_crash_logger.cpp
index 0f125028a3c..79b85147250 100755
--- a/indra/win_crash_logger/win_crash_logger.cpp
+++ b/indra/win_crash_logger/win_crash_logger.cpp
@@ -34,7 +34,7 @@ int APIENTRY WinMain(HINSTANCE hInstance,
                      LPSTR     lpCmdLine,
                      int       nCmdShow)
 {
-	llinfos << "Starting crash reporter." << llendl;
+	llinfos << "Starting crash reporter with args" << &lpCmdLine << llendl;
 	LLCrashLoggerWindows app;
 	app.setHandle(hInstance);
 	app.parseCommandOptions(__argc, __argv);
-- 
GitLab