/thirdparty/breakpad/processor/stackwalker_unittest_utils.h

http://github.com/tomahawk-player/tomahawk · C Header · 180 lines · 117 code · 26 blank · 37 comment · 5 complexity · 4c44630c7c1b4702fc6257755c262be7 MD5 · raw file

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