macOS: put assertion message into crash reporter dialog.
This commit makes FatalError a GUI-dependent function.
This commit is contained in:
parent
eb5501ecd6
commit
a93283df9d
@ -13,6 +13,11 @@ static System SYS;
|
||||
|
||||
static int IsInit = 0;
|
||||
|
||||
void SolveSpace::Platform::FatalError(std::string message) {
|
||||
fprintf(stderr, "%s", message.c_str());
|
||||
abort();
|
||||
}
|
||||
|
||||
void Group::GenerateEquations(IdList<Equation,hEquation> *) {
|
||||
// Nothing to do for now.
|
||||
}
|
||||
|
@ -76,6 +76,12 @@ std::string AcceleratorDescription(const KeyboardEvent &accel);
|
||||
// Interfaces
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
// Handling fatal errors.
|
||||
#if defined(__GNUC__)
|
||||
__attribute__((noreturn))
|
||||
#endif
|
||||
void FatalError(std::string message);
|
||||
|
||||
// A native settings store.
|
||||
class Settings {
|
||||
public:
|
||||
|
@ -25,6 +25,15 @@
|
||||
namespace SolveSpace {
|
||||
namespace Platform {
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Fatal errors
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
void FatalError(std::string message) {
|
||||
fprintf(stderr, "%s", message.c_str());
|
||||
abort();
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Settings
|
||||
//-----------------------------------------------------------------------------
|
||||
|
@ -52,6 +52,33 @@ static NSString* Wrap(const std::string &s) {
|
||||
namespace SolveSpace {
|
||||
namespace Platform {
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Fatal errors
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
// This gets put into the "Application Specific Information" field in crash
|
||||
// reporter dialog.
|
||||
typedef struct {
|
||||
unsigned version __attribute__((aligned(8)));
|
||||
const char *message __attribute__((aligned(8)));
|
||||
const char *signature __attribute__((aligned(8)));
|
||||
const char *backtrace __attribute__((aligned(8)));
|
||||
const char *message2 __attribute__((aligned(8)));
|
||||
void *reserved __attribute__((aligned(8)));
|
||||
void *reserved2 __attribute__((aligned(8)));
|
||||
} crash_info_t;
|
||||
|
||||
#define CRASH_VERSION 4
|
||||
|
||||
crash_info_t crashAnnotation __attribute__((section("__DATA,__crash_info"))) = {
|
||||
CRASH_VERSION, NULL, NULL, NULL, NULL, NULL, NULL
|
||||
};
|
||||
|
||||
void FatalError(std::string message) {
|
||||
crashAnnotation.message = message.c_str();
|
||||
abort();
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Settings
|
||||
//-----------------------------------------------------------------------------
|
||||
|
@ -18,6 +18,35 @@ std::shared_ptr<ViewportCanvas> CreateRenderer() {
|
||||
|
||||
namespace Platform {
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Fatal errors
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
void FatalError(std::string message) {
|
||||
fprintf(stderr, "%s", message.c_str());
|
||||
|
||||
#if !defined(LIBRARY) && defined(HAVE_BACKTRACE)
|
||||
static void *ptrs[1024] = {};
|
||||
size_t nptrs = backtrace(ptrs, sizeof(ptrs) / sizeof(ptrs[0]));
|
||||
char **syms = backtrace_symbols(ptrs, nptrs);
|
||||
|
||||
fprintf(stderr, "Backtrace:\n");
|
||||
if(syms != NULL) {
|
||||
for(size_t i = 0; i < nptrs; i++) {
|
||||
fprintf(stderr, "%2zu: %s\n", i, syms[i]);
|
||||
}
|
||||
} else {
|
||||
for(size_t i = 0; i < nptrs; i++) {
|
||||
fprintf(stderr, "%2zu: %p\n", i, ptrs[i]);
|
||||
}
|
||||
}
|
||||
#else
|
||||
fprintf(stderr, "Backtrace support not compiled in.\n");
|
||||
#endif
|
||||
|
||||
abort();
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Settings
|
||||
//-----------------------------------------------------------------------------
|
||||
|
@ -9,6 +9,7 @@
|
||||
#include <windows.h>
|
||||
#include <windowsx.h>
|
||||
#include <commctrl.h>
|
||||
#include <shellapi.h>
|
||||
|
||||
#ifndef WM_DPICHANGED
|
||||
#define WM_DPICHANGED 0x02E0
|
||||
@ -102,6 +103,34 @@ static int Clamp(int x, int a, int b) {
|
||||
return max(a, min(x, b));
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Fatal errors
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
bool handlingFatalError = false;
|
||||
|
||||
void FatalError(std::string message) {
|
||||
// Indicate that we're handling a fatal error, to avoid re-entering application code
|
||||
// and potentially crashing even harder.
|
||||
handlingFatalError = true;
|
||||
|
||||
message += "\nGenerate debug report?";
|
||||
switch(MessageBoxW(NULL, Platform::Widen(message).c_str(),
|
||||
L"Fatal error — SolveSpace",
|
||||
MB_ICONERROR|MB_TASKMODAL|MB_SETFOREGROUND|MB_TOPMOST|
|
||||
MB_OKCANCEL|MB_DEFBUTTON2)) {
|
||||
case IDOK:
|
||||
abort();
|
||||
|
||||
case IDCANCEL:
|
||||
default: {
|
||||
WCHAR appPath[MAX_PATH] = {};
|
||||
GetModuleFileNameW(NULL, appPath, sizeof(appPath));
|
||||
ShellExecuteW(NULL, L"open", appPath, NULL, NULL, SW_SHOW);
|
||||
_exit(1);
|
||||
}
|
||||
}
|
||||
}
|
||||
//-----------------------------------------------------------------------------
|
||||
// Settings
|
||||
//-----------------------------------------------------------------------------
|
||||
|
@ -9,13 +9,6 @@
|
||||
|
||||
namespace Platform {
|
||||
|
||||
// Handling fatal errors.
|
||||
#if defined(__GNUC__)
|
||||
__attribute__((noreturn))
|
||||
#endif
|
||||
void FatalError(std::string message);
|
||||
extern bool handlingFatalError;
|
||||
|
||||
// UTF-8 ⟷ UTF-16 conversion, for Windows.
|
||||
#if defined(WIN32)
|
||||
std::string Narrow(const wchar_t *s);
|
||||
|
@ -27,35 +27,6 @@ void dbp(const char *str, ...)
|
||||
fputc('\n', stderr);
|
||||
}
|
||||
|
||||
namespace Platform {
|
||||
|
||||
void FatalError(std::string message) {
|
||||
fprintf(stderr, "%s", message.c_str());
|
||||
|
||||
#if !defined(LIBRARY) && defined(HAVE_BACKTRACE)
|
||||
static void *ptrs[1024] = {};
|
||||
size_t nptrs = backtrace(ptrs, sizeof(ptrs) / sizeof(ptrs[0]));
|
||||
char **syms = backtrace_symbols(ptrs, nptrs);
|
||||
|
||||
fprintf(stderr, "Backtrace:\n");
|
||||
if(syms != NULL) {
|
||||
for(size_t i = 0; i < nptrs; i++) {
|
||||
fprintf(stderr, "%2zu: %s\n", i, syms[i]);
|
||||
}
|
||||
} else {
|
||||
for(size_t i = 0; i < nptrs; i++) {
|
||||
fprintf(stderr, "%2zu: %p\n", i, ptrs[i]);
|
||||
}
|
||||
}
|
||||
#else
|
||||
fprintf(stderr, "Backtrace support not compiled in.\n");
|
||||
#endif
|
||||
|
||||
abort();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// A separate heap, on which we allocate expressions. Maybe a bit faster,
|
||||
// since fragmentation is less of a concern, and it also makes it possible
|
||||
|
@ -35,35 +35,6 @@ void dbp(const char *str, ...)
|
||||
#endif
|
||||
}
|
||||
|
||||
namespace Platform {
|
||||
|
||||
bool handlingFatalError = false;
|
||||
|
||||
void FatalError(std::string message) {
|
||||
// Indicate that we're handling a fatal error, to avoid re-entering application code
|
||||
// and potentially crashing even harder.
|
||||
handlingFatalError = true;
|
||||
|
||||
message += "\nGenerate debug report?";
|
||||
switch(MessageBoxW(NULL, Platform::Widen(message).c_str(),
|
||||
L"Fatal error — SolveSpace",
|
||||
MB_ICONERROR|MB_TASKMODAL|MB_SETFOREGROUND|MB_TOPMOST|
|
||||
MB_OKCANCEL|MB_DEFBUTTON2)) {
|
||||
case IDOK:
|
||||
abort();
|
||||
|
||||
case IDCANCEL:
|
||||
default: {
|
||||
WCHAR appPath[MAX_PATH] = {};
|
||||
GetModuleFileNameW(NULL, appPath, sizeof(appPath));
|
||||
ShellExecuteW(NULL, L"open", appPath, NULL, NULL, SW_SHOW);
|
||||
_exit(1);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// A separate heap, on which we allocate expressions. Maybe a bit faster,
|
||||
// since no fragmentation issues whatsoever, and it also makes it possible
|
||||
|
Loading…
Reference in New Issue
Block a user