Skip to content

Commit

Permalink
Deadly little 64bit bug cured
Browse files Browse the repository at this point in the history
... and made crash dumps possible if needed
  • Loading branch information
Arakula committed Jan 4, 2022
1 parent 9c45261 commit 1799e54
Showing 1 changed file with 181 additions and 4 deletions.
185 changes: 181 additions & 4 deletions vsthost/vsthost.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,8 @@
#include "stdafx.h"

// #define LOG_EXCHANGE
// #define LOG
// #define MINIDUMP

enum
{
Expand All @@ -19,6 +21,33 @@ static HANDLE null_file = NULL;
static HANDLE pipe_in = NULL;
static HANDLE pipe_out = NULL;


#ifdef LOG
void Log(LPCTSTR szFormat, ...)
{
static FILE *fpLog = NULL;
va_list l;
va_start(l, szFormat);

if (!fpLog)
{
TCHAR logfile[MAX_PATH];
GetEnvironmentVariable(_T("TEMP"), logfile, _countof(logfile));
lstrcat(logfile, _T("\\vsthost.log"));
fpLog = _tfopen( logfile, _T("a") );
}
if (fpLog)
{
_vftprintf(fpLog, szFormat, l);
fflush(fpLog); // make sure it's out!
}
va_end(l);
}
#else
void NoLog(LPCTSTR szFormat, ...) {}
#define Log while(0) NoLog
#endif

struct myVstEvent
{
struct myVstEvent * next;
Expand Down Expand Up @@ -290,6 +319,138 @@ static VstIntPtr VSTCALLBACK audioMaster( AEffect * effect, VstInt32 opcode, Vst
return 0;
}

#ifdef MINIDUMP
/*****************************************************************************/
/* LoadMiniDump : tries to load minidump functionality */
/*****************************************************************************/

#include <dbghelp.h>
typedef BOOL (__stdcall *PMiniDumpWriteDump)(IN HANDLE hProcess, IN DWORD ProcessId, IN HANDLE hFile, IN MINIDUMP_TYPE DumpType, IN CONST PMINIDUMP_EXCEPTION_INFORMATION ExceptionParam, OPTIONAL IN CONST PMINIDUMP_USER_STREAM_INFORMATION UserStreamParam, OPTIONAL IN CONST PMINIDUMP_CALLBACK_INFORMATION CallbackParam OPTIONAL);
static PMiniDumpWriteDump pMiniDumpWriteDump = NULL;
static TCHAR szExeName[_MAX_PATH] = _T("");
bool LoadMiniDump()
{
static HMODULE hmodDbgHelp = NULL;

if (!pMiniDumpWriteDump && !hmodDbgHelp)
{
TCHAR szBuf[_MAX_PATH];
szBuf[0] = _T('\0');
::GetEnvironmentVariable(_T("ProgramFiles"), szBuf, MAX_PATH);
UINT omode = SetErrorMode(SEM_FAILCRITICALERRORS | SEM_NOOPENFILEERRORBOX);
TCHAR *p = szBuf + lstrlen(szBuf);
if (*szBuf && !hmodDbgHelp)
{
#ifdef _M_IX86
lstrcpy(p, _T("\\Debugging Tools for Windows (x86)\\dbghelp.dll"));
#elif defined(_M_X64)
lstrcpy(p, _T("\\Debugging Tools for Windows (x64)\\dbghelp.dll"));
#endif
if (!(hmodDbgHelp = LoadLibrary(szBuf))) *p = '\0';
}
if (*szBuf && !hmodDbgHelp)
{
lstrcpy(p, _T("\\Debugging Tools for Windows\\dbghelp.dll"));
if (!(hmodDbgHelp = LoadLibrary(szBuf))) *p = '\0';
}
#if defined _M_X64
if (*szBuf && !hmodDbgHelp) /* still not found? */
{ /* try 64-bit version */
lstrcpy(p, _T("\\Debugging Tools for Windows 64-Bit\\dbghelp.dll"));
if (!(hmodDbgHelp = LoadLibrary(szBuf))) *p = '\0';
}
#endif
if (!hmodDbgHelp) // if not already loaded, try to load a default-one
hmodDbgHelp = LoadLibrary(_T("dbghelp.dll"));
SetErrorMode(omode);

if (!hmodDbgHelp) /* if STILL not loaded, */
return false; /* return with error */

pMiniDumpWriteDump = (PMiniDumpWriteDump)GetProcAddress(hmodDbgHelp, "MiniDumpWriteDump");
}
if (!pMiniDumpWriteDump)
return false;

if (!*szExeName)
{
TCHAR szPath[_MAX_PATH];
TCHAR *lbsl = NULL, *ldot = NULL;
lstrcpy(szExeName, _T("vsthost"));
GetModuleFileName(NULL, szPath, _MAX_PATH);
for (TCHAR *p = szPath; *p; p++)
if (*p == _T('\\'))
lbsl = p;
else if (*p == _T('.'))
ldot = p;
if (lbsl && ldot && ldot > lbsl + 1)
{
TCHAR *s, *t;
for (s = lbsl + 1, t = szExeName; s != ldot; s++)
*t++ = *s;
*t = _T('\0');
}
}

return true;
}

/*****************************************************************************/
/* MiniDump : writes out a minidump */
/*****************************************************************************/

void MiniDump(EXCEPTION_POINTERS *ExceptionInfo)
{
// all variables static so they're preallocated - stack might be damaged!
// doesn't catch everything, but should get most.
static TCHAR szPath[_MAX_PATH];
if (!pMiniDumpWriteDump)
{
Log(_T("MiniDump impossible!\n"));
return;
}

static DWORD dwExeLen;
dwExeLen = (DWORD)lstrlen(szExeName);
if (!(dwExeLen = GetTempPath(_countof(szPath) - dwExeLen - 21, szPath)) ||
(dwExeLen > _countof(szPath) - dwExeLen - 22))
{
Log(_T("TempPath allocation error 1\n"));
return;
}
static SYSTEMTIME st;
GetLocalTime(&st);
lstrcpy(szPath + dwExeLen, szExeName);
dwExeLen += (DWORD)lstrlen(szExeName);
wsprintf(szPath + dwExeLen, _T(".%04d%02d%02d-%02d%02d%02d.mdmp"),
szExeName,
st.wYear, st.wMonth, st.wDay,
st.wHour, st.wMinute, st.wSecond);
static HANDLE hFile; /* create the minidump file */
Log(_T("Dumping to %s ...\n"), szPath);
hFile = ::CreateFile(szPath,
GENERIC_WRITE, FILE_SHARE_WRITE,
NULL, CREATE_ALWAYS,
FILE_ATTRIBUTE_NORMAL, NULL );
if (hFile != INVALID_HANDLE_VALUE)
{
static _MINIDUMP_EXCEPTION_INFORMATION ExInfo = {0};
ExInfo.ThreadId = ::GetCurrentThreadId();
ExInfo.ExceptionPointers = ExceptionInfo;
pMiniDumpWriteDump(GetCurrentProcess(),
GetCurrentProcessId(),
hFile,
MiniDumpNormal,
&ExInfo,
NULL, NULL);
::CloseHandle(hFile);
Log(_T("Dumped to %s\n"), szPath);
}
else
Log(_T("Could not dump to %s!\n"), szPath);
}
#endif

LONG __stdcall myExceptFilterProc( LPEXCEPTION_POINTERS param )
{
if (IsDebuggerPresent())
Expand All @@ -298,7 +459,10 @@ LONG __stdcall myExceptFilterProc( LPEXCEPTION_POINTERS param )
}
else
{
//DumpCrashInfo( param );
#ifdef MINIDUMP
Log(_T("Dumping! pMiniDumpWriteDump=%p\nszExeName=%s\n"), pMiniDumpWriteDump, szExeName);
MiniDump(param);
#endif
TerminateProcess( GetCurrentProcess(), 0 );
return 0;// never reached
}
Expand Down Expand Up @@ -361,6 +525,10 @@ int CALLBACK _tWinMain( HINSTANCE hInstance, HINSTANCE hPrevInstance, LPTSTR lpC
if ( FAILED( CoInitialize( NULL ) ) ) return 5;

#ifndef _DEBUG
#ifdef MINIDUMP
LoadMiniDump();
Log(_T("pMiniDumpWriteDump=%p\nszExeName=%s\n"), pMiniDumpWriteDump, szExeName);
#endif
SetUnhandledExceptionFilter( myExceptFilterProc );
#endif

Expand Down Expand Up @@ -452,6 +620,8 @@ int CALLBACK _tWinMain( HINSTANCE hInstance, HINSTANCE hPrevInstance, LPTSTR lpC
uint32_t command = get_code();
if ( !command ) break;

Log(_T("Processing command %d\n"), (int)command);

switch ( command )
{
case 1: // Get Chunk
Expand Down Expand Up @@ -711,7 +881,7 @@ int CALLBACK _tWinMain( HINSTANCE hInstance, HINSTANCE hPrevInstance, LPTSTR lpC

if ( event_count[ 0 ] )
{
events[ 0 ] = ( VstEvents * ) malloc( sizeof(long) + sizeof(long) + sizeof(VstEvent*) * event_count[ 0 ] );
events[ 0 ] = ( VstEvents * ) malloc( sizeof(VstInt32) + sizeof(VstIntPtr) + sizeof(VstEvent*) * event_count[ 0 ] );

events[ 0 ]->numEvents = event_count[ 0 ];
events[ 0 ]->reserved = 0;
Expand All @@ -729,7 +899,7 @@ int CALLBACK _tWinMain( HINSTANCE hInstance, HINSTANCE hPrevInstance, LPTSTR lpC

if ( event_count[ 1 ] )
{
events[ 1 ] = ( VstEvents * ) malloc( sizeof(long) + sizeof(long) + sizeof(VstEvent*) * event_count[ 1 ] );
events[ 1 ] = ( VstEvents * ) malloc( sizeof(VstInt32) + sizeof(VstIntPtr) + sizeof(VstEvent*) * event_count[ 1 ] );

events[ 1 ]->numEvents = event_count[ 1 ];
events[ 1 ]->reserved = 0;
Expand All @@ -747,7 +917,7 @@ int CALLBACK _tWinMain( HINSTANCE hInstance, HINSTANCE hPrevInstance, LPTSTR lpC

if ( event_count[ 2 ] )
{
events[ 2 ] = ( VstEvents * ) malloc( sizeof(long) + sizeof(long) + sizeof(VstEvent*) * event_count[ 2 ] );
events[ 2 ] = ( VstEvents * ) malloc( sizeof(VstInt32) + sizeof(VstIntPtr) + sizeof(VstEvent*) * event_count[ 2 ] );

events[ 2 ]->numEvents = event_count[ 2 ];
events[ 2 ]->reserved = 0;
Expand All @@ -762,8 +932,10 @@ int CALLBACK _tWinMain( HINSTANCE hInstance, HINSTANCE hPrevInstance, LPTSTR lpC

pEffect[ 2 ]->dispatcher( pEffect[ 2 ], effProcessEvents, 0, 0, events[ 2 ], 0 );
}

}


if ( need_idle )
{
pEffect[ 0 ]->dispatcher( pEffect[ 0 ], DECLARE_VST_DEPRECATED (effIdle), 0, 0, 0, 0 );
Expand Down Expand Up @@ -842,6 +1014,9 @@ int CALLBACK _tWinMain( HINSTANCE hInstance, HINSTANCE hPrevInstance, LPTSTR lpC
goto exit;
break;
}

Log(_T("Command %d done\n"), (int)command);

}

exit:
Expand Down Expand Up @@ -876,5 +1051,7 @@ int CALLBACK _tWinMain( HINSTANCE hInstance, HINSTANCE hPrevInstance, LPTSTR lpC
SetStdHandle( STD_OUTPUT_HANDLE, pipe_out );
}

Log(_T("Exit with code %d\n"), code);

return code;
}

0 comments on commit 1799e54

Please sign in to comment.