Audacity 3.2.0
unix/CrashReportContext.cpp
Go to the documentation of this file.
1/*!********************************************************************
2*
3 Audacity: A Digital Audio Editor
4
5 CrashReportContext.cpp
6
7 Vitaly Sverchinsky
8
9 Some parts of the code are designed to operate while app is crashing,
10 so there may be some restrictions on heap usage. For more information
11 please read Breakpad documentation.
12
13 **********************************************************************/
14#include "CrashReportContext.h"
15
16#include <errno.h>
17#include <map>
18#include <sstream>
19
20#if defined(__APPLE__)
21#include "client/mac/handler/exception_handler.h"
22#else
23#include "client/linux/handler/exception_handler.h"
24#endif
25
26bool SendReport(CrashReportContext* c, const char* minidumpPath)
27{
28 auto pid = fork();
29 if(pid == 0)
30 {
31 if(c->mParameters[0] != 0)
32 {
33 execl(c->mSenderPath, CRASHREPORTER_PROGRAM_NAME, "-a", c->mParameters, "-u", c->mReportURL, minidumpPath, NULL);
34 }
35 else
36 {
37 execl(c->mSenderPath, CRASHREPORTER_PROGRAM_NAME, "-u", c->mReportURL, minidumpPath, NULL);
38 }
39 fprintf(stderr, "Failed to start handler: %s\n", strerror(errno));
40 abort();
41 }
42 return pid != -1;
43}
44
45namespace
46{
47
48 //converts parameters map to a string, so that the Crash Reporting program
49 //would understand them
50 std::string StringifyParameters(const std::map<std::string, std::string>& parameters)
51 {
52 std::stringstream stream;
53
54 std::size_t parameterIndex = 0;
55 std::size_t parametersCount = parameters.size();
56 for (auto& pair : parameters)
57 {
58 stream << pair.first.c_str() << "=\"" << pair.second.c_str() << "\"";
59 ++parameterIndex;
60 if (parameterIndex < parametersCount)
61 stream << ",";
62 }
63 return stream.str();
64 }
65
66 //copy contents of src to a raw char dest buffer,
67 //returns false if dest is not large enough
68 bool StrcpyChecked(char* dest, size_t destsz, const std::string& src)
69 {
70 if(src.length() < destsz)
71 {
72 memcpy(dest, src.c_str(), src.length());
73 dest[src.length()] = '\0';
74 return true;
75 }
76 return false;
77 }
78
79#if defined(__APPLE__)
80
81 static constexpr size_t MaxDumpPathLength{ 4096 };
82 static char DumpPath[MaxDumpPathLength];
83
84 bool DumpCallback(const char* dump_dir, const char* minidump_id, void* context, bool succeeded)
85 {
86 if(succeeded)
87 {
88 const int PathDumpLength = strlen(dump_dir) + strlen("/") + strlen(minidump_id) + strlen(".dmp");
89 if(PathDumpLength < MaxDumpPathLength)
90 {
91 strcpy(DumpPath, dump_dir);
92 strcat(DumpPath, "/");
93 strcat(DumpPath, minidump_id);
94 strcat(DumpPath, ".dmp");
95 auto crashReportContext = static_cast<CrashReportContext*>(context);
96 return SendReport(crashReportContext, DumpPath);
97 }
98 return false;
99 }
100 return succeeded;
101 }
102#else
103 bool DumpCallback(const google_breakpad::MinidumpDescriptor& descriptor, void* context, bool succeeded)
104 {
105 if(succeeded)
106 {
107 auto crashReportContext = static_cast<CrashReportContext*>(context);
108 return SendReport(crashReportContext, descriptor.path());
109 }
110 return succeeded;
111 }
112#endif
113}
114
115bool CrashReportContext::SetSenderPathUTF8(const std::string& path)
116{
117 return StrcpyChecked(mSenderPath, MaxBufferLength, path + "/" + CRASHREPORTER_PROGRAM_NAME);
118}
119
120bool CrashReportContext::SetReportURL(const std::string& url)
121{
123}
124
125bool CrashReportContext::SetParameters(const std::map<std::string, std::string>& p)
126{
127 auto str = StringifyParameters(p);
129}
130
131void CrashReportContext::StartHandler(const std::string& databasePath)
132{
133 //intentinal leak: error hooks may be useful while application is terminating
134 //CrashReportContext data should be alive too...
135#if(__APPLE__)
136 static auto handler = new google_breakpad::ExceptionHandler(
137 databasePath,
138 nullptr,
140 this,
141 true,
142 nullptr
143 );
144#else
145 google_breakpad::MinidumpDescriptor descriptor(databasePath);
146 static auto handler = new google_breakpad::ExceptionHandler(
147 descriptor,
148 nullptr,
150 this,
151 true,
152 -1
153 );
154#endif
155}
#define str(a)
This object is for internal usage.
char mParameters[MaxBufferLength]
bool SetParameters(const std::map< std::string, std::string > &p)
bool SetReportURL(const std::string &url)
char mSenderPath[MaxBufferLength]
bool SetSenderPathUTF8(const std::string &path)
char mReportURL[MaxBufferLength]
static constexpr size_t MaxBufferLength
void StartHandler(const std::string &databasePath)
std::string StringifyParameters(const std::map< std::string, std::string > &parameters)
bool DumpCallback(const google_breakpad::MinidumpDescriptor &descriptor, void *context, bool succeeded)
bool StrcpyChecked(char *dest, size_t destsz, const std::string &src)
bool SendReport(CrashReportContext *c, const char *minidumpPath)