Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(366)

Side by Side Diff: breakpad/pending/src/common/module.cc

Issue 8120007: Update Breakpad to r842 and fix the Breakpad bootstrap service leak and -10810 errors (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src/
Patch Set: '' Created 9 years, 2 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « breakpad/breakpad.gyp ('k') | chrome/app/breakpad_mac.h » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright (c) 2010 Google Inc. 1 // Copyright (c) 2011 Google Inc.
2 // All rights reserved. 2 // All rights reserved.
3 // 3 //
4 // Redistribution and use in source and binary forms, with or without 4 // Redistribution and use in source and binary forms, with or without
5 // modification, are permitted provided that the following conditions are 5 // modification, are permitted provided that the following conditions are
6 // met: 6 // met:
7 // 7 //
8 // * Redistributions of source code must retain the above copyright 8 // * Redistributions of source code must retain the above copyright
9 // notice, this list of conditions and the following disclaimer. 9 // notice, this list of conditions and the following disclaimer.
10 // * Redistributions in binary form must reproduce the above 10 // * Redistributions in binary form must reproduce the above
11 // copyright notice, this list of conditions and the following disclaimer 11 // copyright notice, this list of conditions and the following disclaimer
(...skipping 19 matching lines...) Expand all
31 31
32 // module.cc: Implement google_breakpad::Module. See module.h. 32 // module.cc: Implement google_breakpad::Module. See module.h.
33 33
34 #include "common/module.h" 34 #include "common/module.h"
35 35
36 #include <assert.h> 36 #include <assert.h>
37 #include <errno.h> 37 #include <errno.h>
38 #include <stdio.h> 38 #include <stdio.h>
39 #include <string.h> 39 #include <string.h>
40 40
41 #include <ostream> 41 #include <iostream>
42 #include <utility>
42 43
43 namespace google_breakpad { 44 namespace google_breakpad {
44 45
45 using std::dec; 46 using std::dec;
46 using std::endl; 47 using std::endl;
47 using std::hex; 48 using std::hex;
48 49
49 50
50 Module::Module(const string &name, const string &os, 51 Module::Module(const string &name, const string &os,
51 const string &architecture, const string &id) : 52 const string &architecture, const string &id) :
52 name_(name), 53 name_(name),
53 os_(os), 54 os_(os),
54 architecture_(architecture), 55 architecture_(architecture),
55 id_(id), 56 id_(id),
56 load_address_(0) { } 57 load_address_(0) { }
57 58
58 Module::~Module() { 59 Module::~Module() {
59 for (FileByNameMap::iterator it = files_.begin(); it != files_.end(); it++) 60 for (FileByNameMap::iterator it = files_.begin(); it != files_.end(); ++it)
60 delete it->second; 61 delete it->second;
61 for (FunctionSet::iterator it = functions_.begin(); 62 for (FunctionSet::iterator it = functions_.begin();
62 it != functions_.end(); it++) 63 it != functions_.end(); ++it) {
63 delete *it; 64 delete *it;
65 }
64 for (vector<StackFrameEntry *>::iterator it = stack_frame_entries_.begin(); 66 for (vector<StackFrameEntry *>::iterator it = stack_frame_entries_.begin();
65 it != stack_frame_entries_.end(); it++) 67 it != stack_frame_entries_.end(); ++it) {
66 delete *it; 68 delete *it;
67 for (ExternSet::iterator it = externs_.begin(); 69 }
68 it != externs_.end(); it++) 70 for (ExternSet::iterator it = externs_.begin(); it != externs_.end(); ++it)
69 delete *it; 71 delete *it;
70 } 72 }
71 73
72 void Module::SetLoadAddress(Address address) { 74 void Module::SetLoadAddress(Address address) {
73 load_address_ = address; 75 load_address_ = address;
74 } 76 }
75 77
76 void Module::AddFunction(Function *function) { 78 void Module::AddFunction(Function *function) {
77 std::pair<FunctionSet::iterator,bool> ret = functions_.insert(function); 79 std::pair<FunctionSet::iterator,bool> ret = functions_.insert(function);
78 if (!ret.second) { 80 if (!ret.second) {
79 // Free the duplicate that was not inserted because this Module 81 // Free the duplicate that was not inserted because this Module
80 // now owns it. 82 // now owns it.
81 delete function; 83 delete function;
82 } 84 }
83 } 85 }
84 86
85 void Module::AddFunctions(vector<Function *>::iterator begin, 87 void Module::AddFunctions(vector<Function *>::iterator begin,
86 vector<Function *>::iterator end) { 88 vector<Function *>::iterator end) {
87 for (vector<Function *>::iterator it = begin; it != end; it++) 89 for (vector<Function *>::iterator it = begin; it != end; ++it)
88 AddFunction(*it); 90 AddFunction(*it);
89 } 91 }
90 92
91 void Module::AddStackFrameEntry(StackFrameEntry *stack_frame_entry) { 93 void Module::AddStackFrameEntry(StackFrameEntry *stack_frame_entry) {
92 stack_frame_entries_.push_back(stack_frame_entry); 94 stack_frame_entries_.push_back(stack_frame_entry);
93 } 95 }
94 96
95 void Module::AddExtern(Extern *ext) { 97 void Module::AddExtern(Extern *ext) {
96 std::pair<ExternSet::iterator,bool> ret = externs_.insert(ext); 98 std::pair<ExternSet::iterator,bool> ret = externs_.insert(ext);
97 if (!ret.second) { 99 if (!ret.second) {
(...skipping 41 matching lines...) Expand 10 before | Expand all | Expand 10 after
139 return FindFile(name_string); 141 return FindFile(name_string);
140 } 142 }
141 143
142 Module::File *Module::FindExistingFile(const string &name) { 144 Module::File *Module::FindExistingFile(const string &name) {
143 FileByNameMap::iterator it = files_.find(&name); 145 FileByNameMap::iterator it = files_.find(&name);
144 return (it == files_.end()) ? NULL : it->second; 146 return (it == files_.end()) ? NULL : it->second;
145 } 147 }
146 148
147 void Module::GetFiles(vector<File *> *vec) { 149 void Module::GetFiles(vector<File *> *vec) {
148 vec->clear(); 150 vec->clear();
149 for (FileByNameMap::iterator it = files_.begin(); it != files_.end(); it++) 151 for (FileByNameMap::iterator it = files_.begin(); it != files_.end(); ++it)
150 vec->push_back(it->second); 152 vec->push_back(it->second);
151 } 153 }
152 154
153 void Module::GetStackFrameEntries(vector<StackFrameEntry *> *vec) { 155 void Module::GetStackFrameEntries(vector<StackFrameEntry *> *vec) {
154 *vec = stack_frame_entries_; 156 *vec = stack_frame_entries_;
155 } 157 }
156 158
157 void Module::AssignSourceIds() { 159 void Module::AssignSourceIds() {
158 // First, give every source file an id of -1. 160 // First, give every source file an id of -1.
159 for (FileByNameMap::iterator file_it = files_.begin(); 161 for (FileByNameMap::iterator file_it = files_.begin();
160 file_it != files_.end(); file_it++) 162 file_it != files_.end(); ++file_it) {
161 file_it->second->source_id = -1; 163 file_it->second->source_id = -1;
164 }
162 165
163 // Next, mark all files actually cited by our functions' line number 166 // Next, mark all files actually cited by our functions' line number
164 // info, by setting each one's source id to zero. 167 // info, by setting each one's source id to zero.
165 for (FunctionSet::const_iterator func_it = functions_.begin(); 168 for (FunctionSet::const_iterator func_it = functions_.begin();
166 func_it != functions_.end(); func_it++) { 169 func_it != functions_.end(); ++func_it) {
167 Function *func = *func_it; 170 Function *func = *func_it;
168 for (vector<Line>::iterator line_it = func->lines.begin(); 171 for (vector<Line>::iterator line_it = func->lines.begin();
169 line_it != func->lines.end(); line_it++) 172 line_it != func->lines.end(); ++line_it)
170 line_it->file->source_id = 0; 173 line_it->file->source_id = 0;
171 } 174 }
172 175
173 // Finally, assign source ids to those files that have been marked. 176 // Finally, assign source ids to those files that have been marked.
174 // We could have just assigned source id numbers while traversing 177 // We could have just assigned source id numbers while traversing
175 // the line numbers, but doing it this way numbers the files in 178 // the line numbers, but doing it this way numbers the files in
176 // lexicographical order by name, which is neat. 179 // lexicographical order by name, which is neat.
177 int next_source_id = 0; 180 int next_source_id = 0;
178 for (FileByNameMap::iterator file_it = files_.begin(); 181 for (FileByNameMap::iterator file_it = files_.begin();
179 file_it != files_.end(); file_it++) 182 file_it != files_.end(); ++file_it) {
180 if (!file_it->second->source_id) 183 if (!file_it->second->source_id)
181 file_it->second->source_id = next_source_id++; 184 file_it->second->source_id = next_source_id++;
185 }
182 } 186 }
183 187
184 bool Module::ReportError() { 188 bool Module::ReportError() {
185 fprintf(stderr, "error writing symbol file: %s\n", 189 fprintf(stderr, "error writing symbol file: %s\n",
186 strerror(errno)); 190 strerror(errno));
187 return false; 191 return false;
188 } 192 }
189 193
190 bool Module::WriteRuleMap(const RuleMap &rule_map, std::ostream &stream) { 194 bool Module::WriteRuleMap(const RuleMap &rule_map, std::ostream &stream) {
191 for (RuleMap::const_iterator it = rule_map.begin(); 195 for (RuleMap::const_iterator it = rule_map.begin();
192 it != rule_map.end(); it++) { 196 it != rule_map.end(); ++it) {
193 if (it != rule_map.begin()) 197 if (it != rule_map.begin())
194 stream << ' '; 198 stream << ' ';
195 stream << it->first << ": " << it->second; 199 stream << it->first << ": " << it->second;
196 } 200 }
197 return stream.good(); 201 return stream.good();
198 } 202 }
199 203
200 bool Module::Write(std::ostream &stream) { 204 bool Module::Write(std::ostream &stream, bool cfi) {
201 stream << "MODULE " << os_ << " " << architecture_ << " " 205 stream << "MODULE " << os_ << " " << architecture_ << " "
202 << id_ << " " << name_ << endl; 206 << id_ << " " << name_ << endl;
203 if (!stream.good()) 207 if (!stream.good())
204 return ReportError(); 208 return ReportError();
205 209
206 AssignSourceIds(); 210 AssignSourceIds();
207 211
208 // Write out files. 212 // Write out files.
209 for (FileByNameMap::iterator file_it = files_.begin(); 213 for (FileByNameMap::iterator file_it = files_.begin();
210 file_it != files_.end(); file_it++) { 214 file_it != files_.end(); ++file_it) {
211 File *file = file_it->second; 215 File *file = file_it->second;
212 if (file->source_id >= 0) { 216 if (file->source_id >= 0) {
213 stream << "FILE " << file->source_id << " " << file->name << endl; 217 stream << "FILE " << file->source_id << " " << file->name << endl;
214 if (!stream.good()) 218 if (!stream.good())
215 return ReportError(); 219 return ReportError();
216 } 220 }
217 } 221 }
218 222
219 // Write out functions and their lines. 223 // Write out functions and their lines.
220 for (FunctionSet::const_iterator func_it = functions_.begin(); 224 for (FunctionSet::const_iterator func_it = functions_.begin();
221 func_it != functions_.end(); func_it++) { 225 func_it != functions_.end(); ++func_it) {
222 Function *func = *func_it; 226 Function *func = *func_it;
223 assert(!func->name.empty()); 227 assert(!func->name.empty());
224 stream << "FUNC " << hex 228 stream << "FUNC " << hex
225 << (func->address - load_address_) << " " 229 << (func->address - load_address_) << " "
226 << func->size << " " 230 << func->size << " "
227 << func->parameter_size << " " 231 << func->parameter_size << " "
228 << func->name << dec << endl; 232 << func->name << dec << endl;
229 233
230 if (!stream.good()) 234 if (!stream.good())
231 return ReportError(); 235 return ReportError();
232 for (vector<Line>::iterator line_it = func->lines.begin(); 236 for (vector<Line>::iterator line_it = func->lines.begin();
233 line_it != func->lines.end(); line_it++) { 237 line_it != func->lines.end(); ++line_it) {
234 stream << hex 238 stream << hex
235 << (line_it->address - load_address_) << " " 239 << (line_it->address - load_address_) << " "
236 << line_it->size << " " 240 << line_it->size << " "
237 << dec 241 << dec
238 << line_it->number << " " 242 << line_it->number << " "
239 << line_it->file->source_id << endl; 243 << line_it->file->source_id << endl;
240 if (!stream.good()) 244 if (!stream.good())
241 return ReportError(); 245 return ReportError();
242 } 246 }
243 } 247 }
244 248
245 // Write out 'PUBLIC' records. 249 // Write out 'PUBLIC' records.
246 for (ExternSet::const_iterator extern_it = externs_.begin(); 250 for (ExternSet::const_iterator extern_it = externs_.begin();
247 extern_it != externs_.end(); extern_it++) { 251 extern_it != externs_.end(); ++extern_it) {
248 Extern *ext = *extern_it; 252 Extern *ext = *extern_it;
249 stream << "PUBLIC " << hex 253 stream << "PUBLIC " << hex
250 << (ext->address - load_address_) << " 0 " 254 << (ext->address - load_address_) << " 0 "
251 << ext->name << dec << endl; 255 << ext->name << dec << endl;
252 if (!stream.good()) 256 if (!stream.good())
253 return ReportError(); 257 return ReportError();
254 } 258 }
255 259
256 #if 0 260 if (cfi) {
257 // Bypass all of the "STACK CFI" stuff for the time being to work around 261 // Write out 'STACK CFI INIT' and 'STACK CFI' records.
258 // http://code.google.com/p/google-breakpad/issues/detail?id=443. 262 vector<StackFrameEntry *>::const_iterator frame_it;
259 // This should be fine as long as -fomit-frame-pointer is not in use. 263 for (frame_it = stack_frame_entries_.begin();
260 // Write out 'STACK CFI INIT' and 'STACK CFI' records. 264 frame_it != stack_frame_entries_.end(); ++frame_it) {
261 vector<StackFrameEntry *>::const_iterator frame_it; 265 StackFrameEntry *entry = *frame_it;
262 for (frame_it = stack_frame_entries_.begin(); 266 stream << "STACK CFI INIT " << hex
263 frame_it != stack_frame_entries_.end(); frame_it++) { 267 << (entry->address - load_address_) << " "
264 StackFrameEntry *entry = *frame_it; 268 << entry->size << " " << dec;
265 stream << "STACK CFI INIT " << hex
266 << (entry->address - load_address_) << " "
267 << entry->size << " " << dec;
268 if (!stream.good()
269 || !WriteRuleMap(entry->initial_rules, stream))
270 return ReportError();
271
272 stream << endl;
273
274 // Write out this entry's delta rules as 'STACK CFI' records.
275 for (RuleChangeMap::const_iterator delta_it = entry->rule_changes.begin();
276 delta_it != entry->rule_changes.end(); delta_it++) {
277 stream << "STACK CFI " << hex
278 << (delta_it->first - load_address_) << " " << dec;
279 if (!stream.good() 269 if (!stream.good()
280 || !WriteRuleMap(delta_it->second, stream)) 270 || !WriteRuleMap(entry->initial_rules, stream))
281 return ReportError(); 271 return ReportError();
282 272
283 stream << endl; 273 stream << endl;
274
275 // Write out this entry's delta rules as 'STACK CFI' records.
276 for (RuleChangeMap::const_iterator delta_it = entry->rule_changes.begin();
277 delta_it != entry->rule_changes.end(); ++delta_it) {
278 stream << "STACK CFI " << hex
279 << (delta_it->first - load_address_) << " " << dec;
280 if (!stream.good()
281 || !WriteRuleMap(delta_it->second, stream))
282 return ReportError();
283
284 stream << endl;
285 }
284 } 286 }
285 } 287 }
286 #endif
287 288
288 return true; 289 return true;
289 } 290 }
290 291
291 } // namespace google_breakpad 292 } // namespace google_breakpad
OLDNEW
« no previous file with comments | « breakpad/breakpad.gyp ('k') | chrome/app/breakpad_mac.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698