1+ #include " CrashDump.h"
2+
3+ #ifdef _WIN32
4+ bool BeginCrashListener () { return true ; }
5+ #else
6+
7+ #include < boost/stacktrace.hpp>
8+ #include < boost/exception/all.hpp>
9+ #include < rapidjson/document.h>
10+ #include < rapidjson/writer.h>
11+ #include < rapidjson/stringbuffer.h>
12+
13+ #include < random>
14+
15+ #include < tier0/icommandline.h>
16+
17+ #include " ../files/Files.h"
18+ #include " ../http/HTTPManager.h"
19+ #include " ../common.h"
20+
21+ std::string get_uuid ()
22+ {
23+ static std::random_device dev;
24+ static std::mt19937 rng (dev ());
25+
26+ std::uniform_int_distribution<int > dist (0 , 15 );
27+
28+ const char *v = " 0123456789abcdef" ;
29+ const bool dash[] = {0 , 0 , 0 , 0 , 1 , 0 , 1 , 0 , 1 , 0 , 1 , 0 , 0 , 0 , 0 , 0 };
30+
31+ std::string res;
32+ for (int i = 0 ; i < 16 ; i++)
33+ {
34+ if (dash[i])
35+ res += " -" ;
36+ res += v[dist (rng)];
37+ res += v[dist (rng)];
38+ }
39+ return res;
40+ }
41+
42+ std::string startup_cmd = " None" ;
43+
44+ void signal_handler (int signumber)
45+ {
46+ try
47+ {
48+ auto boostStackTrace = boost::stacktrace::stacktrace ();
49+
50+ std::string stacktrace = boost::to_string (boost::stacktrace::stacktrace ());
51+ std::string coredumpdata = stacktrace;
52+ std::vector<std::string> splitted_dump = explode (coredumpdata, " \n " );
53+ PRINTF (" Crash Reporter" , " A crash has occured and a dump has been created:\n " );
54+ for (int i = 0 ; i < splitted_dump.size () - 1 ; i++)
55+ PRINTF (" Crash Reporter" , " %s\n " , splitted_dump[i].c_str ());
56+
57+ std::string file_path = string_format (" addons/swiftly/dumps/crash.%s.log" , get_uuid ().c_str ());
58+ if (Files::ExistsPath (file_path))
59+ Files::Delete (file_path);
60+
61+ Files::Append (file_path, string_format (" ================================\n Command: %s\n Map: %s\n ================================\n\n %s" , startup_cmd.c_str (), g_Plugin.GetMap ().c_str (), coredumpdata.c_str ()), false );
62+ PRINTF (" Crash Reporter" , " A dump log file has been created at: %s\n " , file_path.c_str ());
63+ PRINTF (" Crash Reporter" , " A crash report has been sent to Swiftly Crash Reporter Server.\n " );
64+
65+ rapidjson::Document document (rapidjson::kObjectType );
66+
67+ document.AddMember (rapidjson::Value ().SetString (" coredumpdata" , document.GetAllocator ()), rapidjson::Value ().SetString (coredumpdata.c_str (), document.GetAllocator ()), document.GetAllocator ());
68+ document.AddMember (rapidjson::Value ().SetString (" startup_cmd" , document.GetAllocator ()), rapidjson::Value ().SetString (startup_cmd.c_str (), document.GetAllocator ()), document.GetAllocator ());
69+ document.AddMember (rapidjson::Value ().SetString (" map" , document.GetAllocator ()), rapidjson::Value ().SetString (g_Plugin.GetMap ().c_str (), document.GetAllocator ()), document.GetAllocator ());
70+
71+ rapidjson::StringBuffer buffer;
72+ rapidjson::Writer<rapidjson::StringBuffer> writer (buffer);
73+ document.Accept (writer);
74+
75+ std::string json = std::string (buffer.GetString ());
76+
77+ uint64_t requestid = g_httpManager->CreateRequest (" https://crashreporter.swiftlycs2.net" );
78+ HTTPRequest *req = g_httpManager->FetchRequest (requestid);
79+ req->SetBody (json);
80+ req->SetContentType (ContentType::APPLICATION_JSON);
81+ req->Post (" /" );
82+ g_httpManager->DeleteRequest (requestid);
83+ }
84+ catch (const std::runtime_error &e)
85+ {
86+ PRINTF (" Crash Reporter" , " Error crash handling: %s\n " , e.what ());
87+ }
88+
89+ exit (EXIT_FAILURE);
90+ }
91+
92+ bool BeginCrashListener ()
93+ {
94+ if (!Files::ExistsPath (" addons/swiftly/dumps" ))
95+ {
96+ if (!Files::CreateDirectory (" addons/swiftly/dumps" ))
97+ {
98+ PRINTF (" Crash Listener" , " Couldn't create dumps folder.\n " );
99+ return false ;
100+ }
101+ }
102+
103+ startup_cmd = CommandLine ()->GetCmdLine ();
104+
105+ ::signal (SIGSEGV, &signal_handler);
106+ return true ;
107+ }
108+
109+ #endif
0 commit comments