mirror of
https://git.do.srb2.org/STJr/SRB2.git
synced 2024-11-22 04:21:23 +00:00
Merge branch 'improve-backtrace' into 'next'
Clean up the backtrace code and make it use write() more safely. See merge request STJr/SRB2!1897
This commit is contained in:
commit
d3686b3255
1 changed files with 48 additions and 37 deletions
|
@ -271,75 +271,86 @@ SDL_bool framebuffer = SDL_FALSE;
|
||||||
UINT8 keyboard_started = false;
|
UINT8 keyboard_started = false;
|
||||||
|
|
||||||
#ifdef UNIXBACKTRACE
|
#ifdef UNIXBACKTRACE
|
||||||
#define STDERR_WRITE(string) if (fd != -1) I_OutputMsg("%s", string)
|
|
||||||
#define CRASHLOG_WRITE(string) if (fd != -1) junk = write(fd, string, strlen(string))
|
static void bt_write_file(int fd, const char *string) {
|
||||||
#define CRASHLOG_STDERR_WRITE(string) \
|
ssize_t written = 0;
|
||||||
if (fd != -1)\
|
ssize_t sourcelen = strlen(string);
|
||||||
junk = write(fd, string, strlen(string));\
|
|
||||||
I_OutputMsg("%s", string)
|
while (fd != -1 && (written != -1 && errno != EINTR) && written < sourcelen)
|
||||||
|
written = write(fd, string, sourcelen);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void bt_write_stderr(const char *string) {
|
||||||
|
bt_write_file(STDERR_FILENO, string);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void bt_write_all(int fd, const char *string) {
|
||||||
|
bt_write_file(fd, string);
|
||||||
|
bt_write_file(STDERR_FILENO, string);
|
||||||
|
}
|
||||||
|
|
||||||
static void write_backtrace(INT32 signal)
|
static void write_backtrace(INT32 signal)
|
||||||
{
|
{
|
||||||
int fd = -1;
|
int fd = -1;
|
||||||
#ifndef NOEXECINFO
|
|
||||||
size_t size;
|
|
||||||
#endif
|
|
||||||
time_t rawtime;
|
time_t rawtime;
|
||||||
struct tm timeinfo;
|
struct tm timeinfo;
|
||||||
ssize_t junk;
|
|
||||||
|
|
||||||
enum { BT_SIZE = 1024, STR_SIZE = 32 };
|
enum { BT_SIZE = 1024, STR_SIZE = 32 };
|
||||||
#ifndef NOEXECINFO
|
#ifndef NOEXECINFO
|
||||||
void *array[BT_SIZE];
|
void *funcptrs[BT_SIZE];
|
||||||
|
size_t bt_size;
|
||||||
#endif
|
#endif
|
||||||
char timestr[STR_SIZE];
|
char timestr[STR_SIZE];
|
||||||
|
|
||||||
const char *error = "An error occurred within SRB2! Send this stack trace to someone who can help!\n";
|
const char *filename = va("%s" PATHSEP "%s", srb2home, "crash-log.txt");
|
||||||
const char *error2 = "(Or find crash-log.txt in your SRB2 directory.)\n"; // Shown only to stderr.
|
|
||||||
|
|
||||||
fd = open(va("%s" PATHSEP "%s", srb2home, "crash-log.txt"), O_CREAT|O_APPEND|O_RDWR, S_IRUSR|S_IWUSR);
|
fd = open(filename, O_CREAT|O_APPEND|O_RDWR, S_IRUSR|S_IWUSR);
|
||||||
|
|
||||||
if (fd == -1)
|
if (fd == -1) // File handle error
|
||||||
I_OutputMsg("\nWARNING: Couldn't open crash log for writing! Make sure your permissions are correct. Please save the below report!\n");
|
bt_write_stderr("\nWARNING: Couldn't open crash log for writing! Make sure your permissions are correct. Please save the below report!\n");
|
||||||
|
|
||||||
// Get the current time as a string.
|
// Get the current time as a string.
|
||||||
time(&rawtime);
|
time(&rawtime);
|
||||||
localtime_r(&rawtime, &timeinfo);
|
localtime_r(&rawtime, &timeinfo);
|
||||||
strftime(timestr, STR_SIZE, "%a, %d %b %Y %T %z", &timeinfo);
|
strftime(timestr, STR_SIZE, "%a, %d %b %Y %T %z", &timeinfo);
|
||||||
|
|
||||||
CRASHLOG_WRITE("------------------------\n"); // Nice looking seperator
|
bt_write_file(fd, "------------------------\n"); // Nice looking seperator
|
||||||
|
|
||||||
CRASHLOG_STDERR_WRITE("\n"); // Newline to look nice for both outputs.
|
bt_write_all(fd, "\n"); // Newline to look nice for both outputs.
|
||||||
CRASHLOG_STDERR_WRITE(error); // "Oops, SRB2 crashed" message
|
bt_write_all(fd, "An error occurred within SRB2! Send this stack trace to someone who can help!\n");
|
||||||
STDERR_WRITE(error2); // Tell the user where the crash log is.
|
|
||||||
|
if (fd != -1) // If the crash log exists,
|
||||||
|
bt_write_stderr("(Or find crash-log.txt in your SRB2 directory.)\n"); // tell the user where the crash log is.
|
||||||
|
|
||||||
// Tell the log when we crashed.
|
// Tell the log when we crashed.
|
||||||
CRASHLOG_WRITE("Time of crash: ");
|
bt_write_file(fd, "Time of crash: ");
|
||||||
CRASHLOG_WRITE(timestr);
|
bt_write_file(fd, timestr);
|
||||||
CRASHLOG_WRITE("\n");
|
bt_write_file(fd, "\n");
|
||||||
|
|
||||||
// Give the crash log the cause and a nice 'Backtrace:' thing
|
// Give the crash log the cause and a nice 'Backtrace:' thing
|
||||||
// The signal is given to the user when the parent process sees we crashed.
|
// The signal is given to the user when the parent process sees we crashed.
|
||||||
CRASHLOG_WRITE("Cause: ");
|
bt_write_file(fd, "Cause: ");
|
||||||
CRASHLOG_WRITE(strsignal(signal));
|
bt_write_file(fd, strsignal(signal));
|
||||||
CRASHLOG_WRITE("\n"); // Newline for the signal name
|
bt_write_file(fd, "\n"); // Newline for the signal name
|
||||||
|
|
||||||
#ifndef NOEXECINFO
|
#ifdef NOEXECINFO
|
||||||
CRASHLOG_STDERR_WRITE("\nBacktrace:\n");
|
bt_write_all(fd, "\nNo Backtrace support\n");
|
||||||
|
#else
|
||||||
|
bt_write_all(fd, "\nBacktrace:\n");
|
||||||
|
|
||||||
// Flood the output and log with the backtrace
|
// Flood the output and log with the backtrace
|
||||||
size = backtrace(array, BT_SIZE);
|
bt_size = backtrace(funcptrs, BT_SIZE);
|
||||||
backtrace_symbols_fd(array, size, fd);
|
backtrace_symbols_fd(funcptrs, bt_size, fd);
|
||||||
backtrace_symbols_fd(array, size, STDERR_FILENO);
|
backtrace_symbols_fd(funcptrs, bt_size, STDERR_FILENO);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
CRASHLOG_WRITE("\n"); // Write another newline to the log so it looks nice :)
|
bt_write_file(fd, "\n"); // Write another newline to the log so it looks nice :)
|
||||||
(void)junk;
|
if (fd != -1) {
|
||||||
close(fd);
|
fsync(fd); // reaaaaally make sure we got that data written.
|
||||||
|
close(fd);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
#undef STDERR_WRITE
|
|
||||||
#undef CRASHLOG_WRITE
|
|
||||||
#undef CRASHLOG_STDERR_WRITE
|
|
||||||
#endif // UNIXBACKTRACE
|
#endif // UNIXBACKTRACE
|
||||||
|
|
||||||
static void I_ReportSignal(int num, int coredumped)
|
static void I_ReportSignal(int num, int coredumped)
|
||||||
|
|
Loading…
Reference in a new issue