toolkit/crashreporter/google-breakpad/src/processor/module_comparer.cc

changeset 0
6474c204b198
     1.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     1.2 +++ b/toolkit/crashreporter/google-breakpad/src/processor/module_comparer.cc	Wed Dec 31 06:09:35 2014 +0100
     1.3 @@ -0,0 +1,298 @@
     1.4 +// Copyright (c) 2010, Google Inc.
     1.5 +// All rights reserved.
     1.6 +//
     1.7 +// Redistribution and use in source and binary forms, with or without
     1.8 +// modification, are permitted provided that the following conditions are
     1.9 +// met:
    1.10 +//
    1.11 +//     * Redistributions of source code must retain the above copyright
    1.12 +// notice, this list of conditions and the following disclaimer.
    1.13 +//     * Redistributions in binary form must reproduce the above
    1.14 +// copyright notice, this list of conditions and the following disclaimer
    1.15 +// in the documentation and/or other materials provided with the
    1.16 +// distribution.
    1.17 +//     * Neither the name of Google Inc. nor the names of its
    1.18 +// contributors may be used to endorse or promote products derived from
    1.19 +// this software without specific prior written permission.
    1.20 +//
    1.21 +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
    1.22 +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
    1.23 +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
    1.24 +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
    1.25 +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
    1.26 +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
    1.27 +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
    1.28 +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
    1.29 +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
    1.30 +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
    1.31 +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
    1.32 +//
    1.33 +// module_comparer.cc: ModuleComparer implementation.
    1.34 +// See module_comparer.h for documentation.
    1.35 +//
    1.36 +// Author: lambxsy@google.com (Siyang Xie)
    1.37 +
    1.38 +#include "processor/module_comparer.h"
    1.39 +
    1.40 +#include <map>
    1.41 +#include <string>
    1.42 +
    1.43 +#include "common/scoped_ptr.h"
    1.44 +#include "processor/basic_code_module.h"
    1.45 +#include "processor/logging.h"
    1.46 +
    1.47 +#define ASSERT_TRUE(condition) \
    1.48 +  if (!(condition)) { \
    1.49 +    BPLOG(ERROR) << "FAIL: " << #condition << " @ " \
    1.50 +                 << __FILE__ << ":" << __LINE__; \
    1.51 +    return false; \
    1.52 +  }
    1.53 +
    1.54 +#define ASSERT_FALSE(condition) ASSERT_TRUE(!(condition))
    1.55 +
    1.56 +namespace google_breakpad {
    1.57 +
    1.58 +bool ModuleComparer::Compare(const string &symbol_data) {
    1.59 +  scoped_ptr<BasicModule> basic_module(new BasicModule("test_module"));
    1.60 +  scoped_ptr<FastModule> fast_module(new FastModule("test_module"));
    1.61 +
    1.62 +  // Load symbol data into basic_module
    1.63 +  scoped_array<char> buffer(new char[symbol_data.size() + 1]);
    1.64 +  strcpy(buffer.get(), symbol_data.c_str());
    1.65 +  ASSERT_TRUE(basic_module->LoadMapFromMemory(buffer.get()));
    1.66 +  buffer.reset();
    1.67 +
    1.68 +  // Serialize BasicSourceLineResolver::Module.
    1.69 +  unsigned int serialized_size = 0;
    1.70 +  scoped_array<char> serialized_data(
    1.71 +      serializer_.Serialize(*(basic_module.get()), &serialized_size));
    1.72 +  ASSERT_TRUE(serialized_data.get());
    1.73 +  BPLOG(INFO) << "Serialized size = " << serialized_size << " Bytes";
    1.74 +
    1.75 +  // Load FastSourceLineResolver::Module using serialized data.
    1.76 +  ASSERT_TRUE(fast_module->LoadMapFromMemory(serialized_data.get()));
    1.77 +
    1.78 +  // Compare FastSourceLineResolver::Module with
    1.79 +  // BasicSourceLineResolver::Module.
    1.80 +  ASSERT_TRUE(CompareModule(basic_module.get(), fast_module.get()));
    1.81 +
    1.82 +  return true;
    1.83 +}
    1.84 +
    1.85 +// Traversal the content of module and do comparison
    1.86 +bool ModuleComparer::CompareModule(const BasicModule *basic_module,
    1.87 +                                  const FastModule *fast_module) const {
    1.88 +  // Compare name_.
    1.89 +  ASSERT_TRUE(basic_module->name_ == fast_module->name_);
    1.90 +
    1.91 +  // Compare files_:
    1.92 +  {
    1.93 +    BasicModule::FileMap::const_iterator iter1 = basic_module->files_.begin();
    1.94 +    FastModule::FileMap::iterator iter2 = fast_module->files_.begin();
    1.95 +    while (iter1 != basic_module->files_.end()
    1.96 +        && iter2 != fast_module->files_.end()) {
    1.97 +      ASSERT_TRUE(iter1->first == iter2.GetKey());
    1.98 +      string tmp(iter2.GetValuePtr());
    1.99 +      ASSERT_TRUE(iter1->second == tmp);
   1.100 +      ++iter1;
   1.101 +      ++iter2;
   1.102 +    }
   1.103 +    ASSERT_TRUE(iter1 == basic_module->files_.end());
   1.104 +    ASSERT_TRUE(iter2 == fast_module->files_.end());
   1.105 +  }
   1.106 +
   1.107 +  // Compare functions_:
   1.108 +  {
   1.109 +    RangeMap<MemAddr, linked_ptr<BasicFunc> >::MapConstIterator iter1;
   1.110 +    StaticRangeMap<MemAddr, FastFunc>::MapConstIterator iter2;
   1.111 +    iter1 = basic_module->functions_.map_.begin();
   1.112 +    iter2 = fast_module->functions_.map_.begin();
   1.113 +    while (iter1 != basic_module->functions_.map_.end()
   1.114 +        && iter2 != fast_module->functions_.map_.end()) {
   1.115 +      ASSERT_TRUE(iter1->first == iter2.GetKey());
   1.116 +      ASSERT_TRUE(iter1->second.base() == iter2.GetValuePtr()->base());
   1.117 +      ASSERT_TRUE(CompareFunction(
   1.118 +          iter1->second.entry().get(), iter2.GetValuePtr()->entryptr()));
   1.119 +      ++iter1;
   1.120 +      ++iter2;
   1.121 +    }
   1.122 +    ASSERT_TRUE(iter1 == basic_module->functions_.map_.end());
   1.123 +    ASSERT_TRUE(iter2 == fast_module->functions_.map_.end());
   1.124 +  }
   1.125 +
   1.126 +  // Compare public_symbols_:
   1.127 +  {
   1.128 +    AddressMap<MemAddr, linked_ptr<BasicPubSymbol> >::MapConstIterator iter1;
   1.129 +    StaticAddressMap<MemAddr, FastPubSymbol>::MapConstIterator iter2;
   1.130 +    iter1 = basic_module->public_symbols_.map_.begin();
   1.131 +    iter2 = fast_module->public_symbols_.map_.begin();
   1.132 +    while (iter1 != basic_module->public_symbols_.map_.end()
   1.133 +          && iter2 != fast_module->public_symbols_.map_.end()) {
   1.134 +      ASSERT_TRUE(iter1->first == iter2.GetKey());
   1.135 +      ASSERT_TRUE(ComparePubSymbol(
   1.136 +          iter1->second.get(), iter2.GetValuePtr()));
   1.137 +      ++iter1;
   1.138 +      ++iter2;
   1.139 +    }
   1.140 +    ASSERT_TRUE(iter1 == basic_module->public_symbols_.map_.end());
   1.141 +    ASSERT_TRUE(iter2 == fast_module->public_symbols_.map_.end());
   1.142 +  }
   1.143 +
   1.144 +  // Compare windows_frame_info_[]:
   1.145 +  for (int i = 0; i < WindowsFrameInfo::STACK_INFO_LAST; ++i) {
   1.146 +    ASSERT_TRUE(CompareCRM(&(basic_module->windows_frame_info_[i]),
   1.147 +                           &(fast_module->windows_frame_info_[i])));
   1.148 +  }
   1.149 +
   1.150 +  // Compare cfi_initial_rules_:
   1.151 +  {
   1.152 +    RangeMap<MemAddr, string>::MapConstIterator iter1;
   1.153 +    StaticRangeMap<MemAddr, char>::MapConstIterator iter2;
   1.154 +    iter1 = basic_module->cfi_initial_rules_.map_.begin();
   1.155 +    iter2 = fast_module->cfi_initial_rules_.map_.begin();
   1.156 +    while (iter1 != basic_module->cfi_initial_rules_.map_.end()
   1.157 +        && iter2 != fast_module->cfi_initial_rules_.map_.end()) {
   1.158 +      ASSERT_TRUE(iter1->first == iter2.GetKey());
   1.159 +      ASSERT_TRUE(iter1->second.base() == iter2.GetValuePtr()->base());
   1.160 +      string tmp(iter2.GetValuePtr()->entryptr());
   1.161 +      ASSERT_TRUE(iter1->second.entry() == tmp);
   1.162 +      ++iter1;
   1.163 +      ++iter2;
   1.164 +    }
   1.165 +    ASSERT_TRUE(iter1 == basic_module->cfi_initial_rules_.map_.end());
   1.166 +    ASSERT_TRUE(iter2 == fast_module->cfi_initial_rules_.map_.end());
   1.167 +  }
   1.168 +
   1.169 +  // Compare cfi_delta_rules_:
   1.170 +  {
   1.171 +    map<MemAddr, string>::const_iterator iter1;
   1.172 +    StaticMap<MemAddr, char>::iterator iter2;
   1.173 +    iter1 = basic_module->cfi_delta_rules_.begin();
   1.174 +    iter2 = fast_module->cfi_delta_rules_.begin();
   1.175 +    while (iter1 != basic_module->cfi_delta_rules_.end()
   1.176 +        && iter2 != fast_module->cfi_delta_rules_.end()) {
   1.177 +      ASSERT_TRUE(iter1->first == iter2.GetKey());
   1.178 +      string tmp(iter2.GetValuePtr());
   1.179 +      ASSERT_TRUE(iter1->second == tmp);
   1.180 +      ++iter1;
   1.181 +      ++iter2;
   1.182 +    }
   1.183 +    ASSERT_TRUE(iter1 == basic_module->cfi_delta_rules_.end());
   1.184 +    ASSERT_TRUE(iter2 == fast_module->cfi_delta_rules_.end());
   1.185 +  }
   1.186 +
   1.187 +  return true;
   1.188 +}
   1.189 +
   1.190 +bool ModuleComparer::CompareFunction(const BasicFunc *basic_func,
   1.191 +                                    const FastFunc *fast_func_raw) const {
   1.192 +  FastFunc* fast_func = new FastFunc();
   1.193 +  fast_func->CopyFrom(fast_func_raw);
   1.194 +  ASSERT_TRUE(basic_func->name == fast_func->name);
   1.195 +  ASSERT_TRUE(basic_func->address == fast_func->address);
   1.196 +  ASSERT_TRUE(basic_func->size == fast_func->size);
   1.197 +
   1.198 +  // compare range map of lines:
   1.199 +  RangeMap<MemAddr, linked_ptr<BasicLine> >::MapConstIterator iter1;
   1.200 +  StaticRangeMap<MemAddr, FastLine>::MapConstIterator iter2;
   1.201 +  iter1 = basic_func->lines.map_.begin();
   1.202 +  iter2 = fast_func->lines.map_.begin();
   1.203 +  while (iter1 != basic_func->lines.map_.end()
   1.204 +      && iter2 != fast_func->lines.map_.end()) {
   1.205 +    ASSERT_TRUE(iter1->first == iter2.GetKey());
   1.206 +    ASSERT_TRUE(iter1->second.base() == iter2.GetValuePtr()->base());
   1.207 +    ASSERT_TRUE(CompareLine(iter1->second.entry().get(),
   1.208 +                            iter2.GetValuePtr()->entryptr()));
   1.209 +    ++iter1;
   1.210 +    ++iter2;
   1.211 +  }
   1.212 +  ASSERT_TRUE(iter1 == basic_func->lines.map_.end());
   1.213 +  ASSERT_TRUE(iter2 == fast_func->lines.map_.end());
   1.214 +
   1.215 +  delete fast_func;
   1.216 +  return true;
   1.217 +}
   1.218 +
   1.219 +bool ModuleComparer::CompareLine(const BasicLine *basic_line,
   1.220 +                                const FastLine *fast_line_raw) const {
   1.221 +  FastLine *fast_line = new FastLine;
   1.222 +  fast_line->CopyFrom(fast_line_raw);
   1.223 +
   1.224 +  ASSERT_TRUE(basic_line->address == fast_line->address);
   1.225 +  ASSERT_TRUE(basic_line->size == fast_line->size);
   1.226 +  ASSERT_TRUE(basic_line->source_file_id == fast_line->source_file_id);
   1.227 +  ASSERT_TRUE(basic_line->line == fast_line->line);
   1.228 +
   1.229 +  delete fast_line;
   1.230 +  return true;
   1.231 +}
   1.232 +
   1.233 +bool ModuleComparer::ComparePubSymbol(const BasicPubSymbol* basic_ps,
   1.234 +                                     const FastPubSymbol* fastps_raw) const {
   1.235 +  FastPubSymbol *fast_ps = new FastPubSymbol;
   1.236 +  fast_ps->CopyFrom(fastps_raw);
   1.237 +  ASSERT_TRUE(basic_ps->name == fast_ps->name);
   1.238 +  ASSERT_TRUE(basic_ps->address == fast_ps->address);
   1.239 +  ASSERT_TRUE(basic_ps->parameter_size == fast_ps->parameter_size);
   1.240 +  delete fast_ps;
   1.241 +  return true;
   1.242 +}
   1.243 +
   1.244 +bool ModuleComparer::CompareWFI(const WindowsFrameInfo& wfi1,
   1.245 +                               const WindowsFrameInfo& wfi2) const {
   1.246 +  ASSERT_TRUE(wfi1.type_ == wfi2.type_);
   1.247 +  ASSERT_TRUE(wfi1.valid == wfi2.valid);
   1.248 +  ASSERT_TRUE(wfi1.prolog_size == wfi2.prolog_size);
   1.249 +  ASSERT_TRUE(wfi1.epilog_size == wfi2.epilog_size);
   1.250 +  ASSERT_TRUE(wfi1.parameter_size == wfi2.parameter_size);
   1.251 +  ASSERT_TRUE(wfi1.saved_register_size == wfi2.saved_register_size);
   1.252 +  ASSERT_TRUE(wfi1.local_size == wfi2.local_size);
   1.253 +  ASSERT_TRUE(wfi1.max_stack_size == wfi2.max_stack_size);
   1.254 +  ASSERT_TRUE(wfi1.allocates_base_pointer == wfi2.allocates_base_pointer);
   1.255 +  ASSERT_TRUE(wfi1.program_string == wfi2.program_string);
   1.256 +  return true;
   1.257 +}
   1.258 +
   1.259 +// Compare ContainedRangeMap
   1.260 +bool ModuleComparer::CompareCRM(
   1.261 +    const ContainedRangeMap<MemAddr, linked_ptr<WFI> >* basic_crm,
   1.262 +    const StaticContainedRangeMap<MemAddr, char>* fast_crm) const {
   1.263 +  ASSERT_TRUE(basic_crm->base_ == fast_crm->base_);
   1.264 +
   1.265 +  if (!basic_crm->entry_.get() || !fast_crm->entry_ptr_) {
   1.266 +    // empty entry:
   1.267 +    ASSERT_TRUE(!basic_crm->entry_.get() && !fast_crm->entry_ptr_);
   1.268 +  } else {
   1.269 +    WFI newwfi;
   1.270 +    newwfi.CopyFrom(fast_resolver_->CopyWFI(fast_crm->entry_ptr_));
   1.271 +    ASSERT_TRUE(CompareWFI(*(basic_crm->entry_.get()), newwfi));
   1.272 +  }
   1.273 +
   1.274 +  if ((!basic_crm->map_ || basic_crm->map_->empty())
   1.275 +      || fast_crm->map_.empty()) {
   1.276 +    ASSERT_TRUE((!basic_crm->map_ || basic_crm->map_->empty())
   1.277 +               && fast_crm->map_.empty());
   1.278 +  } else {
   1.279 +    ContainedRangeMap<MemAddr, linked_ptr<WFI> >::MapConstIterator iter1;
   1.280 +    StaticContainedRangeMap<MemAddr, char>::MapConstIterator iter2;
   1.281 +    iter1 = basic_crm->map_->begin();
   1.282 +    iter2 = fast_crm->map_.begin();
   1.283 +    while (iter1 != basic_crm->map_->end()
   1.284 +        && iter2 != fast_crm->map_.end()) {
   1.285 +      ASSERT_TRUE(iter1->first == iter2.GetKey());
   1.286 +      StaticContainedRangeMap<MemAddr, char> *child =
   1.287 +          new StaticContainedRangeMap<MemAddr, char>(
   1.288 +              reinterpret_cast<const char*>(iter2.GetValuePtr()));
   1.289 +      ASSERT_TRUE(CompareCRM(iter1->second, child));
   1.290 +      delete child;
   1.291 +      ++iter1;
   1.292 +      ++iter2;
   1.293 +    }
   1.294 +    ASSERT_TRUE(iter1 == basic_crm->map_->end());
   1.295 +    ASSERT_TRUE(iter2 == fast_crm->map_.end());
   1.296 +  }
   1.297 +
   1.298 +  return true;
   1.299 +}
   1.300 +
   1.301 +}  // namespace google_breakpad

mercurial