Skip to content

Commit 6dabe6a

Browse files
committed
Generate filepath using timestamp
1 parent 093896d commit 6dabe6a

1 file changed

Lines changed: 38 additions & 15 deletions

File tree

library/Crashlog.cpp

Lines changed: 38 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,9 @@
11
#include "DFHackVersion.h"
22
#include <csignal>
3-
#include <thread>
3+
#include <iomanip>
44
#include <filesystem>
55
#include <fstream>
6+
#include <thread>
67

78
#include <execinfo.h>
89

@@ -41,7 +42,7 @@ extern "C" void dfhack_crashlog_handle_signal(int sig) {
4142
}
4243
crash_info.signal = sig;
4344
crash_info.backtrace_entries = backtrace(crash_info.backtrace, BT_ENTRY_MAX);
44-
45+
4546
// Signal saving of crashlog and wait for completion
4647
flag_set(crashlog_ready);
4748
flag_wait(crashlog_complete);
@@ -70,27 +71,49 @@ std::string signal_name(int sig) {
7071
return "";
7172
}
7273

74+
std::filesystem::path get_crashlog_path() {
75+
std::time_t time = std::time(nullptr);
76+
std::tm* tm = std::localtime(&time);
77+
78+
std::string timestamp = "unknown";
79+
if (tm) {
80+
char stamp[64];
81+
std::size_t out = strftime(&stamp[0], 63, "%Y-%m-%d-%H-%M-%S", tm);
82+
if (out != 0)
83+
timestamp = stamp;
84+
}
85+
86+
std::filesystem::path dir = "crashlog";
87+
std::error_code err;
88+
std::filesystem::create_directories(dir, err);
89+
90+
std::filesystem::path log_path = dir / ("crash_" + timestamp + ".txt");
91+
return log_path;
92+
}
93+
7394
void dfhack_save_crashlog() {
7495
char** backtrace_strings = backtrace_symbols(crash_info.backtrace, crash_info.backtrace_entries);
7596
if (!backtrace_strings) {
7697
// Allocation failed, give up
7798
return;
7899
}
79-
std::filesystem::path crashlog_path = "./crash.txt";
80-
std::ofstream crashlog(crashlog_path);
100+
try {
101+
std::filesystem::path crashlog_path = get_crashlog_path();
102+
std::ofstream crashlog(crashlog_path);
81103

82-
crashlog << "Dwarf Fortress Linux has crashed!" << "\n";
83-
crashlog << "Dwarf Fortress Version " << DFHack::Version::df_version() << "\n";
84-
crashlog << "DFHack Version " << DFHack::Version::dfhack_version() << "\n\n";
104+
crashlog << "Dwarf Fortress Linux has crashed!" << "\n";
105+
crashlog << "Dwarf Fortress Version " << DFHack::Version::df_version() << "\n";
106+
crashlog << "DFHack Version " << DFHack::Version::dfhack_version() << "\n\n";
85107

86-
std::string signal = signal_name(crash_info.signal);
87-
if (!signal.empty()) {
88-
crashlog << "Signal " << signal << "\n";
89-
}
108+
std::string signal = signal_name(crash_info.signal);
109+
if (!signal.empty()) {
110+
crashlog << "Signal " << signal << "\n";
111+
}
90112

91-
for (int i = 0; i < crash_info.backtrace_entries; i++) {
92-
crashlog << i << "> " << backtrace_strings[i] << "\n";
93-
}
113+
for (int i = 0; i < crash_info.backtrace_entries; i++) {
114+
crashlog << i << "> " << backtrace_strings[i] << "\n";
115+
}
116+
} catch (...) {}
94117

95118
free(backtrace_strings);
96119
}
@@ -118,7 +141,7 @@ namespace DFHack {
118141
// https://sourceware.org/glibc/manual/latest/html_mono/libc.html#index-backtrace-1
119142
// backtrace is AsyncSignal-Unsafe due to dynamic loading of libgcc_s
120143
// Using it here ensures it is loaded before use in the signal handler.
121-
int _ = backtrace(crash_info.backtrace, 1);
144+
[[maybe_unused]] int _ = backtrace(crash_info.backtrace, 1);
122145

123146
crashlog_thread = std::thread(dfhack_crashlog_thread);
124147
}

0 commit comments

Comments
 (0)