Skip to content

Commit 0dca250

Browse files
committed
Implement crash presubmitting and symbol uploads
1 parent 16022a4 commit 0dca250

9 files changed

+323
-24
lines changed

.gitmodules

+3
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,6 @@
11
[submodule "vendor/breakpad"]
22
path = vendor/breakpad
33
url = https://github.com/google/breakpad
4+
[submodule "vendor/fmt"]
5+
path = vendor/fmt
6+
url = https://github.com/fmtlib/fmt

extension.cpp

+1-2
Original file line numberDiff line numberDiff line change
@@ -308,7 +308,6 @@ void UploadThread()
308308

309309
char tokenBuffer[64];
310310
PresubmitCrashDump(entry.path().string().c_str(), tokenBuffer, sizeof(tokenBuffer));
311-
return;
312311

313312
ConMsg("Uploading minidump %s\n", entry.path().string().c_str());
314313

@@ -576,7 +575,7 @@ const char* AcceleratorCS2::GetLicense()
576575

577576
const char* AcceleratorCS2::GetVersion()
578577
{
579-
return "1.0.0";
578+
return "2.0.0";
580579
}
581580

582581
const char* AcceleratorCS2::GetDate()

patches/0002-Write-FUNC-records-instead-of-PUBLIC-for-ELF-symbols.patch

