toolkit/crashreporter/breakpad-patches/00-module-api-extras.patch

Sat, 03 Jan 2015 20:18:00 +0100

author
Michael Schloh von Bennewitz <michael@schloh.com>
date
Sat, 03 Jan 2015 20:18:00 +0100
branch
TOR_BUG_3246
changeset 7
129ffea94266
permissions
-rw-r--r--

Conditionally enable double key logic according to:
private browsing mode or privacy.thirdparty.isolate preference and
implement in GetCookieStringCommon and FindCookie where it counts...
With some reservations of how to convince FindCookie users to test
condition and pass a nullptr when disabling double key logic.

     1 # HG changeset patch
     2 # User Ted Mielczarek <ted@mielczarek.org>
     3 # Date 1352220493 18000
     4 # Node ID c3b1109dd392c16a9fe4e85da693010966dbbf0b
     5 # Parent  03db269a2868503cca9e80f62ce676aabbf967fd
     6 Add APIs for querying Module data
     7 R=glandium at https://breakpad.appspot.com/511003/
     9 diff --git a/src/common/module.cc b/src/common/module.cc
    10 --- a/src/common/module.cc
    11 +++ b/src/common/module.cc
    12 @@ -58,17 +58,17 @@
    14  Module::~Module() {
    15    for (FileByNameMap::iterator it = files_.begin(); it != files_.end(); ++it)
    16      delete it->second;
    17    for (FunctionSet::iterator it = functions_.begin();
    18         it != functions_.end(); ++it) {
    19      delete *it;
    20    }
    21 -  for (vector<StackFrameEntry *>::iterator it = stack_frame_entries_.begin();
    22 +  for (StackFrameEntrySet::iterator it = stack_frame_entries_.begin();
    23         it != stack_frame_entries_.end(); ++it) {
    24      delete *it;
    25    }
    26    for (ExternSet::iterator it = externs_.begin(); it != externs_.end(); ++it)
    27      delete *it;
    28  }
    30  void Module::SetLoadAddress(Address address) {
    31 @@ -88,39 +88,84 @@
    32  }
    34  void Module::AddFunctions(vector<Function *>::iterator begin,
    35                            vector<Function *>::iterator end) {
    36    for (vector<Function *>::iterator it = begin; it != end; ++it)
    37      AddFunction(*it);
    38  }
    40 -void Module::AddStackFrameEntry(StackFrameEntry *stack_frame_entry) {
    41 -  stack_frame_entries_.push_back(stack_frame_entry);
    42 +void Module::AddStackFrameEntry(StackFrameEntry* stack_frame_entry) {
    43 +  std::pair<StackFrameEntrySet::iterator,bool> ret =
    44 +      stack_frame_entries_.insert(stack_frame_entry);
    45 +  if (!ret.second) {
    46 +    // Free the duplicate that was not inserted because this Module
    47 +    // now owns it.
    48 +    delete stack_frame_entry;
    49 +  }
    50  }
    52  void Module::AddExtern(Extern *ext) {
    53    std::pair<ExternSet::iterator,bool> ret = externs_.insert(ext);
    54    if (!ret.second) {
    55      // Free the duplicate that was not inserted because this Module
    56      // now owns it.
    57      delete ext;
    58    }
    59  }
    61  void Module::GetFunctions(vector<Function *> *vec,
    62                            vector<Function *>::iterator i) {
    63    vec->insert(i, functions_.begin(), functions_.end());
    64  }
    66 +template<typename T>
    67 +bool EntryContainsAddress(T entry, Module::Address address) {
    68 +  return entry->address <= address && address < entry->address + entry->size;
    69 +}
    70 +
    71 +Module::Function* Module::FindFunctionByAddress(Address address) {
    72 +  Function search;
    73 +  search.address = address;
    74 +  // Ensure that name always sorts higher than the function name,
    75 +  // so that upper_bound always returns the function just after
    76 +  // the function containing this address.
    77 +  search.name = "\xFF";
    78 +  FunctionSet::iterator it = functions_.upper_bound(&search);
    79 +  if (it == functions_.begin())
    80 +    return NULL;
    81 +
    82 +  it--;
    83 +
    84 +  if (EntryContainsAddress(*it, address))
    85 +    return *it;
    86 +
    87 +  return NULL;
    88 +}
    89 +
    90  void Module::GetExterns(vector<Extern *> *vec,
    91                          vector<Extern *>::iterator i) {
    92    vec->insert(i, externs_.begin(), externs_.end());
    93  }
    95 +Module::Extern* Module::FindExternByAddress(Address address) {
    96 +  Extern search;
    97 +  search.address = address;
    98 +  ExternSet::iterator it = externs_.upper_bound(&search);
    99 +
   100 +  if (it == externs_.begin())
   101 +    return NULL;
   102 +
   103 +  it--;
   104 +  if ((*it)->address > address)
   105 +    return NULL;
   106 +
   107 +  return *it;
   108 +}
   109 +
   110  Module::File *Module::FindFile(const string &name) {
   111    // A tricky bit here.  The key of each map entry needs to be a
   112    // pointer to the entry's File's name string.  This means that we
   113    // can't do the initial lookup with any operation that would create
   114    // an empty entry for us if the name isn't found (like, say,
   115    // operator[] or insert do), because such a created entry's key will
   116    // be a pointer the string passed as our argument.  Since the key of
   117    // a map's value type is const, we can't fix it up once we've
   118 @@ -150,18 +195,35 @@
   119  }
   121  void Module::GetFiles(vector<File *> *vec) {
   122    vec->clear();
   123    for (FileByNameMap::iterator it = files_.begin(); it != files_.end(); ++it)
   124      vec->push_back(it->second);
   125  }
   127 -void Module::GetStackFrameEntries(vector<StackFrameEntry *> *vec) {
   128 -  *vec = stack_frame_entries_;
   129 +void Module::GetStackFrameEntries(vector<StackFrameEntry *>* vec) {
   130 +  vec->clear();
   131 +  vec->insert(vec->begin(), stack_frame_entries_.begin(),
   132 +              stack_frame_entries_.end());
   133 +}
   134 +
   135 +Module::StackFrameEntry* Module::FindStackFrameEntryByAddress(Address address) {
   136 +  StackFrameEntry search;
   137 +  search.address = address;
   138 +  StackFrameEntrySet::iterator it = stack_frame_entries_.upper_bound(&search);
   139 +
   140 +  if (it == stack_frame_entries_.begin())
   141 +    return NULL;
   142 +
   143 +  it--;
   144 +  if (EntryContainsAddress(*it, address))
   145 +    return *it;
   146 +
   147 +  return NULL;
   148  }
   150  void Module::AssignSourceIds() {
   151    // First, give every source file an id of -1.
   152    for (FileByNameMap::iterator file_it = files_.begin();
   153         file_it != files_.end(); ++file_it) {
   154      file_it->second->source_id = -1;
   155    }
   156 @@ -256,17 +318,17 @@
   157        stream << "PUBLIC " << hex
   158               << (ext->address - load_address_) << " 0 "
   159               << ext->name << dec << endl;
   160      }
   161    }
   163    if (symbol_data != NO_CFI) {
   164      // Write out 'STACK CFI INIT' and 'STACK CFI' records.
   165 -    vector<StackFrameEntry *>::const_iterator frame_it;
   166 +    StackFrameEntrySet::const_iterator frame_it;
   167      for (frame_it = stack_frame_entries_.begin();
   168           frame_it != stack_frame_entries_.end(); ++frame_it) {
   169        StackFrameEntry *entry = *frame_it;
   170        stream << "STACK CFI INIT " << hex
   171               << (entry->address - load_address_) << " "
   172               << entry->size << " " << dec;
   173        if (!stream.good()
   174            || !WriteRuleMap(entry->initial_rules, stream))
   175 diff --git a/src/common/module.h b/src/common/module.h
   176 --- a/src/common/module.h
   177 +++ b/src/common/module.h
   178 @@ -164,16 +164,23 @@
   180    struct ExternCompare {
   181      bool operator() (const Extern *lhs,
   182                       const Extern *rhs) const {
   183        return lhs->address < rhs->address;
   184      }
   185    };
   187 +  struct StackFrameEntryCompare {
   188 +    bool operator() (const StackFrameEntry* lhs,
   189 +                     const StackFrameEntry* rhs) const {
   190 +      return lhs->address < rhs->address;
   191 +    }
   192 +  };
   193 +
   194    // Create a new module with the given name, operating system,
   195    // architecture, and ID string.
   196    Module(const string &name, const string &os, const string &architecture,
   197           const string &id);
   198    ~Module();
   200    // Set the module's load address to LOAD_ADDRESS; addresses given
   201    // for functions and lines will be written to the Breakpad symbol
   202 @@ -223,37 +230,49 @@
   204    // Insert pointers to the functions added to this module at I in
   205    // VEC. The pointed-to Functions are still owned by this module.
   206    // (Since this is effectively a copy of the function list, this is
   207    // mostly useful for testing; other uses should probably get a more
   208    // appropriate interface.)
   209    void GetFunctions(vector<Function *> *vec, vector<Function *>::iterator i);
   211 +  // If this module has a function at ADDRESS, return a pointer to it.
   212 +  // Otherwise, return NULL.
   213 +  Function* FindFunctionByAddress(Address address);
   214 +
   215    // Insert pointers to the externs added to this module at I in
   216    // VEC. The pointed-to Externs are still owned by this module.
   217    // (Since this is effectively a copy of the extern list, this is
   218    // mostly useful for testing; other uses should probably get a more
   219    // appropriate interface.)
   220    void GetExterns(vector<Extern *> *vec, vector<Extern *>::iterator i);
   222 +  // If this module has an extern whose base address is less than ADDRESS,
   223 +  // return a pointer to it. Otherwise, return NULL.
   224 +  Extern* FindExternByAddress(Address address);
   225 +
   226    // Clear VEC and fill it with pointers to the Files added to this
   227    // module, sorted by name. The pointed-to Files are still owned by
   228    // this module. (Since this is effectively a copy of the file list,
   229    // this is mostly useful for testing; other uses should probably get
   230    // a more appropriate interface.)
   231    void GetFiles(vector<File *> *vec);
   233    // Clear VEC and fill it with pointers to the StackFrameEntry
   234    // objects that have been added to this module. (Since this is
   235    // effectively a copy of the stack frame entry list, this is mostly
   236    // useful for testing; other uses should probably get
   237    // a more appropriate interface.)
   238    void GetStackFrameEntries(vector<StackFrameEntry *> *vec);
   240 +  // If this module has a StackFrameEntry whose address range covers
   241 +  // ADDRESS, return it. Otherwise return NULL.
   242 +  StackFrameEntry* FindStackFrameEntryByAddress(Address address);
   243 +
   244    // Find those files in this module that are actually referred to by
   245    // functions' line number data, and assign them source id numbers.
   246    // Set the source id numbers for all other files --- unused by the
   247    // source line data --- to -1.  We do this before writing out the
   248    // symbol file, at which point we omit any unused files.
   249    void AssignSourceIds();
   251    // Call AssignSourceIds, and write this module to STREAM in the
   252 @@ -299,25 +318,28 @@
   253    typedef map<const string *, File *, CompareStringPtrs> FileByNameMap;
   255    // A set containing Function structures, sorted by address.
   256    typedef set<Function *, FunctionCompare> FunctionSet;
   258    // A set containing Extern structures, sorted by address.
   259    typedef set<Extern *, ExternCompare> ExternSet;
   261 +  // A set containing StackFrameEntry structures, sorted by address.
   262 +  typedef set<StackFrameEntry*, StackFrameEntryCompare> StackFrameEntrySet;
   263 +
   264    // The module owns all the files and functions that have been added
   265    // to it; destroying the module frees the Files and Functions these
   266    // point to.
   267    FileByNameMap files_;    // This module's source files.
   268    FunctionSet functions_;  // This module's functions.
   270    // The module owns all the call frame info entries that have been
   271    // added to it.
   272 -  vector<StackFrameEntry *> stack_frame_entries_;
   273 +  StackFrameEntrySet stack_frame_entries_;
   275    // The module owns all the externs that have been added to it;
   276    // destroying the module frees the Externs these point to.
   277    ExternSet externs_;
   278  };
   280  }  // namespace google_breakpad
   282 diff --git a/src/common/module_unittest.cc b/src/common/module_unittest.cc
   283 --- a/src/common/module_unittest.cc
   284 +++ b/src/common/module_unittest.cc
   285 @@ -329,63 +329,63 @@
   286    entry3->rule_changes[0x36682fad3763ffffULL][".cfa"] =
   287      "I think I know";
   288    m.AddStackFrameEntry(entry3);
   290    // Check that Write writes STACK CFI records properly.
   291    m.Write(s, ALL_SYMBOL_DATA);
   292    string contents = s.str();
   293    EXPECT_STREQ("MODULE os-name architecture id-string name with spaces\n"
   294 -               "STACK CFI INIT ddb5f41285aa7757 1486493370dc5073 \n"
   295 -               "STACK CFI INIT 8064f3af5e067e38 de2a5ee55509407"
   296 -               " .cfa: I think that I shall never see"
   297 -               " cannoli: a tree whose hungry mouth is prest"
   298 -               " stromboli: a poem lovely as a tree\n"
   299                 "STACK CFI INIT 5e8d0db0a7075c6c 1c7edb12a7aea229"
   300                 " .cfa: Whose woods are these\n"
   301                 "STACK CFI 36682fad3763ffff"
   302                 " .cfa: I think I know"
   303                 " stromboli: his house is in\n"
   304                 "STACK CFI 47ceb0f63c269d7f"
   305                 " calzone: the village though"
   306 -               " cannoli: he will not see me stopping here\n",
   307 +               " cannoli: he will not see me stopping here\n"
   308 +               "STACK CFI INIT 8064f3af5e067e38 de2a5ee55509407"
   309 +               " .cfa: I think that I shall never see"
   310 +               " cannoli: a tree whose hungry mouth is prest"
   311 +               " stromboli: a poem lovely as a tree\n"
   312 +               "STACK CFI INIT ddb5f41285aa7757 1486493370dc5073 \n",
   313                 contents.c_str());
   315    // Check that GetStackFrameEntries works.
   316    vector<Module::StackFrameEntry *> entries;
   317    m.GetStackFrameEntries(&entries);
   318    ASSERT_EQ(3U, entries.size());
   319    // Check first entry.
   320 -  EXPECT_EQ(0xddb5f41285aa7757ULL, entries[0]->address);
   321 -  EXPECT_EQ(0x1486493370dc5073ULL, entries[0]->size);
   322 -  ASSERT_EQ(0U, entries[0]->initial_rules.size());
   323 -  ASSERT_EQ(0U, entries[0]->rule_changes.size());
   324 +  EXPECT_EQ(0x5e8d0db0a7075c6cULL, entries[0]->address);
   325 +  EXPECT_EQ(0x1c7edb12a7aea229ULL, entries[0]->size);
   326 +  Module::RuleMap entry1_initial;
   327 +  entry1_initial[".cfa"] = "Whose woods are these";
   328 +  EXPECT_THAT(entries[0]->initial_rules, ContainerEq(entry1_initial));
   329 +  Module::RuleChangeMap entry1_changes;
   330 +  entry1_changes[0x36682fad3763ffffULL][".cfa"] = "I think I know";
   331 +  entry1_changes[0x36682fad3763ffffULL]["stromboli"] = "his house is in";
   332 +  entry1_changes[0x47ceb0f63c269d7fULL]["calzone"] = "the village though";
   333 +  entry1_changes[0x47ceb0f63c269d7fULL]["cannoli"] =
   334 +    "he will not see me stopping here";
   335 +  EXPECT_THAT(entries[0]->rule_changes, ContainerEq(entry1_changes));
   336    // Check second entry.
   337    EXPECT_EQ(0x8064f3af5e067e38ULL, entries[1]->address);
   338    EXPECT_EQ(0x0de2a5ee55509407ULL, entries[1]->size);
   339    ASSERT_EQ(3U, entries[1]->initial_rules.size());
   340    Module::RuleMap entry2_initial;
   341    entry2_initial[".cfa"] = "I think that I shall never see";
   342    entry2_initial["stromboli"] = "a poem lovely as a tree";
   343    entry2_initial["cannoli"] = "a tree whose hungry mouth is prest";
   344    EXPECT_THAT(entries[1]->initial_rules, ContainerEq(entry2_initial));
   345    ASSERT_EQ(0U, entries[1]->rule_changes.size());
   346    // Check third entry.
   347 -  EXPECT_EQ(0x5e8d0db0a7075c6cULL, entries[2]->address);
   348 -  EXPECT_EQ(0x1c7edb12a7aea229ULL, entries[2]->size);
   349 -  Module::RuleMap entry3_initial;
   350 -  entry3_initial[".cfa"] = "Whose woods are these";
   351 -  EXPECT_THAT(entries[2]->initial_rules, ContainerEq(entry3_initial));
   352 -  Module::RuleChangeMap entry3_changes;
   353 -  entry3_changes[0x36682fad3763ffffULL][".cfa"] = "I think I know";
   354 -  entry3_changes[0x36682fad3763ffffULL]["stromboli"] = "his house is in";
   355 -  entry3_changes[0x47ceb0f63c269d7fULL]["calzone"] = "the village though";
   356 -  entry3_changes[0x47ceb0f63c269d7fULL]["cannoli"] =
   357 -    "he will not see me stopping here";
   358 -  EXPECT_THAT(entries[2]->rule_changes, ContainerEq(entry3_changes));
   359 +  EXPECT_EQ(0xddb5f41285aa7757ULL, entries[2]->address);
   360 +  EXPECT_EQ(0x1486493370dc5073ULL, entries[2]->size);
   361 +  ASSERT_EQ(0U, entries[2]->initial_rules.size());
   362 +  ASSERT_EQ(0U, entries[2]->rule_changes.size());
   363  }
   365  TEST(Construct, UniqueFiles) {
   366    Module m(MODULE_NAME, MODULE_OS, MODULE_ARCH, MODULE_ID);
   367    Module::File *file1 = m.FindFile("foo");
   368    Module::File *file2 = m.FindFile(string("bar"));
   369    Module::File *file3 = m.FindFile(string("foo"));
   370    Module::File *file4 = m.FindFile("bar");
   371 @@ -483,8 +483,155 @@
   372    m.Write(s, ALL_SYMBOL_DATA);
   373    string contents = s.str();
   375    EXPECT_STREQ("MODULE " MODULE_OS " " MODULE_ARCH " "
   376                 MODULE_ID " " MODULE_NAME "\n"
   377                 "PUBLIC ffff 0 _xyz\n",
   378                 contents.c_str());
   379  }
   380 +
   381 +TEST(Lookup, Function) {
   382 +  Module m(MODULE_NAME, MODULE_OS, MODULE_ARCH, MODULE_ID);
   383 +
   384 +  Module::Function *function1 = new(Module::Function);
   385 +  function1->name = "_abc1";
   386 +  function1->address = 0x1000;
   387 +  function1->size = 0x900;
   388 +  function1->parameter_size = 0x0;
   389 +
   390 +  Module::Function *function2 = new(Module::Function);
   391 +  function2->name = "_xyz2";
   392 +  function2->address = 0x2000;
   393 +  function2->size = 0x900;
   394 +  function2->parameter_size = 0x0;
   395 +
   396 +  Module::Function *function3 = new(Module::Function);
   397 +  function3->name = "_def3";
   398 +  function3->address = 0x3000;
   399 +  function3->size = 0x900;
   400 +  function3->parameter_size = 0x0;
   401 +
   402 +  // Put them in a vector.
   403 +  vector<Module::Function *> vec;
   404 +  vec.push_back(function1);
   405 +  vec.push_back(function2);
   406 +  vec.push_back(function3);
   407 +
   408 +  m.AddFunctions(vec.begin(), vec.end());
   409 +
   410 +  // Try looking up functions by address.
   411 +  Module::Function* f = m.FindFunctionByAddress(0x1000);
   412 +  EXPECT_EQ(function1, f);
   413 +  f = m.FindFunctionByAddress(0x18FF);
   414 +  EXPECT_EQ(function1, f);
   415 +
   416 +  f = m.FindFunctionByAddress(0x1900);
   417 +  EXPECT_EQ((Module::Function*)NULL, f);
   418 +  f = m.FindFunctionByAddress(0x1A00);
   419 +  EXPECT_EQ((Module::Function*)NULL, f);
   420 +
   421 +  f = m.FindFunctionByAddress(0x2000);
   422 +  EXPECT_EQ(function2, f);
   423 +  f = m.FindFunctionByAddress(0x28FF);
   424 +  EXPECT_EQ(function2, f);
   425 +
   426 +  f = m.FindFunctionByAddress(0x3000);
   427 +  EXPECT_EQ(function3, f);
   428 +  f = m.FindFunctionByAddress(0x38FF);
   429 +  EXPECT_EQ(function3, f);
   430 +
   431 +  f = m.FindFunctionByAddress(0x3900);
   432 +  EXPECT_EQ((Module::Function*)NULL, f);
   433 +  f = m.FindFunctionByAddress(0x3A00);
   434 +  EXPECT_EQ((Module::Function*)NULL, f);
   435 +}
   436 +
   437 +TEST(Lookup, Externs) {
   438 +  Module m(MODULE_NAME, MODULE_OS, MODULE_ARCH, MODULE_ID);
   439 +
   440 +  // Two externs.
   441 +  Module::Extern* extern1 = new(Module::Extern);
   442 +  extern1->address = 0x1000;
   443 +  extern1->name = "_abc";
   444 +  Module::Extern* extern2 = new(Module::Extern);
   445 +  extern2->address = 0x2000;
   446 +  extern2->name = "_xyz";
   447 +
   448 +  m.AddExtern(extern1);
   449 +  m.AddExtern(extern2);
   450 +
   451 +  Module::Extern* e = m.FindExternByAddress(0xFFF);
   452 +  EXPECT_EQ((Module::Extern*)NULL, e);
   453 +
   454 +  e = m.FindExternByAddress(0x1000);
   455 +  EXPECT_EQ(extern1, e);
   456 +  e = m.FindExternByAddress(0x1900);
   457 +  EXPECT_EQ(extern1, e);
   458 +  e = m.FindExternByAddress(0x1FFF);
   459 +  EXPECT_EQ(extern1, e);
   460 +
   461 +  e = m.FindExternByAddress(0x2000);
   462 +  EXPECT_EQ(extern2, e);
   463 +  e = m.FindExternByAddress(0x2900);
   464 +  EXPECT_EQ(extern2, e);
   465 +  e = m.FindExternByAddress(0xFFFFFFFF);
   466 +  EXPECT_EQ(extern2, e);
   467 +}
   468 +
   469 +TEST(Lookup, StackFrameEntries) {
   470 +  Module m(MODULE_NAME, MODULE_OS, MODULE_ARCH, MODULE_ID);
   471 +
   472 +  // First STACK CFI entry, with no initial rules or deltas.
   473 +  Module::StackFrameEntry *entry1 = new Module::StackFrameEntry();
   474 +  entry1->address = 0x2000;
   475 +  entry1->size = 0x900;
   476 +  m.AddStackFrameEntry(entry1);
   477 +
   478 +  // Second STACK CFI entry, with initial rules but no deltas.
   479 +  Module::StackFrameEntry *entry2 = new Module::StackFrameEntry();
   480 +  entry2->address = 0x3000;
   481 +  entry2->size = 0x900;
   482 +  entry2->initial_rules[".cfa"] = "I think that I shall never see";
   483 +  entry2->initial_rules["stromboli"] = "a poem lovely as a tree";
   484 +  entry2->initial_rules["cannoli"] = "a tree whose hungry mouth is prest";
   485 +  m.AddStackFrameEntry(entry2);
   486 +
   487 +  // Third STACK CFI entry, with initial rules and deltas.
   488 +  Module::StackFrameEntry *entry3 = new Module::StackFrameEntry();
   489 +  entry3->address = 0x1000;
   490 +  entry3->size = 0x900;
   491 +  entry3->initial_rules[".cfa"] = "Whose woods are these";
   492 +  entry3->rule_changes[0x47ceb0f63c269d7fULL]["calzone"] =
   493 +    "the village though";
   494 +  entry3->rule_changes[0x47ceb0f63c269d7fULL]["cannoli"] =
   495 +    "he will not see me stopping here";
   496 +  entry3->rule_changes[0x36682fad3763ffffULL]["stromboli"] =
   497 +    "his house is in";
   498 +  entry3->rule_changes[0x36682fad3763ffffULL][".cfa"] =
   499 +    "I think I know";
   500 +  m.AddStackFrameEntry(entry3);
   501 +
   502 +  Module::StackFrameEntry* s = m.FindStackFrameEntryByAddress(0x1000);
   503 +  EXPECT_EQ(entry3, s);
   504 +  s = m.FindStackFrameEntryByAddress(0x18FF);
   505 +  EXPECT_EQ(entry3, s);
   506 +
   507 +  s = m.FindStackFrameEntryByAddress(0x1900);
   508 +  EXPECT_EQ((Module::StackFrameEntry*)NULL, s);
   509 +  s = m.FindStackFrameEntryByAddress(0x1A00);
   510 +  EXPECT_EQ((Module::StackFrameEntry*)NULL, s);
   511 +
   512 +  s = m.FindStackFrameEntryByAddress(0x2000);
   513 +  EXPECT_EQ(entry1, s);
   514 +  s = m.FindStackFrameEntryByAddress(0x28FF);
   515 +  EXPECT_EQ(entry1, s);
   516 +
   517 +  s = m.FindStackFrameEntryByAddress(0x3000);
   518 +  EXPECT_EQ(entry2, s);
   519 +  s = m.FindStackFrameEntryByAddress(0x38FF);
   520 +  EXPECT_EQ(entry2, s);
   521 +
   522 +  s = m.FindStackFrameEntryByAddress(0x3900);
   523 +  EXPECT_EQ((Module::StackFrameEntry*)NULL, s);
   524 +  s = m.FindStackFrameEntryByAddress(0x3A00);
   525 +  EXPECT_EQ((Module::StackFrameEntry*)NULL, s);
   526 +}

mercurial