Properly handle unicode paths in crashlogging (Windows).

master
Nicky 2013-06-19 00:29:52 +02:00
parent c9c14a1aaf
commit b5e8e3025a
4 changed files with 127 additions and 23 deletions

View File

@ -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));
// <FS:ND> 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) );
// </FS:ND>
#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
// <FS:ND> 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;
}
}
}
// </FS:ND>
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<size_t>(remaining));
remaining -= bytesUsed;
path += bytesUsed;
if(remaining > 0 && bytesUsed > 0 && path[-1] != '\\')
// <FS:ND> 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<size_t>(remaining));
// remaining -= bytesUsed;
// path += bytesUsed;
// if(remaining > 0 && bytesUsed > 0 && path[-1] != '\\')
// {
// *path++ = '\\';
// --remaining;
// }
// if(remaining > 0)
// {
// bytesUsed = wcstombs(path, minidump_id, static_cast<size_t>(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<size_t>(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;
// <FS:ND>
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);

View File

@ -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");
// <FS:ND> 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
// </FS:ND>
// 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();

View File

@ -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);

View File

@ -39,6 +39,7 @@ public:
protected:
IDebugClient* m_pDbgClient;
IDebugClient4* m_pDbgClient4;
IDebugControl4* m_pDbgControl;
IDebugSymbols2* m_pDbgSymbols;
};