+1-1
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,7 @@ index 70d50f89..f21460bf 100644
2323
#endif
2424
+#if 1
2525
+ if (iterator->size) {
26-
+ Module::Function *fun = new Module::Function(name, iterator->value);
26+
+ Module::Function *fun = new Module::Function(module->AddStringToPool(name), iterator->value);
2727
+ fun->ranges.push_back(Module::Range(iterator->value, iterator->size));
2828
+ module->AddFunction(fun);
2929
+ }
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,268 @@
1+
diff --git a/src/common/linux/dump_symbols.cc b/src/common/linux/dump_symbols.cc
2+
index b693fc9..30b3a4d 100644
3+
--- a/src/common/linux/dump_symbols.cc
4+
+++ b/src/common/linux/dump_symbols.cc
5+
@@ -1288,7 +1288,7 @@ bool WriteSymbolFile(const string& load_path,
6+
const string& obj_os,
7+
const std::vector<string>& debug_dirs,
8+
const DumpOptions& options,
9+
- std::ostream& sym_stream) {
10+
+ std::string& sym_stream) {
11+
Module* module;
12+
if (!ReadSymbolData(load_path, obj_file, obj_os, debug_dirs, options,
13+
&module))
14+
@@ -1305,7 +1305,7 @@ bool WriteSymbolFile(const string& load_path,
15+
bool WriteSymbolFileHeader(const string& load_path,
16+
const string& obj_file,
17+
const string& obj_os,
18+
- std::ostream& sym_stream) {
19+
+ std::string& sym_stream) {
20+
MmapWrapper map_wrapper;
21+
void* elf_header = NULL;
22+
if (!LoadELF(load_path, &map_wrapper, &elf_header)) {
23+
diff --git a/src/common/linux/dump_symbols.h b/src/common/linux/dump_symbols.h
24+
index f1802ec..f22169a 100644
25+
--- a/src/common/linux/dump_symbols.h
26+
+++ b/src/common/linux/dump_symbols.h
27+
@@ -69,7 +69,7 @@ bool WriteSymbolFile(const string& load_path,
28+
const string& obj_os,
29+
const std::vector<string>& debug_dirs,
30+
const DumpOptions& options,
31+
- std::ostream& sym_stream);
32+
+ std::string& sym_stream);
33+
34+
// Read the selected object file's debugging information, and write out the
35+
// header only to |stream|. Return true on success; if an error occurs, report
36+
@@ -78,7 +78,7 @@ bool WriteSymbolFile(const string& load_path,
37+
bool WriteSymbolFileHeader(const string& load_path,
38+
const string& obj_file,
39+
const string& obj_os,
40+
- std::ostream& sym_stream);
41+
+ std::string& sym_stream);
42+
43+
// As above, but simply return the debugging information in MODULE
44+
// instead of writing it to a stream. The caller owns the resulting
45+
diff --git a/src/common/module.cc b/src/common/module.cc
46+
index b6f5da7..7137adc 100644
47+
--- a/src/common/module.cc
48+
+++ b/src/common/module.cc
49+
@@ -48,6 +48,9 @@
50+
#include <memory>
51+
#include <utility>
52+
53+
+#define FMT_HEADER_ONLY
54+
+#include <fmt/format.h>
55+
+
56+
namespace google_breakpad {
57+
58+
using std::dec;
59+
@@ -357,14 +360,15 @@ bool Module::ReportError() {
60+
return false;
61+
}
62+
63+
-bool Module::WriteRuleMap(const RuleMap& rule_map, std::ostream& stream) {
64+
+bool Module::WriteRuleMap(const RuleMap& rule_map, std::string& stream) {
65+
for (RuleMap::const_iterator it = rule_map.begin();
66+
it != rule_map.end(); ++it) {
67+
if (it != rule_map.begin())
68+
- stream << ' ';
69+
- stream << it->first << ": " << it->second;
70+
+ stream += ' ';
71+
+ //stream << it->first << ": " << it->second;
72+
+ stream += fmt::format("{}: {}", it->first, it->second);
73+
}
74+
- return stream.good();
75+
+ return true;
76+
}
77+
78+
bool Module::AddressIsInModule(Address address) const {
79+
@@ -380,14 +384,15 @@ bool Module::AddressIsInModule(Address address) const {
80+
return false;
81+
}
82+
83+
-bool Module::Write(std::ostream& stream, SymbolData symbol_data) {
84+
- stream << "MODULE " << os_ << " " << architecture_ << " "
85+
- << id_ << " " << name_ << "\n";
86+
- if (!stream.good())
87+
- return ReportError();
88+
+bool Module::Write(std::string& stream, SymbolData symbol_data) {
89+
+ /*stream << "MODULE " << os_ << " " << architecture_ << " "
90+
+ << id_ << " " << name_ << "\n";*/
91+
+
92+
+ stream = fmt::format("MODULE {} {} {} {}\n", os_, architecture_, id_, name_);
93+
94+
if (!code_id_.empty()) {
95+
- stream << "INFO CODE_ID " << code_id_ << "\n";
96+
+ //stream << "INFO CODE_ID " << code_id_ << "\n";
97+
+ stream += fmt::format("INFO CODE_ID {}\n", code_id_);
98+
}
99+
100+
if (symbol_data & SYMBOLS_AND_FILES) {
101+
@@ -401,16 +406,14 @@ bool Module::Write(std::ostream& stream, SymbolData symbol_data) {
102+
file_it != files_.end(); ++file_it) {
103+
File* file = file_it->second;
104+
if (file->source_id >= 0) {
105+
- stream << "FILE " << file->source_id << " " << file->name << "\n";
106+
- if (!stream.good())
107+
- return ReportError();
108+
+ //stream << "FILE " << file->source_id << " " << file->name << "\n";
109+
+ stream += fmt::format("FILE {} {}\n", file->source_id, file->name);
110+
}
111+
}
112+
// Write out inline origins.
113+
for (InlineOrigin* origin : inline_origins) {
114+
- stream << "INLINE_ORIGIN " << origin->id << " " << origin->name << "\n";
115+
- if (!stream.good())
116+
- return ReportError();
117+
+ //stream << "INLINE_ORIGIN " << origin->id << " " << origin->name << "\n";
118+
+ stream += fmt::format("INLINE_ORIGIN {} {}\n", origin->id, origin->name.str());
119+
}
120+
121+
// Write out functions and their inlines and lines.
122+
@@ -420,39 +423,54 @@ bool Module::Write(std::ostream& stream, SymbolData symbol_data) {
123+
vector<Line>::iterator line_it = func->lines.begin();
124+
for (auto range_it = func->ranges.cbegin();
125+
range_it != func->ranges.cend(); ++range_it) {
126+
- stream << "FUNC " << (func->is_multiple ? "m " : "") << hex
127+
+ /*stream << "FUNC " << (func->is_multiple ? "m " : "") << hex
128+
<< (range_it->address - load_address_) << " " << range_it->size
129+
<< " " << func->parameter_size << " " << func->name << dec
130+
- << "\n";
131+
+ << "\n";*/
132+
133+
- if (!stream.good())
134+
- return ReportError();
135+
+ stream += fmt::format("FUNC {}{:x} {:x} {:x} {}\n",
136+
+ (func->is_multiple ? "m " : ""),
137+
+ (range_it->address - load_address_),
138+
+ range_it->size,
139+
+ func->parameter_size,
140+
+ func->name.str().c_str());
141+
142+
// Write out inlines.
143+
auto write_inline = [&](unique_ptr<Inline>& in) {
144+
- stream << "INLINE ";
145+
+ /*stream << "INLINE ";
146+
stream << in->inline_nest_level << " " << in->call_site_line << " "
147+
<< in->getCallSiteFileID() << " " << in->origin->id << hex;
148+
+ */
149+
+ stream += fmt::format("INLINE {} {} {} {}",
150+
+ in->inline_nest_level,
151+
+ in->call_site_line,
152+
+ in->getCallSiteFileID(),
153+
+ in->origin->id);
154+
+
155+
for (const Range& r : in->ranges)
156+
- stream << " " << (r.address - load_address_) << " " << r.size;
157+
- stream << dec << "\n";
158+
+ //stream << " " << (r.address - load_address_) << " " << r.size;
159+
+ stream += fmt::format(" {:x} {:x}", (r.address - load_address_), r.size);
160+
+ //stream << dec << "\n";
161+
+ stream += "\n";
162+
};
163+
Module::Inline::InlineDFS(func->inlines, write_inline);
164+
- if (!stream.good())
165+
- return ReportError();
166+
167+
while ((line_it != func->lines.end()) &&
168+
(line_it->address >= range_it->address) &&
169+
(line_it->address < (range_it->address + range_it->size))) {
170+
- stream << hex
171+
+ /*stream << hex
172+
<< (line_it->address - load_address_) << " "
173+
<< line_it->size << " "
174+
<< dec
175+
<< line_it->number << " "
176+
- << line_it->file->source_id << "\n";
177+
+ << line_it->file->source_id << "\n";*/
178+
+
179+
+ stream += fmt::format("{:x} {:x} {} {}\n",
180+
+ (line_it->address - load_address_),
181+
+ line_it->size,
182+
+ line_it->number,
183+
+ line_it->file->source_id);
184+
185+
- if (!stream.good())
186+
- return ReportError();
187+
188+
++line_it;
189+
}
190+
@@ -463,9 +481,13 @@ bool Module::Write(std::ostream& stream, SymbolData symbol_data) {
191+
for (ExternSet::const_iterator extern_it = externs_.begin();
192+
extern_it != externs_.end(); ++extern_it) {
193+
Extern* ext = extern_it->get();
194+
- stream << "PUBLIC " << (ext->is_multiple ? "m " : "") << hex
195+
+ /*stream << "PUBLIC " << (ext->is_multiple ? "m " : "") << hex
196+
<< (ext->address - load_address_) << " 0 " << ext->name << dec
197+
- << "\n";
198+
+ << "\n";*/
199+
+ stream += fmt::format("PUBLIC {}{:x} 0 {}\n",
200+
+ (ext->is_multiple ? "m " : ""),
201+
+ (ext->address - load_address_),
202+
+ ext->name);
203+
}
204+
}
205+
206+
@@ -474,25 +496,30 @@ bool Module::Write(std::ostream& stream, SymbolData symbol_data) {
207+
for (auto frame_it = stack_frame_entries_.begin();
208+
frame_it != stack_frame_entries_.end(); ++frame_it) {
209+
StackFrameEntry* entry = frame_it->get();
210+
- stream << "STACK CFI INIT " << hex
211+
+ /*stream << "STACK CFI INIT " << hex
212+
<< (entry->address - load_address_) << " "
213+
- << entry->size << " " << dec;
214+
- if (!stream.good()
215+
- || !WriteRuleMap(entry->initial_rules, stream))
216+
+ << entry->size << " " << dec;*/
217+
+ stream += fmt::format("STACK CFI INIT {:x} {:x} ",
218+
+ (entry->address - load_address_),
219+
+ entry->size);
220+
+
221+
+ if (!WriteRuleMap(entry->initial_rules, stream))
222+
return ReportError();
223+
224+
- stream << "\n";
225+
+ //stream << "\n";
226+
+ stream += "\n";
227+
228+
// Write out this entry's delta rules as 'STACK CFI' records.
229+
for (RuleChangeMap::const_iterator delta_it = entry->rule_changes.begin();
230+
delta_it != entry->rule_changes.end(); ++delta_it) {
231+
- stream << "STACK CFI " << hex
232+
- << (delta_it->first - load_address_) << " " << dec;
233+
- if (!stream.good()
234+
- || !WriteRuleMap(delta_it->second, stream))
235+
+ /*stream << "STACK CFI " << hex
236+
+ << (delta_it->first - load_address_) << " " << dec;*/
237+
+
238+
+ stream += fmt::format("STACK CFI {:x} ", (delta_it->first - load_address_));
239+
+ if (!WriteRuleMap(delta_it->second, stream))
240+
return ReportError();
241+
242+
- stream << "\n";
243+
+ stream += "\n";
244+
}
245+
}
246+
}
247+
diff --git a/src/common/module.h b/src/common/module.h
248+
index 28e8e9c..ef4f1a4 100644
249+
--- a/src/common/module.h
250+
+++ b/src/common/module.h
251+
@@ -422,7 +422,7 @@ class Module {
252+
// - all CFI records.
253+
// Addresses in the output are all relative to the load address
254+
// established by SetLoadAddress.
255+
- bool Write(std::ostream& stream, SymbolData symbol_data);
256+
+ bool Write(std::string& stream, SymbolData symbol_data);
257+
258+
// Place the name in the global set of strings. Return a StringView points to
259+
// a string inside the pool.
260+
@@ -445,7 +445,7 @@ class Module {
261+
// Write RULE_MAP to STREAM, in the form appropriate for 'STACK CFI'
262+
// records, without a final newline. Return true if all goes well;
263+
// if an error occurs, return false, and leave errno set.
264+
- static bool WriteRuleMap(const RuleMap& rule_map, std::ostream& stream);
265+
+ static bool WriteRuleMap(const RuleMap& rule_map, std::string& stream);
266+
267+
// Returns true of the specified address resides with an specified address
268+
// range, or if no ranges have been specified.

premake/fmt.lua

+15
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
local fmtPath = "../vendor/fmt"
2+
3+
project "fmt"
4+
location "../build/fmt"
5+
kind "StaticLib"
6+
7+
files {
8+
path.join(fmtPath, "src", "format.cc"),
9+
path.join(fmtPath, "src", "os.cc"),
10+
path.join(fmtPath, "src", "fmt.cc"),
11+
}
12+
13+
includedirs {
14+
path.join(fmtPath, "include")
15+
}

premake/mm-linux.lua

+2-1
Original file line numberDiff line numberDiff line change
@@ -49,7 +49,8 @@ defines {
4949
"POSIX",
5050
"GNUC",
5151
"COMPILER_GCC",
52-
"PLATFORM_64BITS"
52+
"PLATFORM_64BITS",
53+
"_GLIBCXX_USE_CXX11_ABI=0"
5354
}
5455

5556
characterset "MBCS"

premake5.lua

+2-3
Original file line numberDiff line numberDiff line change
@@ -84,9 +84,7 @@ project "AcceleratorCS2"
8484
"libdisasm"
8585
}
8686

87-
defines { "META_IS_SOURCE2", "HAVE_CONFIG_H", "HAVE_STDINT_H", "GNUC", "_GLIBCXX_USE_CXX11_ABI=0" }
88-
89-
linkoptions { '-static-libstdc++', '-static-libgcc' }
87+
defines { "META_IS_SOURCE2", "HAVE_CONFIG_H", "HAVE_STDINT_H" }
9088

9189
vectorextensions "sse"
9290
strictaliasing "Off"
@@ -96,4 +94,5 @@ project "AcceleratorCS2"
9694

9795
includedirs {
9896
path.join("vendor", "breakpad", "src"),
97+
path.join("vendor", "fmt", "include"),
9998
}

0 commit comments

Comments
 (0)