Add Win32 backtrace generator for temporary deployment-debugging

This commit is contained in:
Jack Andersen 2016-05-31 12:09:38 -10:00
parent d26a550ef8
commit 8edf43ad6e
4 changed files with 96 additions and 9 deletions

View File

@ -30,6 +30,58 @@ static inline void SNPrintf(boo::SystemChar* str, size_t maxlen, const boo::Syst
va_end(va); va_end(va);
} }
#if _WIN32
#include <DbgHelp.h>
#pragma comment(lib, "Dbghelp.lib")
#include <signal.h>
static void abortHandler( int signum )
{
unsigned int i;
void * stack[ 100 ];
unsigned short frames;
SYMBOL_INFO * symbol;
HANDLE process;
process = GetCurrentProcess();
SymInitialize( process, NULL, TRUE );
frames = CaptureStackBackTrace( 0, 100, stack, NULL );
symbol = ( SYMBOL_INFO * )calloc( sizeof( SYMBOL_INFO ) + 256 * sizeof( char ), 1 );
symbol->MaxNameLen = 255;
symbol->SizeOfStruct = sizeof( SYMBOL_INFO );
for( i = 0; i < frames; i++ )
{
SymFromAddr( process, ( DWORD64 )( stack[ i ] ), 0, symbol );
printf( "%i: %s - 0x%0llX", frames - i - 1, symbol->Name, symbol->Address );
DWORD dwDisplacement;
IMAGEHLP_LINE64 line;
SymSetOptions(SYMOPT_LOAD_LINES);
line.SizeOfStruct = sizeof(IMAGEHLP_LINE64);
if (SymGetLineFromAddr64(process, ( DWORD64 )( stack[ i ] ), &dwDisplacement, &line))
{
// SymGetLineFromAddr64 returned success
printf(" LINE %d\n", line.LineNumber);
}
else
{
printf("\n");
}
}
free( symbol );
// If you caught one of the above signals, it is likely you just
// want to quit your program right now.
system("PAUSE");
exit( signum );
}
#endif
struct AppCallback; struct AppCallback;
struct EventCallback : boo::IWindowCallback struct EventCallback : boo::IWindowCallback
@ -566,7 +618,10 @@ struct AppCallback : boo::IApplicationCallback
/* Load data */ /* Load data */
if (m_argc < 2) if (m_argc < 2)
Log.report(logvisor::Fatal, "needs group path argument"); {
Log.report(logvisor::Error, "needs group path argument");
exit(1);
}
#if _WIN32 #if _WIN32
char utf8Path[1024]; char utf8Path[1024];
@ -577,13 +632,19 @@ struct AppCallback : boo::IApplicationCallback
amuse::ContainerRegistry::Type cType = amuse::ContainerRegistry::DetectContainerType(utf8Path); amuse::ContainerRegistry::Type cType = amuse::ContainerRegistry::DetectContainerType(utf8Path);
if (cType == amuse::ContainerRegistry::Type::Invalid) if (cType == amuse::ContainerRegistry::Type::Invalid)
Log.report(logvisor::Fatal, "invalid/no data at path argument"); {
Log.report(logvisor::Error, "invalid/no data at path argument");
exit(1);
}
Log.report(logvisor::Info, "Found '%s' Audio Group data", amuse::ContainerRegistry::TypeToName(cType)); Log.report(logvisor::Info, "Found '%s' Audio Group data", amuse::ContainerRegistry::TypeToName(cType));
std::vector<std::pair<std::string, amuse::IntrusiveAudioGroupData>> data = std::vector<std::pair<std::string, amuse::IntrusiveAudioGroupData>> data =
amuse::ContainerRegistry::LoadContainer(utf8Path); amuse::ContainerRegistry::LoadContainer(utf8Path);
if (data.empty()) if (data.empty())
Log.report(logvisor::Fatal, "invalid/no data at path argument"); {
Log.report(logvisor::Error, "invalid/no data at path argument");
exit(1);
}
std::list<amuse::AudioGroupProject> m_projs; std::list<amuse::AudioGroupProject> m_projs;
std::map<int, std::pair<std::pair<std::string, amuse::IntrusiveAudioGroupData>*, const amuse::SongGroupIndex*>> allSongGroups; std::map<int, std::pair<std::pair<std::string, amuse::IntrusiveAudioGroupData>*, const amuse::SongGroupIndex*>> allSongGroups;
@ -612,7 +673,10 @@ struct AppCallback : boo::IApplicationCallback
else if (allSFXGroups.find(m_groupId) != allSFXGroups.end()) else if (allSFXGroups.find(m_groupId) != allSFXGroups.end())
m_sfxGroup = true; m_sfxGroup = true;
else else
Log.report(logvisor::Fatal, "unable to find Group %d", m_groupId); {
Log.report(logvisor::Error, "unable to find Group %d", m_groupId);
exit(1);
}
} }
else if (totalGroups > 1) else if (totalGroups > 1)
{ {
@ -634,7 +698,10 @@ struct AppCallback : boo::IApplicationCallback
int userSel = 0; int userSel = 0;
printf("Enter Group Number: "); printf("Enter Group Number: ");
if (scanf("%d", &userSel) <= 0) if (scanf("%d", &userSel) <= 0)
Log.report(logvisor::Fatal, "unable to parse prompt"); {
Log.report(logvisor::Error, "unable to parse prompt");
exit(1);
}
if (allSongGroups.find(userSel) != allSongGroups.end()) if (allSongGroups.find(userSel) != allSongGroups.end())
{ {
@ -647,7 +714,10 @@ struct AppCallback : boo::IApplicationCallback
m_sfxGroup = true; m_sfxGroup = true;
} }
else else
Log.report(logvisor::Fatal, "unable to find Group %d", userSel); {
Log.report(logvisor::Error, "unable to find Group %d", userSel);
exit(1);
}
} }
else if (totalGroups == 1) else if (totalGroups == 1)
{ {
@ -666,7 +736,10 @@ struct AppCallback : boo::IApplicationCallback
} }
} }
else else
Log.report(logvisor::Fatal, "empty project"); {
Log.report(logvisor::Error, "empty project");
exit(1);
}
/* Make final group selection */ /* Make final group selection */
amuse::IntrusiveAudioGroupData* selData = nullptr; amuse::IntrusiveAudioGroupData* selData = nullptr;
@ -689,7 +762,10 @@ struct AppCallback : boo::IApplicationCallback
} }
if (!selData) if (!selData)
Log.report(logvisor::Fatal, "unable to select audio group data"); {
Log.report(logvisor::Error, "unable to select audio group data");
exit(1);
}
/* Attempt loading song */ /* Attempt loading song */
@ -726,7 +802,10 @@ struct AppCallback : boo::IApplicationCallback
/* Load group into engine */ /* Load group into engine */
const amuse::AudioGroup* group = m_engine->addAudioGroup(*selData); const amuse::AudioGroup* group = m_engine->addAudioGroup(*selData);
if (!group) if (!group)
Log.report(logvisor::Fatal, "unable to add audio group"); {
Log.report(logvisor::Error, "unable to add audio group");
exit(1);
}
/* Enter playback loop */ /* Enter playback loop */
if (m_sfxGroup) if (m_sfxGroup)
@ -850,6 +929,11 @@ int main(int argc, const boo::SystemChar** argv)
#if _WIN32 #if _WIN32
int APIENTRY wWinMain(HINSTANCE hInstance, HINSTANCE, LPWSTR lpCmdLine, int) int APIENTRY wWinMain(HINSTANCE hInstance, HINSTANCE, LPWSTR lpCmdLine, int)
{ {
signal( SIGABRT, abortHandler );
signal( SIGSEGV, abortHandler );
signal( SIGILL, abortHandler );
signal( SIGFPE, abortHandler );
int argc = 0; int argc = 0;
const boo::SystemChar** argv = (const wchar_t**)(CommandLineToArgvW(lpCmdLine, &argc)); const boo::SystemChar** argv = (const wchar_t**)(CommandLineToArgvW(lpCmdLine, &argc));
static boo::SystemChar selfPath[1024]; static boo::SystemChar selfPath[1024];

View File

@ -56,6 +56,7 @@ public:
return static_cast<ImpType&>(*m_effectStack.back()); return static_cast<ImpType&>(*m_effectStack.back());
} }
case SubmixFormat::Int32: case SubmixFormat::Int32:
default:
{ {
using ImpType = typename T::template ImpType<int32_t>; using ImpType = typename T::template ImpType<int32_t>;
m_effectStack.emplace_back(new ImpType(args..., m_backendSubmix->getSampleRate())); m_effectStack.emplace_back(new ImpType(args..., m_backendSubmix->getSampleRate()));

View File

@ -457,6 +457,7 @@ AudioGroupProject AudioGroupProject::CreateAudioGroupProject(const AudioGroupDat
switch (data.getDataFormat()) switch (data.getDataFormat())
{ {
case DataFormat::GCN: case DataFormat::GCN:
default:
return AudioGroupProject(data.getProj(), GCNDataTag{}); return AudioGroupProject(data.getProj(), GCNDataTag{});
case DataFormat::N64: case DataFormat::N64:
return AudioGroupProject(data.getProj(), data.getAbsoluteProjOffsets(), N64DataTag{}); return AudioGroupProject(data.getProj(), data.getAbsoluteProjOffsets(), N64DataTag{});

View File

@ -97,6 +97,7 @@ float Envelope::advance(double dt)
return std::min(m_releaseStartFactor, 1.0 - releaseFac); return std::min(m_releaseStartFactor, 1.0 - releaseFac);
} }
case State::Complete: case State::Complete:
default:
return 0.f; return 0.f;
} }
} }