diff --git a/indra/llcommon/llapp.cpp b/indra/llcommon/llapp.cpp index 958dfc470a..b1819d4f65 100644 --- a/indra/llcommon/llapp.cpp +++ b/indra/llcommon/llapp.cpp @@ -441,9 +441,15 @@ void LLApp::setMiniDumpDir(const std::string &path) { if(mExceptionHandler == 0) return; #ifdef LL_WINDOWS - wchar_t buffer[MAX_MINDUMP_PATH_LENGTH]; - mbstowcs(buffer, path.c_str(), MAX_MINDUMP_PATH_LENGTH); - mExceptionHandler->set_dump_path(std::wstring(buffer)); + // Make sure to pass a proper unicode string to breapad. path is UTF8, not MBCS + + // wchar_t buffer[MAX_MINDUMP_PATH_LENGTH]; + // mbstowcs(buffer, path.c_str(), MAX_MINDUMP_PATH_LENGTH); + // mExceptionHandler->set_dump_path(std::wstring(buffer)); + + mExceptionHandler->set_dump_path( utf8str_to_utf16str(path) ); + + // #else mExceptionHandler->set_dump_path(path); #endif @@ -936,6 +942,41 @@ bool unix_post_minidump_callback(const char *dump_dir, #endif // !WINDOWS #ifdef LL_WINDOWS + +// Helper function to convert a wchar_t string into an UTF8 buffer +namespace nd +{ + namespace strings + { + inline bool convertString( wchar_t const *aIn, char *&aOut, S32 &aLen ) + { + char tmpBuffer[8]; + S32 i(0), j(0); + + while( *aIn ) + { + i = wchar_to_utf8chars( *aIn++, tmpBuffer ); + + if( i < aLen ) + { + j = 0; + while( j < i ) + { + *aOut++ = tmpBuffer[ j++ ]; + --aLen; + } + } + else + return true; + } + + return false; + } + } +} + +// + bool windows_post_minidump_callback(const wchar_t* dump_path, const wchar_t* minidump_id, void* context, @@ -943,29 +984,61 @@ bool windows_post_minidump_callback(const wchar_t* dump_path, MDRawAssertionInfo* assertion, bool succeeded) { - char * path = LLApp::instance()->getMiniDumpFilename(); - S32 remaining = LLApp::MAX_MINDUMP_PATH_LENGTH; - size_t bytesUsed; + MessageBox( NULL, L"", L"", MB_OK ); - bytesUsed = wcstombs(path, dump_path, static_cast(remaining)); - remaining -= bytesUsed; - path += bytesUsed; - if(remaining > 0 && bytesUsed > 0 && path[-1] != '\\') + // Convert all path to UTF8 and not MBCS. Having some path in MBCS and some in UTF8 is a source of great joy + // and bugs. Stick with one standard, that is UTF8. + + // char * path = LLApp::instance()->getMiniDumpFilename(); + // S32 remaining = LLApp::MAX_MINDUMP_PATH_LENGTH; + // size_t bytesUsed; + // + // bytesUsed = wcstombs(path, dump_path, static_cast(remaining)); + // remaining -= bytesUsed; + // path += bytesUsed; + // if(remaining > 0 && bytesUsed > 0 && path[-1] != '\\') + // { + // *path++ = '\\'; + // --remaining; + // } + // if(remaining > 0) + // { + // bytesUsed = wcstombs(path, minidump_id, static_cast(remaining)); + // remaining -= bytesUsed; + // path += bytesUsed; + // } + // if(remaining > 0) + // { + // strncpy(path, ".dmp", remaining); + // } + + char *pOut( LLApp::instance()->getMiniDumpFilename() ); + bool hasOverflow(false); + S32 bufferLength( LLApp::MAX_MINDUMP_PATH_LENGTH ); + + hasOverflow = nd::strings::convertString( dump_path, pOut, bufferLength ); + if( !hasOverflow && bufferLength < LLApp::MAX_MINDUMP_PATH_LENGTH && bufferLength > 1 && pOut[-1] != '\\' && pOut[-1] != '/' ) { - *path++ = '\\'; - --remaining; - } - if(remaining > 0) - { - bytesUsed = wcstombs(path, minidump_id, static_cast(remaining)); - remaining -= bytesUsed; - path += bytesUsed; - } - if(remaining > 0) - { - strncpy(path, ".dmp", remaining); + *pOut++ = '\\'; + --bufferLength; } + if( !hasOverflow ) + hasOverflow = nd::strings::convertString( minidump_id, pOut, bufferLength ); + + if( !hasOverflow && bufferLength >= 5 ) + { + pOut[0] = '.'; + pOut[1] = 'd'; + pOut[2] = 'm'; + pOut[3] = 'p'; + pOut[4] = 0; + } + else if( hasOverflow ) + LLApp::instance()->getMiniDumpFilename()[ 0 ] = 0; + + // + llinfos << "generated minidump: " << LLApp::instance()->getMiniDumpFilename() << llendl; // *NOTE:Mani - this code is stolen from LLApp, where its never actually used. //OSMessageBox("Attach Debugger Now", "Error", OSMB_OK); diff --git a/indra/llcrashlogger/llcrashlogger.cpp b/indra/llcrashlogger/llcrashlogger.cpp index 523fcd7505..97659f99b3 100644 --- a/indra/llcrashlogger/llcrashlogger.cpp +++ b/indra/llcrashlogger/llcrashlogger.cpp @@ -159,7 +159,18 @@ void LLCrashLogger::gatherFiles() // Figure out the filename of the debug log std::string db_file_name = gDirUtilp->getExpandedFilename(LL_PATH_LOGS,"debug_info.log"); + + // Properly handle unicode path on Windows. Maybe could use a llifstream instead of ifdef? + + // std::ifstream debug_log_file(db_file_name.c_str()); + +#ifdef LL_WINDOWS + std::ifstream debug_log_file( utf8str_to_utf16str( db_file_name ).c_str()); +#else std::ifstream debug_log_file(db_file_name.c_str()); +#endif + + // // Look for it in the debug_info.log file if (debug_log_file.is_open()) @@ -498,7 +509,12 @@ bool LLCrashLogger::sendCrashLogs() // [/SL:KB] std::string report_file = dump_path + ".log"; +#ifdef LL_WINDOWS + std::ofstream out_file( utf8str_to_utf16str(report_file).c_str() ); +#else std::ofstream out_file(report_file.c_str()); +#endif + LLSDSerialize::toPrettyXML(post_data, out_file); out_file.close(); diff --git a/indra/win_crash_logger/llcrashlookupwindows.cpp b/indra/win_crash_logger/llcrashlookupwindows.cpp index 4759b11d83..a701f479d9 100644 --- a/indra/win_crash_logger/llcrashlookupwindows.cpp +++ b/indra/win_crash_logger/llcrashlookupwindows.cpp @@ -35,6 +35,7 @@ LLCrashLookupWindows::LLCrashLookupWindows() , m_pDbgClient(NULL) , m_pDbgControl(NULL) , m_pDbgSymbols(NULL) + , m_pDbgClient4(0) { CoInitialize(NULL); @@ -48,6 +49,8 @@ LLCrashLookupWindows::LLCrashLookupWindows() hRes = m_pDbgClient->QueryInterface(__uuidof(IDebugSymbols2), (void**)&m_pDbgSymbols); if (FAILED(hRes)) return; + + m_pDbgClient->QueryInterface( __uuidof(IDebugClient4), (void**)&m_pDbgClient4 ); } } @@ -63,6 +66,10 @@ LLCrashLookupWindows::~LLCrashLookupWindows() m_pDbgControl->Release(); m_pDbgControl = NULL; } + + if( m_pDbgClient4 ) + m_pDbgClient4->Release(); + if (m_pDbgClient) { m_pDbgClient->Release(); @@ -83,8 +90,15 @@ bool LLCrashLookupWindows::initFromDump(const std::string& strDumpPath) if ( (!m_pDbgClient) || (!m_pDbgControl) || (!m_pDbgSymbols) ) return false; + std::wstring strDumpPathW = utf8str_to_utf16str( strDumpPath ); // Open the minidump and wait to finish processing - HRESULT hRes = m_pDbgClient->OpenDumpFile(strDumpPath.c_str()); + HRESULT hRes(S_OK); + + if( !m_pDbgClient4 ) + hRes = m_pDbgClient->OpenDumpFile (strDumpPath.c_str()); + else + hRes = m_pDbgClient4->OpenDumpFileWide (strDumpPathW.c_str(),0); + if (FAILED(hRes)) return false; m_pDbgControl->WaitForEvent(DEBUG_WAIT_DEFAULT, INFINITE); diff --git a/indra/win_crash_logger/llcrashlookupwindows.h b/indra/win_crash_logger/llcrashlookupwindows.h index c85d206dba..5a7e94b5d0 100644 --- a/indra/win_crash_logger/llcrashlookupwindows.h +++ b/indra/win_crash_logger/llcrashlookupwindows.h @@ -39,6 +39,7 @@ public: protected: IDebugClient* m_pDbgClient; + IDebugClient4* m_pDbgClient4; IDebugControl4* m_pDbgControl; IDebugSymbols2* m_pDbgSymbols; };