xref: /aosp_15_r20/external/google-breakpad/src/processor/module_comparer.cc (revision 9712c20fc9bbfbac4935993a2ca0b3958c5adad2)
1*9712c20fSFrederick Mayle // Copyright 2010 Google LLC
2*9712c20fSFrederick Mayle //
3*9712c20fSFrederick Mayle // Redistribution and use in source and binary forms, with or without
4*9712c20fSFrederick Mayle // modification, are permitted provided that the following conditions are
5*9712c20fSFrederick Mayle // met:
6*9712c20fSFrederick Mayle //
7*9712c20fSFrederick Mayle //     * Redistributions of source code must retain the above copyright
8*9712c20fSFrederick Mayle // notice, this list of conditions and the following disclaimer.
9*9712c20fSFrederick Mayle //     * Redistributions in binary form must reproduce the above
10*9712c20fSFrederick Mayle // copyright notice, this list of conditions and the following disclaimer
11*9712c20fSFrederick Mayle // in the documentation and/or other materials provided with the
12*9712c20fSFrederick Mayle // distribution.
13*9712c20fSFrederick Mayle //     * Neither the name of Google LLC nor the names of its
14*9712c20fSFrederick Mayle // contributors may be used to endorse or promote products derived from
15*9712c20fSFrederick Mayle // this software without specific prior written permission.
16*9712c20fSFrederick Mayle //
17*9712c20fSFrederick Mayle // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
18*9712c20fSFrederick Mayle // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
19*9712c20fSFrederick Mayle // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
20*9712c20fSFrederick Mayle // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
21*9712c20fSFrederick Mayle // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
22*9712c20fSFrederick Mayle // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
23*9712c20fSFrederick Mayle // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
24*9712c20fSFrederick Mayle // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
25*9712c20fSFrederick Mayle // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
26*9712c20fSFrederick Mayle // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
27*9712c20fSFrederick Mayle // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
28*9712c20fSFrederick Mayle //
29*9712c20fSFrederick Mayle // module_comparer.cc: ModuleComparer implementation.
30*9712c20fSFrederick Mayle // See module_comparer.h for documentation.
31*9712c20fSFrederick Mayle //
32*9712c20fSFrederick Mayle // Author: [email protected] (Siyang Xie)
33*9712c20fSFrederick Mayle 
34*9712c20fSFrederick Mayle #ifdef HAVE_CONFIG_H
35*9712c20fSFrederick Mayle #include <config.h>  // Must come first
36*9712c20fSFrederick Mayle #endif
37*9712c20fSFrederick Mayle 
38*9712c20fSFrederick Mayle #include "processor/module_comparer.h"
39*9712c20fSFrederick Mayle 
40*9712c20fSFrederick Mayle #include <map>
41*9712c20fSFrederick Mayle #include <string>
42*9712c20fSFrederick Mayle 
43*9712c20fSFrederick Mayle #include "common/scoped_ptr.h"
44*9712c20fSFrederick Mayle #include "processor/basic_code_module.h"
45*9712c20fSFrederick Mayle #include "processor/logging.h"
46*9712c20fSFrederick Mayle 
47*9712c20fSFrederick Mayle #define ASSERT_TRUE(condition) \
48*9712c20fSFrederick Mayle   if (!(condition)) { \
49*9712c20fSFrederick Mayle     BPLOG(ERROR) << "FAIL: " << #condition << " @ " \
50*9712c20fSFrederick Mayle                  << __FILE__ << ":" << __LINE__; \
51*9712c20fSFrederick Mayle     return false; \
52*9712c20fSFrederick Mayle   }
53*9712c20fSFrederick Mayle 
54*9712c20fSFrederick Mayle #define ASSERT_FALSE(condition) ASSERT_TRUE(!(condition))
55*9712c20fSFrederick Mayle 
56*9712c20fSFrederick Mayle namespace google_breakpad {
57*9712c20fSFrederick Mayle 
Compare(const string & symbol_data)58*9712c20fSFrederick Mayle bool ModuleComparer::Compare(const string& symbol_data) {
59*9712c20fSFrederick Mayle   scoped_ptr<BasicModule> basic_module(new BasicModule("test_module"));
60*9712c20fSFrederick Mayle   scoped_ptr<FastModule> fast_module(new FastModule("test_module"));
61*9712c20fSFrederick Mayle 
62*9712c20fSFrederick Mayle   // Load symbol data into basic_module
63*9712c20fSFrederick Mayle   scoped_array<char> buffer(new char[symbol_data.size() + 1]);
64*9712c20fSFrederick Mayle   memcpy(buffer.get(), symbol_data.c_str(), symbol_data.size());
65*9712c20fSFrederick Mayle   buffer.get()[symbol_data.size()] = '\0';
66*9712c20fSFrederick Mayle   ASSERT_TRUE(basic_module->LoadMapFromMemory(buffer.get(),
67*9712c20fSFrederick Mayle                                               symbol_data.size() + 1));
68*9712c20fSFrederick Mayle   buffer.reset();
69*9712c20fSFrederick Mayle 
70*9712c20fSFrederick Mayle   // Serialize BasicSourceLineResolver::Module.
71*9712c20fSFrederick Mayle   size_t serialized_size = 0;
72*9712c20fSFrederick Mayle   scoped_array<char> serialized_data(
73*9712c20fSFrederick Mayle       serializer_.Serialize(*(basic_module.get()), &serialized_size));
74*9712c20fSFrederick Mayle   ASSERT_TRUE(serialized_data.get());
75*9712c20fSFrederick Mayle   BPLOG(INFO) << "Serialized size = " << serialized_size << " Bytes";
76*9712c20fSFrederick Mayle 
77*9712c20fSFrederick Mayle   // Load FastSourceLineResolver::Module using serialized data.
78*9712c20fSFrederick Mayle   ASSERT_TRUE(fast_module->LoadMapFromMemory(serialized_data.get(),
79*9712c20fSFrederick Mayle                                              serialized_size));
80*9712c20fSFrederick Mayle   ASSERT_TRUE(fast_module->IsCorrupt() == basic_module->IsCorrupt());
81*9712c20fSFrederick Mayle 
82*9712c20fSFrederick Mayle   // Compare FastSourceLineResolver::Module with
83*9712c20fSFrederick Mayle   // BasicSourceLineResolver::Module.
84*9712c20fSFrederick Mayle   ASSERT_TRUE(CompareModule(basic_module.get(), fast_module.get()));
85*9712c20fSFrederick Mayle 
86*9712c20fSFrederick Mayle   return true;
87*9712c20fSFrederick Mayle }
88*9712c20fSFrederick Mayle 
89*9712c20fSFrederick Mayle // Traversal the content of module and do comparison
CompareModule(const BasicModule * basic_module,const FastModule * fast_module) const90*9712c20fSFrederick Mayle bool ModuleComparer::CompareModule(const BasicModule *basic_module,
91*9712c20fSFrederick Mayle                                   const FastModule *fast_module) const {
92*9712c20fSFrederick Mayle   // Compare name_.
93*9712c20fSFrederick Mayle   ASSERT_TRUE(basic_module->name_ == fast_module->name_);
94*9712c20fSFrederick Mayle 
95*9712c20fSFrederick Mayle   // Compare files_:
96*9712c20fSFrederick Mayle   {
97*9712c20fSFrederick Mayle     BasicModule::FileMap::const_iterator iter1 = basic_module->files_.begin();
98*9712c20fSFrederick Mayle     FastModule::FileMap::iterator iter2 = fast_module->files_.begin();
99*9712c20fSFrederick Mayle     while (iter1 != basic_module->files_.end()
100*9712c20fSFrederick Mayle         && iter2 != fast_module->files_.end()) {
101*9712c20fSFrederick Mayle       ASSERT_TRUE(iter1->first == iter2.GetKey());
102*9712c20fSFrederick Mayle       string tmp(iter2.GetValuePtr());
103*9712c20fSFrederick Mayle       ASSERT_TRUE(iter1->second == tmp);
104*9712c20fSFrederick Mayle       ++iter1;
105*9712c20fSFrederick Mayle       ++iter2;
106*9712c20fSFrederick Mayle     }
107*9712c20fSFrederick Mayle     ASSERT_TRUE(iter1 == basic_module->files_.end());
108*9712c20fSFrederick Mayle     ASSERT_TRUE(iter2 == fast_module->files_.end());
109*9712c20fSFrederick Mayle   }
110*9712c20fSFrederick Mayle 
111*9712c20fSFrederick Mayle   // Compare functions_:
112*9712c20fSFrederick Mayle   {
113*9712c20fSFrederick Mayle     RangeMap<MemAddr, linked_ptr<BasicFunc> >::MapConstIterator iter1;
114*9712c20fSFrederick Mayle     StaticRangeMap<MemAddr, FastFunc>::MapConstIterator iter2;
115*9712c20fSFrederick Mayle     iter1 = basic_module->functions_.map_.begin();
116*9712c20fSFrederick Mayle     iter2 = fast_module->functions_.map_.begin();
117*9712c20fSFrederick Mayle     while (iter1 != basic_module->functions_.map_.end()
118*9712c20fSFrederick Mayle         && iter2 != fast_module->functions_.map_.end()) {
119*9712c20fSFrederick Mayle       ASSERT_TRUE(iter1->first == iter2.GetKey());
120*9712c20fSFrederick Mayle       ASSERT_TRUE(iter1->second.base() == iter2.GetValuePtr()->base());
121*9712c20fSFrederick Mayle       ASSERT_TRUE(CompareFunction(
122*9712c20fSFrederick Mayle           iter1->second.entry().get(), iter2.GetValuePtr()->entryptr()));
123*9712c20fSFrederick Mayle       ++iter1;
124*9712c20fSFrederick Mayle       ++iter2;
125*9712c20fSFrederick Mayle     }
126*9712c20fSFrederick Mayle     ASSERT_TRUE(iter1 == basic_module->functions_.map_.end());
127*9712c20fSFrederick Mayle     ASSERT_TRUE(iter2 == fast_module->functions_.map_.end());
128*9712c20fSFrederick Mayle   }
129*9712c20fSFrederick Mayle 
130*9712c20fSFrederick Mayle   // Compare public_symbols_:
131*9712c20fSFrederick Mayle   {
132*9712c20fSFrederick Mayle     AddressMap<MemAddr, linked_ptr<BasicPubSymbol> >::MapConstIterator iter1;
133*9712c20fSFrederick Mayle     StaticAddressMap<MemAddr, FastPubSymbol>::MapConstIterator iter2;
134*9712c20fSFrederick Mayle     iter1 = basic_module->public_symbols_.map_.begin();
135*9712c20fSFrederick Mayle     iter2 = fast_module->public_symbols_.map_.begin();
136*9712c20fSFrederick Mayle     while (iter1 != basic_module->public_symbols_.map_.end()
137*9712c20fSFrederick Mayle           && iter2 != fast_module->public_symbols_.map_.end()) {
138*9712c20fSFrederick Mayle       ASSERT_TRUE(iter1->first == iter2.GetKey());
139*9712c20fSFrederick Mayle       ASSERT_TRUE(ComparePubSymbol(
140*9712c20fSFrederick Mayle           iter1->second.get(), iter2.GetValuePtr()));
141*9712c20fSFrederick Mayle       ++iter1;
142*9712c20fSFrederick Mayle       ++iter2;
143*9712c20fSFrederick Mayle     }
144*9712c20fSFrederick Mayle     ASSERT_TRUE(iter1 == basic_module->public_symbols_.map_.end());
145*9712c20fSFrederick Mayle     ASSERT_TRUE(iter2 == fast_module->public_symbols_.map_.end());
146*9712c20fSFrederick Mayle   }
147*9712c20fSFrederick Mayle 
148*9712c20fSFrederick Mayle   // Compare windows_frame_info_[]:
149*9712c20fSFrederick Mayle   for (int i = 0; i < WindowsFrameInfo::STACK_INFO_LAST; ++i) {
150*9712c20fSFrederick Mayle     ASSERT_TRUE(CompareCRM(&(basic_module->windows_frame_info_[i]),
151*9712c20fSFrederick Mayle                            &(fast_module->windows_frame_info_[i])));
152*9712c20fSFrederick Mayle   }
153*9712c20fSFrederick Mayle 
154*9712c20fSFrederick Mayle   // Compare cfi_initial_rules_:
155*9712c20fSFrederick Mayle   {
156*9712c20fSFrederick Mayle     RangeMap<MemAddr, string>::MapConstIterator iter1;
157*9712c20fSFrederick Mayle     StaticRangeMap<MemAddr, char>::MapConstIterator iter2;
158*9712c20fSFrederick Mayle     iter1 = basic_module->cfi_initial_rules_.map_.begin();
159*9712c20fSFrederick Mayle     iter2 = fast_module->cfi_initial_rules_.map_.begin();
160*9712c20fSFrederick Mayle     while (iter1 != basic_module->cfi_initial_rules_.map_.end()
161*9712c20fSFrederick Mayle         && iter2 != fast_module->cfi_initial_rules_.map_.end()) {
162*9712c20fSFrederick Mayle       ASSERT_TRUE(iter1->first == iter2.GetKey());
163*9712c20fSFrederick Mayle       ASSERT_TRUE(iter1->second.base() == iter2.GetValuePtr()->base());
164*9712c20fSFrederick Mayle       string tmp(iter2.GetValuePtr()->entryptr());
165*9712c20fSFrederick Mayle       ASSERT_TRUE(iter1->second.entry() == tmp);
166*9712c20fSFrederick Mayle       ++iter1;
167*9712c20fSFrederick Mayle       ++iter2;
168*9712c20fSFrederick Mayle     }
169*9712c20fSFrederick Mayle     ASSERT_TRUE(iter1 == basic_module->cfi_initial_rules_.map_.end());
170*9712c20fSFrederick Mayle     ASSERT_TRUE(iter2 == fast_module->cfi_initial_rules_.map_.end());
171*9712c20fSFrederick Mayle   }
172*9712c20fSFrederick Mayle 
173*9712c20fSFrederick Mayle   // Compare cfi_delta_rules_:
174*9712c20fSFrederick Mayle   {
175*9712c20fSFrederick Mayle     map<MemAddr, string>::const_iterator iter1;
176*9712c20fSFrederick Mayle     StaticMap<MemAddr, char>::iterator iter2;
177*9712c20fSFrederick Mayle     iter1 = basic_module->cfi_delta_rules_.begin();
178*9712c20fSFrederick Mayle     iter2 = fast_module->cfi_delta_rules_.begin();
179*9712c20fSFrederick Mayle     while (iter1 != basic_module->cfi_delta_rules_.end()
180*9712c20fSFrederick Mayle         && iter2 != fast_module->cfi_delta_rules_.end()) {
181*9712c20fSFrederick Mayle       ASSERT_TRUE(iter1->first == iter2.GetKey());
182*9712c20fSFrederick Mayle       string tmp(iter2.GetValuePtr());
183*9712c20fSFrederick Mayle       ASSERT_TRUE(iter1->second == tmp);
184*9712c20fSFrederick Mayle       ++iter1;
185*9712c20fSFrederick Mayle       ++iter2;
186*9712c20fSFrederick Mayle     }
187*9712c20fSFrederick Mayle     ASSERT_TRUE(iter1 == basic_module->cfi_delta_rules_.end());
188*9712c20fSFrederick Mayle     ASSERT_TRUE(iter2 == fast_module->cfi_delta_rules_.end());
189*9712c20fSFrederick Mayle   }
190*9712c20fSFrederick Mayle 
191*9712c20fSFrederick Mayle   return true;
192*9712c20fSFrederick Mayle }
193*9712c20fSFrederick Mayle 
CompareFunction(const BasicFunc * basic_func,const FastFunc * fast_func_raw) const194*9712c20fSFrederick Mayle bool ModuleComparer::CompareFunction(const BasicFunc *basic_func,
195*9712c20fSFrederick Mayle                                     const FastFunc *fast_func_raw) const {
196*9712c20fSFrederick Mayle   FastFunc* fast_func = new FastFunc();
197*9712c20fSFrederick Mayle   fast_func->CopyFrom(fast_func_raw);
198*9712c20fSFrederick Mayle   ASSERT_TRUE(basic_func->name == fast_func->name);
199*9712c20fSFrederick Mayle   ASSERT_TRUE(basic_func->address == fast_func->address);
200*9712c20fSFrederick Mayle   ASSERT_TRUE(basic_func->size == fast_func->size);
201*9712c20fSFrederick Mayle 
202*9712c20fSFrederick Mayle   // compare range map of lines:
203*9712c20fSFrederick Mayle   RangeMap<MemAddr, linked_ptr<BasicLine> >::MapConstIterator iter1;
204*9712c20fSFrederick Mayle   StaticRangeMap<MemAddr, FastLine>::MapConstIterator iter2;
205*9712c20fSFrederick Mayle   iter1 = basic_func->lines.map_.begin();
206*9712c20fSFrederick Mayle   iter2 = fast_func->lines.map_.begin();
207*9712c20fSFrederick Mayle   while (iter1 != basic_func->lines.map_.end()
208*9712c20fSFrederick Mayle       && iter2 != fast_func->lines.map_.end()) {
209*9712c20fSFrederick Mayle     ASSERT_TRUE(iter1->first == iter2.GetKey());
210*9712c20fSFrederick Mayle     ASSERT_TRUE(iter1->second.base() == iter2.GetValuePtr()->base());
211*9712c20fSFrederick Mayle     ASSERT_TRUE(CompareLine(iter1->second.entry().get(),
212*9712c20fSFrederick Mayle                             iter2.GetValuePtr()->entryptr()));
213*9712c20fSFrederick Mayle     ++iter1;
214*9712c20fSFrederick Mayle     ++iter2;
215*9712c20fSFrederick Mayle   }
216*9712c20fSFrederick Mayle   ASSERT_TRUE(iter1 == basic_func->lines.map_.end());
217*9712c20fSFrederick Mayle   ASSERT_TRUE(iter2 == fast_func->lines.map_.end());
218*9712c20fSFrederick Mayle 
219*9712c20fSFrederick Mayle   delete fast_func;
220*9712c20fSFrederick Mayle   return true;
221*9712c20fSFrederick Mayle }
222*9712c20fSFrederick Mayle 
CompareLine(const BasicLine * basic_line,const FastLine * fast_line_raw) const223*9712c20fSFrederick Mayle bool ModuleComparer::CompareLine(const BasicLine *basic_line,
224*9712c20fSFrederick Mayle                                 const FastLine *fast_line_raw) const {
225*9712c20fSFrederick Mayle   FastLine *fast_line = new FastLine;
226*9712c20fSFrederick Mayle   fast_line->CopyFrom(fast_line_raw);
227*9712c20fSFrederick Mayle 
228*9712c20fSFrederick Mayle   ASSERT_TRUE(basic_line->address == fast_line->address);
229*9712c20fSFrederick Mayle   ASSERT_TRUE(basic_line->size == fast_line->size);
230*9712c20fSFrederick Mayle   ASSERT_TRUE(basic_line->source_file_id == fast_line->source_file_id);
231*9712c20fSFrederick Mayle   ASSERT_TRUE(basic_line->line == fast_line->line);
232*9712c20fSFrederick Mayle 
233*9712c20fSFrederick Mayle   delete fast_line;
234*9712c20fSFrederick Mayle   return true;
235*9712c20fSFrederick Mayle }
236*9712c20fSFrederick Mayle 
ComparePubSymbol(const BasicPubSymbol * basic_ps,const FastPubSymbol * fastps_raw) const237*9712c20fSFrederick Mayle bool ModuleComparer::ComparePubSymbol(const BasicPubSymbol* basic_ps,
238*9712c20fSFrederick Mayle                                      const FastPubSymbol* fastps_raw) const {
239*9712c20fSFrederick Mayle   FastPubSymbol *fast_ps = new FastPubSymbol;
240*9712c20fSFrederick Mayle   fast_ps->CopyFrom(fastps_raw);
241*9712c20fSFrederick Mayle   ASSERT_TRUE(basic_ps->name == fast_ps->name);
242*9712c20fSFrederick Mayle   ASSERT_TRUE(basic_ps->address == fast_ps->address);
243*9712c20fSFrederick Mayle   ASSERT_TRUE(basic_ps->parameter_size == fast_ps->parameter_size);
244*9712c20fSFrederick Mayle   delete fast_ps;
245*9712c20fSFrederick Mayle   return true;
246*9712c20fSFrederick Mayle }
247*9712c20fSFrederick Mayle 
CompareWFI(const WindowsFrameInfo & wfi1,const WindowsFrameInfo & wfi2) const248*9712c20fSFrederick Mayle bool ModuleComparer::CompareWFI(const WindowsFrameInfo& wfi1,
249*9712c20fSFrederick Mayle                                const WindowsFrameInfo& wfi2) const {
250*9712c20fSFrederick Mayle   ASSERT_TRUE(wfi1.type_ == wfi2.type_);
251*9712c20fSFrederick Mayle   ASSERT_TRUE(wfi1.valid == wfi2.valid);
252*9712c20fSFrederick Mayle   ASSERT_TRUE(wfi1.prolog_size == wfi2.prolog_size);
253*9712c20fSFrederick Mayle   ASSERT_TRUE(wfi1.epilog_size == wfi2.epilog_size);
254*9712c20fSFrederick Mayle   ASSERT_TRUE(wfi1.parameter_size == wfi2.parameter_size);
255*9712c20fSFrederick Mayle   ASSERT_TRUE(wfi1.saved_register_size == wfi2.saved_register_size);
256*9712c20fSFrederick Mayle   ASSERT_TRUE(wfi1.local_size == wfi2.local_size);
257*9712c20fSFrederick Mayle   ASSERT_TRUE(wfi1.max_stack_size == wfi2.max_stack_size);
258*9712c20fSFrederick Mayle   ASSERT_TRUE(wfi1.allocates_base_pointer == wfi2.allocates_base_pointer);
259*9712c20fSFrederick Mayle   ASSERT_TRUE(wfi1.program_string == wfi2.program_string);
260*9712c20fSFrederick Mayle   return true;
261*9712c20fSFrederick Mayle }
262*9712c20fSFrederick Mayle 
263*9712c20fSFrederick Mayle // Compare ContainedRangeMap
CompareCRM(const ContainedRangeMap<MemAddr,linked_ptr<WFI>> * basic_crm,const StaticContainedRangeMap<MemAddr,char> * fast_crm) const264*9712c20fSFrederick Mayle bool ModuleComparer::CompareCRM(
265*9712c20fSFrederick Mayle     const ContainedRangeMap<MemAddr, linked_ptr<WFI> >* basic_crm,
266*9712c20fSFrederick Mayle     const StaticContainedRangeMap<MemAddr, char>* fast_crm) const {
267*9712c20fSFrederick Mayle   ASSERT_TRUE(basic_crm->base_ == fast_crm->base_);
268*9712c20fSFrederick Mayle 
269*9712c20fSFrederick Mayle   if (!basic_crm->entry_.get() || !fast_crm->entry_ptr_) {
270*9712c20fSFrederick Mayle     // empty entry:
271*9712c20fSFrederick Mayle     ASSERT_TRUE(!basic_crm->entry_.get() && !fast_crm->entry_ptr_);
272*9712c20fSFrederick Mayle   } else {
273*9712c20fSFrederick Mayle     WFI newwfi;
274*9712c20fSFrederick Mayle     newwfi.CopyFrom(fast_resolver_->CopyWFI(fast_crm->entry_ptr_));
275*9712c20fSFrederick Mayle     ASSERT_TRUE(CompareWFI(*(basic_crm->entry_.get()), newwfi));
276*9712c20fSFrederick Mayle   }
277*9712c20fSFrederick Mayle 
278*9712c20fSFrederick Mayle   if ((!basic_crm->map_ || basic_crm->map_->empty())
279*9712c20fSFrederick Mayle       || fast_crm->map_.empty()) {
280*9712c20fSFrederick Mayle     ASSERT_TRUE((!basic_crm->map_ || basic_crm->map_->empty())
281*9712c20fSFrederick Mayle                && fast_crm->map_.empty());
282*9712c20fSFrederick Mayle   } else {
283*9712c20fSFrederick Mayle     ContainedRangeMap<MemAddr, linked_ptr<WFI> >::MapConstIterator iter1;
284*9712c20fSFrederick Mayle     StaticContainedRangeMap<MemAddr, char>::MapConstIterator iter2;
285*9712c20fSFrederick Mayle     iter1 = basic_crm->map_->begin();
286*9712c20fSFrederick Mayle     iter2 = fast_crm->map_.begin();
287*9712c20fSFrederick Mayle     while (iter1 != basic_crm->map_->end()
288*9712c20fSFrederick Mayle         && iter2 != fast_crm->map_.end()) {
289*9712c20fSFrederick Mayle       ASSERT_TRUE(iter1->first == iter2.GetKey());
290*9712c20fSFrederick Mayle       StaticContainedRangeMap<MemAddr, char>* child =
291*9712c20fSFrederick Mayle           new StaticContainedRangeMap<MemAddr, char>(
292*9712c20fSFrederick Mayle               reinterpret_cast<const char*>(iter2.GetValuePtr()));
293*9712c20fSFrederick Mayle       ASSERT_TRUE(CompareCRM(iter1->second, child));
294*9712c20fSFrederick Mayle       delete child;
295*9712c20fSFrederick Mayle       ++iter1;
296*9712c20fSFrederick Mayle       ++iter2;
297*9712c20fSFrederick Mayle     }
298*9712c20fSFrederick Mayle     ASSERT_TRUE(iter1 == basic_crm->map_->end());
299*9712c20fSFrederick Mayle     ASSERT_TRUE(iter2 == fast_crm->map_.end());
300*9712c20fSFrederick Mayle   }
301*9712c20fSFrederick Mayle 
302*9712c20fSFrederick Mayle   return true;
303*9712c20fSFrederick Mayle }
304*9712c20fSFrederick Mayle 
305*9712c20fSFrederick Mayle }  // namespace google_breakpad
306