Use the error dialog window, like on Windows, instead of xmessage from 1865

This commit is contained in:
Magnus Norddahl 2025-04-21 01:05:24 +02:00
commit 1312772e8b
2 changed files with 132 additions and 1 deletions

View file

@ -119,6 +119,7 @@ static void gdb_info(pid_t pid)
strcpy(respfile, "gdb-respfile-XXXXXX");
if((fd=mkstemp(respfile)) >= 0 && (f=fdopen(fd, "w")) != NULL)
{
#ifdef WHY_IS_EVERYTHING_ON_LINUX_ALWAYS_SPAMMING_THE_POOR_USER_WITH_GARBAGE
fprintf(f, "attach %d\n"
"shell echo \"\"\n"
"shell echo \"* Loaded Libraries\"\n"
@ -137,11 +138,19 @@ static void gdb_info(pid_t pid)
"thread apply all backtrace full\n"
"detach\n"
"quit\n", pid);
#else
fprintf(f, "attach %d\n"
"bt\n"
"detach\n"
"quit\n", pid);
#endif
fclose(f);
/* Run gdb and print process info. */
snprintf(cmd_buf, sizeof(cmd_buf), "gdb --quiet --batch --command=%s", respfile);
#ifdef WHY_IS_EVERYTHING_ON_LINUX_ALWAYS_SPAMMING_THE_POOR_USER_WITH_GARBAGE
printf("Executing: %s\n", cmd_buf);
#endif
fflush(stdout);
system(cmd_buf);
@ -258,9 +267,12 @@ static void crash_catcher(int signum, siginfo_t *siginfo, void *context)
}
}
const char *M_GetGameExe();
static void crash_handler(const char *logfile)
{
const char *sigdesc = "";
const char *dumpfile = "";
int i;
if(fread(&crash_info, sizeof(crash_info), 1, stdin) != 1)
@ -367,7 +379,9 @@ static void crash_handler(const char *logfile)
{
char buf[512];
if(I_FileAvailable("kdialog"))
if(I_FileAvailable(M_GetGameExe()))
snprintf(buf, sizeof(buf), "%s -showcrashreport \"%s\" \"%s\"", M_GetGameExe(), dumpfile, logfile);
else if(I_FileAvailable("kdialog"))
snprintf(buf, sizeof(buf), "kdialog --title \"Very Fatal Error\" --textbox \"%s\" 800 600", logfile);
else if(I_FileAvailable("gxmessage"))
snprintf(buf, sizeof(buf), "gxmessage -buttons \"Okay:0\" -geometry 800x600 -title \"Very Fatal Error\" -center -file \"%s\"", logfile);

View file

@ -238,3 +238,120 @@ FString M_GetNormalizedPath(const char* path)
return fullpath;
}
//===========================================================================
//
// Crashcatcher is a C file. Thanks a lot for that! Really appreciate the
// quality work. Here's some more that fits so nicely into the codebase...
//
//===========================================================================
#include <libgen.h>
#include <unistd.h>
#ifdef __APPLE__
#include <CoreFoundation/CoreFoundation.h>
#endif
#ifdef EXTERN___PROGNAME
extern const char *__progname;
#endif
std::string exe_path()
{
char exe_file[PATH_MAX];
#ifdef __APPLE__
CFBundleRef mainBundle = CFBundleGetMainBundle();
if (mainBundle)
{
CFURLRef mainURL = CFBundleCopyBundleURL(mainBundle);
if (mainURL)
{
int ok = CFURLGetFileSystemRepresentation (
mainURL, (Boolean) true, (UInt8*)exe_file, PATH_MAX
);
if (ok)
{
return std::string(exe_file) + "/";
}
}
}
throw Exception("get_exe_path failed");
#else
#ifndef PROC_EXE_PATH
#define PROC_EXE_PATH "/proc/self/exe"
#endif
int size;
struct stat sb;
if (lstat(PROC_EXE_PATH, &sb) < 0)
{
#ifdef EXTERN___PROGNAME
char *pathenv, *name, *end;
char fname[PATH_MAX];
char cwd[PATH_MAX];
struct stat sba;
exe_file[0] = '\0';
if ((pathenv = getenv("PATH")) != nullptr)
{
for (name = pathenv; name; name = end)
{
if ((end = strchr(name, ':')))
*end++ = '\0';
snprintf(fname, sizeof(fname),
"%s/%s", name, (char *)__progname);
if (stat(fname, &sba) == 0) {
snprintf(exe_file, sizeof(exe_file),
"%s/", name);
break;
}
}
}
// if getenv failed or path still not found
// try current directory as last resort
if (!exe_file[0])
{
if (getcwd(cwd, sizeof(cwd)) != nullptr)
{
snprintf(fname, sizeof(fname),
"%s/%s", cwd, (char *)__progname);
if (stat(fname, &sba) == 0)
snprintf(exe_file, sizeof(exe_file),
"%s/", cwd);
}
}
if (!exe_file[0])
return "";
else
return std::string(exe_file);
#else
return "";
#endif
}
else
{
size = readlink(PROC_EXE_PATH, exe_file, PATH_MAX);
if (size < 0)
{
return strerror(errno);
}
else
{
exe_file[size] = '\0';
return std::string(dirname(exe_file)) + "/";
}
}
#endif
}
extern "C"
{
const char *M_GetGameExe()
{
static FString s = (exe_path() + GAMENAMELOWERCASE).c_str();
return s.GetChars();
}
}