| File: | root/firefox-clang/obj-x86_64-pc-linux-gnu/toolkit/crashreporter/google-breakpad/src/processor/./../../../../../../toolkit/crashreporter/google-breakpad/src/processor/source_line_resolver_base.cc |
| Warning: | line 100, column 5 Value stored to 'error_code' is never read |
Press '?' to see keyboard shortcuts
Keyboard shortcuts:
| 1 | // Copyright (c) 2010 Google Inc. |
| 2 | // All rights reserved. |
| 3 | // |
| 4 | // Redistribution and use in source and binary forms, with or without |
| 5 | // modification, are permitted provided that the following conditions are |
| 6 | // met: |
| 7 | // |
| 8 | // * Redistributions of source code must retain the above copyright |
| 9 | // notice, this list of conditions and the following disclaimer. |
| 10 | // * Redistributions in binary form must reproduce the above |
| 11 | // copyright notice, this list of conditions and the following disclaimer |
| 12 | // in the documentation and/or other materials provided with the |
| 13 | // distribution. |
| 14 | // * Neither the name of Google Inc. nor the names of its |
| 15 | // contributors may be used to endorse or promote products derived from |
| 16 | // this software without specific prior written permission. |
| 17 | // |
| 18 | // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS |
| 19 | // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT |
| 20 | // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR |
| 21 | // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT |
| 22 | // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, |
| 23 | // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT |
| 24 | // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, |
| 25 | // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY |
| 26 | // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT |
| 27 | // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE |
| 28 | // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
| 29 | // |
| 30 | // source_line_resolver_base.cc: Implementation of SourceLineResolverBase. |
| 31 | // |
| 32 | // See source_line_resolver_base.h and source_line_resolver_base_types.h for |
| 33 | // more documentation. |
| 34 | // |
| 35 | // Author: Siyang Xie (lambxsy@google.com) |
| 36 | |
| 37 | #include <stdio.h> |
| 38 | #include <string.h> |
| 39 | #include <sys/stat.h> |
| 40 | |
| 41 | #include <map> |
| 42 | #include <utility> |
| 43 | |
| 44 | #include "google_breakpad/processor/source_line_resolver_base.h" |
| 45 | #include "processor/source_line_resolver_base_types.h" |
| 46 | #include "processor/module_factory.h" |
| 47 | |
| 48 | using std::map; |
| 49 | using std::make_pair; |
| 50 | |
| 51 | namespace google_breakpad { |
| 52 | |
| 53 | SourceLineResolverBase::SourceLineResolverBase( |
| 54 | ModuleFactory *module_factory) |
| 55 | : modules_(new ModuleMap), |
| 56 | corrupt_modules_(new ModuleSet), |
| 57 | memory_buffers_(new MemoryMap), |
| 58 | module_factory_(module_factory) { |
| 59 | } |
| 60 | |
| 61 | SourceLineResolverBase::~SourceLineResolverBase() { |
| 62 | ModuleMap::iterator it; |
| 63 | // Iterate through ModuleMap and delete all loaded modules. |
| 64 | for (it = modules_->begin(); it != modules_->end(); ++it) { |
| 65 | // Delete individual module. |
| 66 | delete it->second; |
| 67 | } |
| 68 | // Delete the map of modules. |
| 69 | delete modules_; |
| 70 | modules_ = NULL__null; |
| 71 | |
| 72 | // Delete the set of corrupt modules. |
| 73 | delete corrupt_modules_; |
| 74 | corrupt_modules_ = NULL__null; |
| 75 | |
| 76 | MemoryMap::iterator iter = memory_buffers_->begin(); |
| 77 | for (; iter != memory_buffers_->end(); ++iter) { |
| 78 | delete [] iter->second; |
| 79 | } |
| 80 | // Delete the map of memory buffers. |
| 81 | delete memory_buffers_; |
| 82 | memory_buffers_ = NULL__null; |
| 83 | |
| 84 | delete module_factory_; |
| 85 | module_factory_ = NULL__null; |
| 86 | } |
| 87 | |
| 88 | bool SourceLineResolverBase::ReadSymbolFile(const string &map_file, |
| 89 | char **symbol_data, |
| 90 | size_t *symbol_data_size) { |
| 91 | if (symbol_data == NULL__null || symbol_data_size == NULL__null) { |
| 92 | BPLOG(ERROR)!(((google_breakpad::LogStream::SEVERITY_ERROR) >= (google_breakpad ::LogStream::SEVERITY_CRITICAL))) ? (void) 0 : google_breakpad ::LogMessageVoidify() & (google_breakpad::LogStream(std:: cerr, google_breakpad::LogStream::SEVERITY_ERROR, "./../../../../../../toolkit/crashreporter/google-breakpad/src/processor/source_line_resolver_base.cc" , 92)) << "Could not Read file into Null memory pointer"; |
| 93 | return false; |
| 94 | } |
| 95 | |
| 96 | struct stat buf; |
| 97 | int error_code = stat(map_file.c_str(), &buf); |
| 98 | if (error_code == -1) { |
| 99 | string error_string; |
| 100 | error_code = ErrnoString(&error_string); |
Value stored to 'error_code' is never read | |
| 101 | BPLOG(ERROR)!(((google_breakpad::LogStream::SEVERITY_ERROR) >= (google_breakpad ::LogStream::SEVERITY_CRITICAL))) ? (void) 0 : google_breakpad ::LogMessageVoidify() & (google_breakpad::LogStream(std:: cerr, google_breakpad::LogStream::SEVERITY_ERROR, "./../../../../../../toolkit/crashreporter/google-breakpad/src/processor/source_line_resolver_base.cc" , 101)) << "Could not open " << map_file << |
| 102 | ", error " << error_code << ": " << error_string; |
| 103 | return false; |
| 104 | } |
| 105 | |
| 106 | off_t file_size = buf.st_size; |
| 107 | |
| 108 | // Allocate memory for file contents, plus a null terminator |
| 109 | // since we may use strtok() on the contents. |
| 110 | *symbol_data_size = file_size + 1; |
| 111 | *symbol_data = new char[file_size + 1]; |
| 112 | |
| 113 | if (*symbol_data == NULL__null) { |
| 114 | BPLOG(ERROR)!(((google_breakpad::LogStream::SEVERITY_ERROR) >= (google_breakpad ::LogStream::SEVERITY_CRITICAL))) ? (void) 0 : google_breakpad ::LogMessageVoidify() & (google_breakpad::LogStream(std:: cerr, google_breakpad::LogStream::SEVERITY_ERROR, "./../../../../../../toolkit/crashreporter/google-breakpad/src/processor/source_line_resolver_base.cc" , 114)) << "Could not allocate memory for " << map_file; |
| 115 | return false; |
| 116 | } |
| 117 | |
| 118 | BPLOG(INFO)!(((google_breakpad::LogStream::SEVERITY_INFO) >= (google_breakpad ::LogStream::SEVERITY_CRITICAL))) ? (void) 0 : google_breakpad ::LogMessageVoidify() & (google_breakpad::LogStream(std:: clog, google_breakpad::LogStream::SEVERITY_INFO, "./../../../../../../toolkit/crashreporter/google-breakpad/src/processor/source_line_resolver_base.cc" , 118)) << "Opening " << map_file; |
| 119 | |
| 120 | FILE *f = fopen(map_file.c_str(), "rt"); |
| 121 | if (!f) { |
| 122 | string error_string; |
| 123 | error_code = ErrnoString(&error_string); |
| 124 | BPLOG(ERROR)!(((google_breakpad::LogStream::SEVERITY_ERROR) >= (google_breakpad ::LogStream::SEVERITY_CRITICAL))) ? (void) 0 : google_breakpad ::LogMessageVoidify() & (google_breakpad::LogStream(std:: cerr, google_breakpad::LogStream::SEVERITY_ERROR, "./../../../../../../toolkit/crashreporter/google-breakpad/src/processor/source_line_resolver_base.cc" , 124)) << "Could not open " << map_file << |
| 125 | ", error " << error_code << ": " << error_string; |
| 126 | delete [] (*symbol_data); |
| 127 | *symbol_data = NULL__null; |
| 128 | return false; |
| 129 | } |
| 130 | |
| 131 | AutoFileCloser closer(f); |
| 132 | |
| 133 | int items_read = 0; |
| 134 | |
| 135 | items_read = fread(*symbol_data, 1, file_size, f); |
| 136 | |
| 137 | if (items_read != file_size) { |
| 138 | string error_string; |
| 139 | error_code = ErrnoString(&error_string); |
| 140 | BPLOG(ERROR)!(((google_breakpad::LogStream::SEVERITY_ERROR) >= (google_breakpad ::LogStream::SEVERITY_CRITICAL))) ? (void) 0 : google_breakpad ::LogMessageVoidify() & (google_breakpad::LogStream(std:: cerr, google_breakpad::LogStream::SEVERITY_ERROR, "./../../../../../../toolkit/crashreporter/google-breakpad/src/processor/source_line_resolver_base.cc" , 140)) << "Could not slurp " << map_file << |
| 141 | ", error " << error_code << ": " << error_string; |
| 142 | delete [] (*symbol_data); |
| 143 | *symbol_data = NULL__null; |
| 144 | return false; |
| 145 | } |
| 146 | |
| 147 | (*symbol_data)[file_size] = '\0'; |
| 148 | return true; |
| 149 | } |
| 150 | |
| 151 | bool SourceLineResolverBase::LoadModule(const CodeModule *module, |
| 152 | const string &map_file) { |
| 153 | if (module == NULL__null) |
| 154 | return false; |
| 155 | |
| 156 | // Make sure we don't already have a module with the given name. |
| 157 | if (modules_->find(module->code_file()) != modules_->end()) { |
| 158 | BPLOG(INFO)!(((google_breakpad::LogStream::SEVERITY_INFO) >= (google_breakpad ::LogStream::SEVERITY_CRITICAL))) ? (void) 0 : google_breakpad ::LogMessageVoidify() & (google_breakpad::LogStream(std:: clog, google_breakpad::LogStream::SEVERITY_INFO, "./../../../../../../toolkit/crashreporter/google-breakpad/src/processor/source_line_resolver_base.cc" , 158)) << "Symbols for module " << module->code_file() |
| 159 | << " already loaded"; |
| 160 | return false; |
| 161 | } |
| 162 | |
| 163 | BPLOG(INFO)!(((google_breakpad::LogStream::SEVERITY_INFO) >= (google_breakpad ::LogStream::SEVERITY_CRITICAL))) ? (void) 0 : google_breakpad ::LogMessageVoidify() & (google_breakpad::LogStream(std:: clog, google_breakpad::LogStream::SEVERITY_INFO, "./../../../../../../toolkit/crashreporter/google-breakpad/src/processor/source_line_resolver_base.cc" , 163)) << "Loading symbols for module " << module->code_file() |
| 164 | << " from " << map_file; |
| 165 | |
| 166 | char *memory_buffer; |
| 167 | size_t memory_buffer_size; |
| 168 | if (!ReadSymbolFile(map_file, &memory_buffer, &memory_buffer_size)) |
| 169 | return false; |
| 170 | |
| 171 | BPLOG(INFO)!(((google_breakpad::LogStream::SEVERITY_INFO) >= (google_breakpad ::LogStream::SEVERITY_CRITICAL))) ? (void) 0 : google_breakpad ::LogMessageVoidify() & (google_breakpad::LogStream(std:: clog, google_breakpad::LogStream::SEVERITY_INFO, "./../../../../../../toolkit/crashreporter/google-breakpad/src/processor/source_line_resolver_base.cc" , 171)) << "Read symbol file " << map_file << " succeeded"; |
| 172 | |
| 173 | bool load_result = LoadModuleUsingMemoryBuffer(module, memory_buffer, |
| 174 | memory_buffer_size); |
| 175 | |
| 176 | if (load_result && !ShouldDeleteMemoryBufferAfterLoadModule()) { |
| 177 | // memory_buffer has to stay alive as long as the module. |
| 178 | memory_buffers_->insert(make_pair(module->code_file(), memory_buffer)); |
| 179 | } else { |
| 180 | delete [] memory_buffer; |
| 181 | } |
| 182 | |
| 183 | return load_result; |
| 184 | } |
| 185 | |
| 186 | bool SourceLineResolverBase::LoadModuleUsingMapBuffer( |
| 187 | const CodeModule *module, const string &map_buffer) { |
| 188 | if (module == NULL__null) |
| 189 | return false; |
| 190 | |
| 191 | // Make sure we don't already have a module with the given name. |
| 192 | if (modules_->find(module->code_file()) != modules_->end()) { |
| 193 | BPLOG(INFO)!(((google_breakpad::LogStream::SEVERITY_INFO) >= (google_breakpad ::LogStream::SEVERITY_CRITICAL))) ? (void) 0 : google_breakpad ::LogMessageVoidify() & (google_breakpad::LogStream(std:: clog, google_breakpad::LogStream::SEVERITY_INFO, "./../../../../../../toolkit/crashreporter/google-breakpad/src/processor/source_line_resolver_base.cc" , 193)) << "Symbols for module " << module->code_file() |
| 194 | << " already loaded"; |
| 195 | return false; |
| 196 | } |
| 197 | |
| 198 | size_t memory_buffer_size = map_buffer.size() + 1; |
| 199 | char *memory_buffer = new char[memory_buffer_size]; |
| 200 | if (memory_buffer == NULL__null) { |
| 201 | BPLOG(ERROR)!(((google_breakpad::LogStream::SEVERITY_ERROR) >= (google_breakpad ::LogStream::SEVERITY_CRITICAL))) ? (void) 0 : google_breakpad ::LogMessageVoidify() & (google_breakpad::LogStream(std:: cerr, google_breakpad::LogStream::SEVERITY_ERROR, "./../../../../../../toolkit/crashreporter/google-breakpad/src/processor/source_line_resolver_base.cc" , 201)) << "Could not allocate memory for " << module->code_file(); |
| 202 | return false; |
| 203 | } |
| 204 | |
| 205 | // Can't use strcpy, as the data may contain '\0's before the end. |
| 206 | memcpy(memory_buffer, map_buffer.c_str(), map_buffer.size()); |
| 207 | memory_buffer[map_buffer.size()] = '\0'; |
| 208 | |
| 209 | bool load_result = LoadModuleUsingMemoryBuffer(module, memory_buffer, |
| 210 | memory_buffer_size); |
| 211 | |
| 212 | if (load_result && !ShouldDeleteMemoryBufferAfterLoadModule()) { |
| 213 | // memory_buffer has to stay alive as long as the module. |
| 214 | memory_buffers_->insert(make_pair(module->code_file(), memory_buffer)); |
| 215 | } else { |
| 216 | delete [] memory_buffer; |
| 217 | } |
| 218 | |
| 219 | return load_result; |
| 220 | } |
| 221 | |
| 222 | bool SourceLineResolverBase::LoadModuleUsingMemoryBuffer( |
| 223 | const CodeModule *module, |
| 224 | char *memory_buffer, |
| 225 | size_t memory_buffer_size) { |
| 226 | if (!module) |
| 227 | return false; |
| 228 | |
| 229 | // Make sure we don't already have a module with the given name. |
| 230 | if (modules_->find(module->code_file()) != modules_->end()) { |
| 231 | BPLOG(INFO)!(((google_breakpad::LogStream::SEVERITY_INFO) >= (google_breakpad ::LogStream::SEVERITY_CRITICAL))) ? (void) 0 : google_breakpad ::LogMessageVoidify() & (google_breakpad::LogStream(std:: clog, google_breakpad::LogStream::SEVERITY_INFO, "./../../../../../../toolkit/crashreporter/google-breakpad/src/processor/source_line_resolver_base.cc" , 231)) << "Symbols for module " << module->code_file() |
| 232 | << " already loaded"; |
| 233 | return false; |
| 234 | } |
| 235 | |
| 236 | BPLOG(INFO)!(((google_breakpad::LogStream::SEVERITY_INFO) >= (google_breakpad ::LogStream::SEVERITY_CRITICAL))) ? (void) 0 : google_breakpad ::LogMessageVoidify() & (google_breakpad::LogStream(std:: clog, google_breakpad::LogStream::SEVERITY_INFO, "./../../../../../../toolkit/crashreporter/google-breakpad/src/processor/source_line_resolver_base.cc" , 236)) << "Loading symbols for module " << module->code_file() |
| 237 | << " from memory buffer"; |
| 238 | |
| 239 | Module *basic_module = module_factory_->CreateModule(module->code_file()); |
| 240 | |
| 241 | // Ownership of memory is NOT transfered to Module::LoadMapFromMemory(). |
| 242 | if (!basic_module->LoadMapFromMemory(memory_buffer, memory_buffer_size)) { |
| 243 | BPLOG(ERROR)!(((google_breakpad::LogStream::SEVERITY_ERROR) >= (google_breakpad ::LogStream::SEVERITY_CRITICAL))) ? (void) 0 : google_breakpad ::LogMessageVoidify() & (google_breakpad::LogStream(std:: cerr, google_breakpad::LogStream::SEVERITY_ERROR, "./../../../../../../toolkit/crashreporter/google-breakpad/src/processor/source_line_resolver_base.cc" , 243)) << "Too many error while parsing symbol data for module " |
| 244 | << module->code_file(); |
| 245 | // Returning false from here would be an indication that the symbols for |
| 246 | // this module are missing which would be wrong. Intentionally fall through |
| 247 | // and add the module to both the modules_ and the corrupt_modules_ lists. |
| 248 | assert(basic_module->IsCorrupt())(static_cast <bool> (basic_module->IsCorrupt()) ? void (0) : __assert_fail ("basic_module->IsCorrupt()", __builtin_FILE (), __builtin_LINE (), __extension__ __PRETTY_FUNCTION__)); |
| 249 | } |
| 250 | |
| 251 | modules_->insert(make_pair(module->code_file(), basic_module)); |
| 252 | if (basic_module->IsCorrupt()) { |
| 253 | corrupt_modules_->insert(module->code_file()); |
| 254 | } |
| 255 | return true; |
| 256 | } |
| 257 | |
| 258 | bool SourceLineResolverBase::ShouldDeleteMemoryBufferAfterLoadModule() { |
| 259 | return true; |
| 260 | } |
| 261 | |
| 262 | void SourceLineResolverBase::UnloadModule(const CodeModule *code_module) { |
| 263 | if (!code_module) |
| 264 | return; |
| 265 | |
| 266 | ModuleMap::iterator mod_iter = modules_->find(code_module->code_file()); |
| 267 | if (mod_iter != modules_->end()) { |
| 268 | Module *symbol_module = mod_iter->second; |
| 269 | delete symbol_module; |
| 270 | corrupt_modules_->erase(mod_iter->first); |
| 271 | modules_->erase(mod_iter); |
| 272 | } |
| 273 | |
| 274 | if (ShouldDeleteMemoryBufferAfterLoadModule()) { |
| 275 | // No-op. Because we never store any memory buffers. |
| 276 | } else { |
| 277 | // There may be a buffer stored locally, we need to find and delete it. |
| 278 | MemoryMap::iterator iter = memory_buffers_->find(code_module->code_file()); |
| 279 | if (iter != memory_buffers_->end()) { |
| 280 | delete [] iter->second; |
| 281 | memory_buffers_->erase(iter); |
| 282 | } |
| 283 | } |
| 284 | } |
| 285 | |
| 286 | bool SourceLineResolverBase::HasModule(const CodeModule *module) { |
| 287 | if (!module) |
| 288 | return false; |
| 289 | return modules_->find(module->code_file()) != modules_->end(); |
| 290 | } |
| 291 | |
| 292 | bool SourceLineResolverBase::IsModuleCorrupt(const CodeModule *module) { |
| 293 | if (!module) |
| 294 | return false; |
| 295 | return corrupt_modules_->find(module->code_file()) != corrupt_modules_->end(); |
| 296 | } |
| 297 | |
| 298 | void SourceLineResolverBase::FillSourceLineInfo(StackFrame *frame) { |
| 299 | if (frame->module) { |
| 300 | ModuleMap::const_iterator it = modules_->find(frame->module->code_file()); |
| 301 | if (it != modules_->end()) { |
| 302 | it->second->LookupAddress(frame); |
| 303 | } |
| 304 | } |
| 305 | } |
| 306 | |
| 307 | WindowsFrameInfo *SourceLineResolverBase::FindWindowsFrameInfo( |
| 308 | const StackFrame *frame) { |
| 309 | if (frame->module) { |
| 310 | ModuleMap::const_iterator it = modules_->find(frame->module->code_file()); |
| 311 | if (it != modules_->end()) { |
| 312 | return it->second->FindWindowsFrameInfo(frame); |
| 313 | } |
| 314 | } |
| 315 | return NULL__null; |
| 316 | } |
| 317 | |
| 318 | CFIFrameInfo *SourceLineResolverBase::FindCFIFrameInfo( |
| 319 | const StackFrame *frame) { |
| 320 | if (frame->module) { |
| 321 | ModuleMap::const_iterator it = modules_->find(frame->module->code_file()); |
| 322 | if (it != modules_->end()) { |
| 323 | return it->second->FindCFIFrameInfo(frame); |
| 324 | } |
| 325 | } |
| 326 | return NULL__null; |
| 327 | } |
| 328 | |
| 329 | bool SourceLineResolverBase::CompareString::operator()( |
| 330 | const string &s1, const string &s2) const { |
| 331 | return strcmp(s1.c_str(), s2.c_str()) < 0; |
| 332 | } |
| 333 | |
| 334 | bool SourceLineResolverBase::Module::ParseCFIRuleSet( |
| 335 | const string &rule_set, CFIFrameInfo *frame_info) const { |
| 336 | CFIFrameInfoParseHandler handler(frame_info); |
| 337 | CFIRuleParser parser(&handler); |
| 338 | return parser.Parse(rule_set); |
| 339 | } |
| 340 | |
| 341 | } // namespace google_breakpad |