always print stack information on errors
This commit is contained in:
parent
9567787af2
commit
2d98fbb90c
3 changed files with 122 additions and 51 deletions
src
68
src/include/st_backtrace.h
Normal file
68
src/include/st_backtrace.h
Normal file
|
@ -0,0 +1,68 @@
|
|||
#ifndef ST_BACKTRACE_H
|
||||
#define ST_BACKTRACE_H 1
|
||||
|
||||
#include "stdio.h"
|
||||
|
||||
#ifdef __GLIBC__
|
||||
|
||||
#include "execinfo.h"
|
||||
inline void print_backtrace(void) {
|
||||
int j, nptrs;
|
||||
void *buffer[100];
|
||||
nptrs = backtrace(buffer, 100);
|
||||
fprintf(stderr, "backtrace() returned %d addresses\n", nptrs);
|
||||
backtrace_symbols_fd(buffer, 100, 2);
|
||||
}
|
||||
|
||||
#elif defined(USE_WIN32)
|
||||
|
||||
#include "windows.h"
|
||||
#include "dbghelp.h"
|
||||
#include "process.h"
|
||||
|
||||
inline void print_backtrace(void) {
|
||||
unsigned int i;
|
||||
void *stack[100];
|
||||
unsigned short frames;
|
||||
SYMBOL_INFO *symbol;
|
||||
HANDLE process;
|
||||
DWORD displacement;
|
||||
IMAGEHLP_LINE64 *line;
|
||||
char* name;
|
||||
|
||||
process = GetCurrentProcess();
|
||||
SymInitialize(process, NULL, TRUE);
|
||||
frames = CaptureStackBackTrace(0, 100, stack, NULL);
|
||||
fprintf(stderr, "backtrace returned %d addresses\n", frames);
|
||||
symbol = (SYMBOL_INFO*)calloc(sizeof(SYMBOL_INFO) + 256 * sizeof(char), 1);
|
||||
symbol->MaxNameLen = 1024;
|
||||
symbol->SizeOfStruct = sizeof(SYMBOL_INFO);
|
||||
|
||||
line = (IMAGEHLP_LINE64 *)malloc(sizeof(IMAGEHLP_LINE64));
|
||||
line->SizeOfStruct = sizeof(IMAGEHLP_LINE64);
|
||||
|
||||
for(i = 0; i < frames; i++) {
|
||||
SymFromAddr(process, (DWORD64)(stack[i]), 0, symbol);
|
||||
if (symbol->Name) {
|
||||
name = symbol->Name;
|
||||
} else {
|
||||
name = "<unknown frame>";
|
||||
}
|
||||
if (SymGetLineFromAddr64(process, (DWORD64)(stack[i]), &displacement, line)) {
|
||||
fprintf("%d: %s in %s:%d 0x%x\n", frames - i - 1, name, line->FileName, line->LineNumber, symbol->Address);
|
||||
} else {
|
||||
fprintf("%d: %s 0x%x\n", frames - i - 1, name, symbol->Address);
|
||||
}
|
||||
}
|
||||
free(symbol);
|
||||
}
|
||||
|
||||
#else
|
||||
|
||||
inline void print_backtrace(void) {
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
#endif
|
|
@ -210,6 +210,8 @@ extern void beos_init(int argc, char **argv);
|
|||
#include <stdexcept>
|
||||
#include <stacktrace/call_stack.hpp>
|
||||
#include <stacktrace/stack_exception.hpp>
|
||||
#else
|
||||
#include "st_backtrace.h"
|
||||
#endif
|
||||
|
||||
#include <stdlib.h>
|
||||
|
@ -434,6 +436,8 @@ void ExitFatal(int err)
|
|||
{
|
||||
#ifdef USE_STACKTRACE
|
||||
throw stacktrace::stack_runtime_error((const char*)err);
|
||||
#else
|
||||
print_backtrace();
|
||||
#endif
|
||||
exit(err);
|
||||
}
|
||||
|
@ -577,7 +581,7 @@ void ParseCommandLine(int argc, char **argv, Parameters ¶meters)
|
|||
if (ZoomNoResize) {
|
||||
fprintf(stderr, "Error: -Z only works with OpenGL enabled\n");
|
||||
Usage();
|
||||
ExitFatal(-1);
|
||||
exit(-1);
|
||||
}
|
||||
continue;
|
||||
case 'O':
|
||||
|
@ -605,7 +609,7 @@ void ParseCommandLine(int argc, char **argv, Parameters ¶meters)
|
|||
if (!sep || !*(sep + 1)) {
|
||||
fprintf(stderr, "%s: incorrect format of video mode resolution -- '%s'\n", argv[0], optarg);
|
||||
Usage();
|
||||
ExitFatal(-1);
|
||||
exit(-1);
|
||||
}
|
||||
Video.ViewportHeight = atoi(sep + 1);
|
||||
*sep = 0;
|
||||
|
@ -613,7 +617,7 @@ void ParseCommandLine(int argc, char **argv, Parameters ¶meters)
|
|||
if (!Video.ViewportHeight || !Video.ViewportWidth) {
|
||||
fprintf(stderr, "%s: incorrect format of video mode resolution -- '%sx%s'\n", argv[0], optarg, sep + 1);
|
||||
Usage();
|
||||
ExitFatal(-1);
|
||||
exit(-1);
|
||||
}
|
||||
#if defined(USE_OPENGL) || defined(USE_GLES)
|
||||
if (!ZoomNoResize) {
|
||||
|
@ -647,7 +651,7 @@ void ParseCommandLine(int argc, char **argv, Parameters ¶meters)
|
|||
if (!sep || !*(sep + 1)) {
|
||||
fprintf(stderr, "%s: incorrect format of video mode resolution -- '%s'\n", argv[0], optarg);
|
||||
Usage();
|
||||
ExitFatal(-1);
|
||||
exit(-1);
|
||||
}
|
||||
Video.Height = atoi(sep + 1);
|
||||
*sep = 0;
|
||||
|
@ -660,7 +664,7 @@ void ParseCommandLine(int argc, char **argv, Parameters ¶meters)
|
|||
case 'h':
|
||||
default:
|
||||
Usage();
|
||||
ExitFatal(-1);
|
||||
exit(-1);
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
@ -731,72 +735,69 @@ int stratagusMain(int argc, char **argv)
|
|||
Assert(pathPtr);
|
||||
StratagusLibPath = pathPtr;
|
||||
#endif
|
||||
#ifdef USE_STACKTRACE
|
||||
try {
|
||||
#endif
|
||||
Parameters ¶meters = Parameters::Instance;
|
||||
parameters.SetDefaultValues();
|
||||
parameters.SetLocalPlayerNameFromEnv();
|
||||
Parameters ¶meters = Parameters::Instance;
|
||||
parameters.SetDefaultValues();
|
||||
parameters.SetLocalPlayerNameFromEnv();
|
||||
|
||||
#ifdef REDIRECT_OUTPUT
|
||||
RedirectOutput();
|
||||
RedirectOutput();
|
||||
#endif
|
||||
|
||||
if (argc > 0) {
|
||||
parameters.applicationName = argv[0];
|
||||
}
|
||||
if (argc > 0) {
|
||||
parameters.applicationName = argv[0];
|
||||
}
|
||||
|
||||
// FIXME: Parse options before or after scripts?
|
||||
ParseCommandLine(argc, argv, parameters);
|
||||
// Init the random number generator.
|
||||
InitSyncRand();
|
||||
// FIXME: Parse options before or after scripts?
|
||||
ParseCommandLine(argc, argv, parameters);
|
||||
// Init the random number generator.
|
||||
InitSyncRand();
|
||||
|
||||
makedir(parameters.GetUserDirectory().c_str(), 0777);
|
||||
makedir(parameters.GetUserDirectory().c_str(), 0777);
|
||||
|
||||
// Init Lua and register lua functions!
|
||||
InitLua();
|
||||
LuaRegisterModules();
|
||||
// Init Lua and register lua functions!
|
||||
InitLua();
|
||||
LuaRegisterModules();
|
||||
|
||||
// Initialise AI module
|
||||
InitAiModule();
|
||||
// Initialise AI module
|
||||
InitAiModule();
|
||||
|
||||
LoadCcl(parameters.luaStartFilename, parameters.luaScriptArguments);
|
||||
LoadCcl(parameters.luaStartFilename, parameters.luaScriptArguments);
|
||||
|
||||
PrintHeader();
|
||||
PrintLicense();
|
||||
PrintHeader();
|
||||
PrintLicense();
|
||||
|
||||
// Setup video display
|
||||
InitVideo();
|
||||
// Setup video display
|
||||
InitVideo();
|
||||
|
||||
// Setup sound card
|
||||
if (!InitSound()) {
|
||||
InitMusic();
|
||||
}
|
||||
// Setup sound card
|
||||
if (!InitSound()) {
|
||||
InitMusic();
|
||||
}
|
||||
|
||||
#ifndef DEBUG // For debug it's better not to have:
|
||||
srand(time(NULL)); // Random counter = random each start
|
||||
srand(time(NULL)); // Random counter = random each start
|
||||
#endif
|
||||
|
||||
// Show title screens.
|
||||
SetDefaultTextColors(FontYellow, FontWhite);
|
||||
LoadFonts();
|
||||
SetClipping(0, 0, Video.Width - 1, Video.Height - 1);
|
||||
Video.ClearScreen();
|
||||
ShowTitleScreens();
|
||||
// Show title screens.
|
||||
SetDefaultTextColors(FontYellow, FontWhite);
|
||||
LoadFonts();
|
||||
SetClipping(0, 0, Video.Width - 1, Video.Height - 1);
|
||||
Video.ClearScreen();
|
||||
ShowTitleScreens();
|
||||
|
||||
// Init player data
|
||||
ThisPlayer = NULL;
|
||||
//Don't clear the Players structure as it would erase the allowed units.
|
||||
// memset(Players, 0, sizeof(Players));
|
||||
NumPlayers = 0;
|
||||
// Init player data
|
||||
ThisPlayer = NULL;
|
||||
//Don't clear the Players structure as it would erase the allowed units.
|
||||
// memset(Players, 0, sizeof(Players));
|
||||
NumPlayers = 0;
|
||||
|
||||
UnitManager.Init(); // Units memory management
|
||||
PreMenuSetup(); // Load everything needed for menus
|
||||
UnitManager.Init(); // Units memory management
|
||||
PreMenuSetup(); // Load everything needed for menus
|
||||
|
||||
MenuLoop();
|
||||
MenuLoop();
|
||||
|
||||
Exit(0);
|
||||
#ifdef USE_STACKTRACE
|
||||
Exit(0);
|
||||
} catch (const std::exception &e) {
|
||||
fprintf(stderr, "Stratagus crashed!\n");
|
||||
fprintf(stderr, "Please send this call stack to our bug tracker: https://github.com/Wargus/stratagus/issues\n");
|
||||
|
@ -805,7 +806,6 @@ int stratagusMain(int argc, char **argv)
|
|||
fprintf(stderr, "%s", e.what());
|
||||
exit(1);
|
||||
}
|
||||
#endif
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
|
|
@ -45,6 +45,8 @@
|
|||
#include <stdexcept>
|
||||
#include <stacktrace/call_stack.hpp>
|
||||
#include <stacktrace/stack_exception.hpp>
|
||||
#else
|
||||
#include "st_backtrace.h"
|
||||
#endif
|
||||
|
||||
#ifdef USE_X11
|
||||
|
@ -530,6 +532,7 @@ void AbortAt(const char *file, int line, const char *funcName, const char *condi
|
|||
throw stacktrace::stack_runtime_error((const char*)buf);
|
||||
#else
|
||||
fprintf(stderr, "%s\n", buf);
|
||||
print_backtrace();
|
||||
#endif
|
||||
fflush(stdout);
|
||||
fflush(stderr);
|
||||
|
|
Loading…
Add table
Reference in a new issue