toolkit/crashreporter/google-breakpad/src/processor/stackwalker_unittest_utils.h

Wed, 31 Dec 2014 06:09:35 +0100

author
Michael Schloh von Bennewitz <michael@schloh.com>
date
Wed, 31 Dec 2014 06:09:35 +0100
changeset 0
6474c204b198
permissions
-rw-r--r--

Cloned upstream origin tor-browser at tor-browser-31.3.0esr-4.5-1-build1
revision ID fc1c9ff7c1b2defdbc039f12214767608f46423f for hacking purpose.

michael@0 1 // -*- mode: C++ -*-
michael@0 2
michael@0 3 // Copyright (c) 2010, Google Inc.
michael@0 4 // All rights reserved.
michael@0 5 //
michael@0 6 // Redistribution and use in source and binary forms, with or without
michael@0 7 // modification, are permitted provided that the following conditions are
michael@0 8 // met:
michael@0 9 //
michael@0 10 // * Redistributions of source code must retain the above copyright
michael@0 11 // notice, this list of conditions and the following disclaimer.
michael@0 12 // * Redistributions in binary form must reproduce the above
michael@0 13 // copyright notice, this list of conditions and the following disclaimer
michael@0 14 // in the documentation and/or other materials provided with the
michael@0 15 // distribution.
michael@0 16 // * Neither the name of Google Inc. nor the names of its
michael@0 17 // contributors may be used to endorse or promote products derived from
michael@0 18 // this software without specific prior written permission.
michael@0 19 //
michael@0 20 // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
michael@0 21 // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
michael@0 22 // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
michael@0 23 // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
michael@0 24 // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
michael@0 25 // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
michael@0 26 // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
michael@0 27 // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
michael@0 28 // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
michael@0 29 // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
michael@0 30 // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
michael@0 31
michael@0 32 // Original author: Jim Blandy <jimb@mozilla.com> <jimb@red-bean.com>
michael@0 33
michael@0 34 // Mock classes for writing stackwalker tests, shared amongst architectures.
michael@0 35
michael@0 36 #ifndef PROCESSOR_STACKWALKER_UNITTEST_UTILS_H_
michael@0 37 #define PROCESSOR_STACKWALKER_UNITTEST_UTILS_H_
michael@0 38
michael@0 39 #include <stdlib.h>
michael@0 40 #include <string>
michael@0 41 #include <vector>
michael@0 42
michael@0 43 #include "common/using_std_string.h"
michael@0 44 #include "google_breakpad/common/breakpad_types.h"
michael@0 45 #include "google_breakpad/processor/code_module.h"
michael@0 46 #include "google_breakpad/processor/code_modules.h"
michael@0 47 #include "google_breakpad/processor/memory_region.h"
michael@0 48 #include "google_breakpad/processor/symbol_supplier.h"
michael@0 49 #include "google_breakpad/processor/system_info.h"
michael@0 50
michael@0 51 class MockMemoryRegion: public google_breakpad::MemoryRegion {
michael@0 52 public:
michael@0 53 MockMemoryRegion(): base_address_(0) { }
michael@0 54
michael@0 55 // Set this region's address and contents. If we have placed an
michael@0 56 // instance of this class in a test fixture class, individual tests
michael@0 57 // can use this to provide the region's contents.
michael@0 58 void Init(uint64_t base_address, const string &contents) {
michael@0 59 base_address_ = base_address;
michael@0 60 contents_ = contents;
michael@0 61 }
michael@0 62
michael@0 63 uint64_t GetBase() const { return base_address_; }
michael@0 64 uint32_t GetSize() const { return contents_.size(); }
michael@0 65
michael@0 66 bool GetMemoryAtAddress(uint64_t address, uint8_t *value) const {
michael@0 67 return GetMemoryLittleEndian(address, value);
michael@0 68 }
michael@0 69 bool GetMemoryAtAddress(uint64_t address, uint16_t *value) const {
michael@0 70 return GetMemoryLittleEndian(address, value);
michael@0 71 }
michael@0 72 bool GetMemoryAtAddress(uint64_t address, uint32_t *value) const {
michael@0 73 return GetMemoryLittleEndian(address, value);
michael@0 74 }
michael@0 75 bool GetMemoryAtAddress(uint64_t address, uint64_t *value) const {
michael@0 76 return GetMemoryLittleEndian(address, value);
michael@0 77 }
michael@0 78
michael@0 79 private:
michael@0 80 // Fetch a little-endian value from ADDRESS in contents_ whose size
michael@0 81 // is BYTES, and store it in *VALUE. Return true on success.
michael@0 82 template<typename ValueType>
michael@0 83 bool GetMemoryLittleEndian(uint64_t address, ValueType *value) const {
michael@0 84 if (address < base_address_ ||
michael@0 85 address - base_address_ + sizeof(ValueType) > contents_.size())
michael@0 86 return false;
michael@0 87 ValueType v = 0;
michael@0 88 int start = address - base_address_;
michael@0 89 // The loop condition is odd, but it's correct for size_t.
michael@0 90 for (size_t i = sizeof(ValueType) - 1; i < sizeof(ValueType); i--)
michael@0 91 v = (v << 8) | static_cast<unsigned char>(contents_[start + i]);
michael@0 92 *value = v;
michael@0 93 return true;
michael@0 94 }
michael@0 95
michael@0 96 uint64_t base_address_;
michael@0 97 string contents_;
michael@0 98 };
michael@0 99
michael@0 100 class MockCodeModule: public google_breakpad::CodeModule {
michael@0 101 public:
michael@0 102 MockCodeModule(uint64_t base_address, uint64_t size,
michael@0 103 const string &code_file, const string &version)
michael@0 104 : base_address_(base_address), size_(size), code_file_(code_file) { }
michael@0 105
michael@0 106 uint64_t base_address() const { return base_address_; }
michael@0 107 uint64_t size() const { return size_; }
michael@0 108 string code_file() const { return code_file_; }
michael@0 109 string code_identifier() const { return code_file_; }
michael@0 110 string debug_file() const { return code_file_; }
michael@0 111 string debug_identifier() const { return code_file_; }
michael@0 112 string version() const { return version_; }
michael@0 113 const google_breakpad::CodeModule *Copy() const {
michael@0 114 abort(); // Tests won't use this.
michael@0 115 }
michael@0 116
michael@0 117 private:
michael@0 118 uint64_t base_address_;
michael@0 119 uint64_t size_;
michael@0 120 string code_file_;
michael@0 121 string version_;
michael@0 122 };
michael@0 123
michael@0 124 class MockCodeModules: public google_breakpad::CodeModules {
michael@0 125 public:
michael@0 126 typedef google_breakpad::CodeModule CodeModule;
michael@0 127 typedef google_breakpad::CodeModules CodeModules;
michael@0 128
michael@0 129 void Add(const MockCodeModule *module) {
michael@0 130 modules_.push_back(module);
michael@0 131 }
michael@0 132
michael@0 133 unsigned int module_count() const { return modules_.size(); }
michael@0 134
michael@0 135 const CodeModule *GetModuleForAddress(uint64_t address) const {
michael@0 136 for (ModuleVector::const_iterator i = modules_.begin();
michael@0 137 i != modules_.end(); i++) {
michael@0 138 const MockCodeModule *module = *i;
michael@0 139 if (module->base_address() <= address &&
michael@0 140 address - module->base_address() < module->size())
michael@0 141 return module;
michael@0 142 }
michael@0 143 return NULL;
michael@0 144 };
michael@0 145
michael@0 146 const CodeModule *GetMainModule() const { return modules_[0]; }
michael@0 147
michael@0 148 const CodeModule *GetModuleAtSequence(unsigned int sequence) const {
michael@0 149 return modules_.at(sequence);
michael@0 150 }
michael@0 151
michael@0 152 const CodeModule *GetModuleAtIndex(unsigned int index) const {
michael@0 153 return modules_.at(index);
michael@0 154 }
michael@0 155
michael@0 156 const CodeModules *Copy() const { abort(); } // Tests won't use this.
michael@0 157
michael@0 158 private:
michael@0 159 typedef std::vector<const MockCodeModule *> ModuleVector;
michael@0 160 ModuleVector modules_;
michael@0 161 };
michael@0 162
michael@0 163 class MockSymbolSupplier: public google_breakpad::SymbolSupplier {
michael@0 164 public:
michael@0 165 typedef google_breakpad::CodeModule CodeModule;
michael@0 166 typedef google_breakpad::SystemInfo SystemInfo;
michael@0 167 MOCK_METHOD3(GetSymbolFile, SymbolResult(const CodeModule *module,
michael@0 168 const SystemInfo *system_info,
michael@0 169 string *symbol_file));
michael@0 170 MOCK_METHOD4(GetSymbolFile, SymbolResult(const CodeModule *module,
michael@0 171 const SystemInfo *system_info,
michael@0 172 string *symbol_file,
michael@0 173 string *symbol_data));
michael@0 174 MOCK_METHOD4(GetCStringSymbolData, SymbolResult(const CodeModule *module,
michael@0 175 const SystemInfo *system_info,
michael@0 176 string *symbol_file,
michael@0 177 char **symbol_data));
michael@0 178 MOCK_METHOD1(FreeSymbolData, void(const CodeModule *module));
michael@0 179
michael@0 180 // Copies the passed string contents into a newly allocated buffer.
michael@0 181 // The newly allocated buffer will be freed during destruction.
michael@0 182 char* CopySymbolDataAndOwnTheCopy(const std::string &info) {
michael@0 183 unsigned int buffer_size = info.size() + 1;
michael@0 184 char *symbol_data = new char [buffer_size];
michael@0 185 strcpy(symbol_data, info.c_str());
michael@0 186 symbol_data_to_free_.push_back(symbol_data);
michael@0 187 return symbol_data;
michael@0 188 }
michael@0 189
michael@0 190 virtual ~MockSymbolSupplier() {
michael@0 191 for (SymbolDataVector::const_iterator i = symbol_data_to_free_.begin();
michael@0 192 i != symbol_data_to_free_.end(); i++) {
michael@0 193 char* symbol_data = *i;
michael@0 194 delete [] symbol_data;
michael@0 195 }
michael@0 196 }
michael@0 197
michael@0 198 private:
michael@0 199 // List of symbol data to be freed upon destruction
michael@0 200 typedef std::vector<char*> SymbolDataVector;
michael@0 201 SymbolDataVector symbol_data_to_free_;
michael@0 202 };
michael@0 203
michael@0 204 #endif // PROCESSOR_STACKWALKER_UNITTEST_UTILS_H_

mercurial