1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 1.2 +++ b/toolkit/crashreporter/google-breakpad/src/common/dwarf/dwarf2diehandler_unittest.cc Wed Dec 31 06:09:35 2014 +0100 1.3 @@ -0,0 +1,524 @@ 1.4 +// -*- mode: c++ -*- 1.5 + 1.6 +// Copyright (c) 2010 Google Inc. All Rights Reserved. 1.7 +// 1.8 +// Redistribution and use in source and binary forms, with or without 1.9 +// modification, are permitted provided that the following conditions are 1.10 +// met: 1.11 +// 1.12 +// * Redistributions of source code must retain the above copyright 1.13 +// notice, this list of conditions and the following disclaimer. 1.14 +// * Redistributions in binary form must reproduce the above 1.15 +// copyright notice, this list of conditions and the following disclaimer 1.16 +// in the documentation and/or other materials provided with the 1.17 +// distribution. 1.18 +// * Neither the name of Google Inc. nor the names of its 1.19 +// contributors may be used to endorse or promote products derived from 1.20 +// this software without specific prior written permission. 1.21 +// 1.22 +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 1.23 +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 1.24 +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 1.25 +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 1.26 +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 1.27 +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 1.28 +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 1.29 +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 1.30 +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 1.31 +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 1.32 +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 1.33 + 1.34 +// Original author: Jim Blandy <jimb@mozilla.com> <jimb@red-bean.com> 1.35 + 1.36 +// dwarf2diehander_unittest.cc: Unit tests for google_breakpad::DIEDispatcher. 1.37 + 1.38 +#include <string> 1.39 +#include <utility> 1.40 + 1.41 +#include "breakpad_googletest_includes.h" 1.42 + 1.43 +#include "common/dwarf/dwarf2diehandler.h" 1.44 +#include "common/using_std_string.h" 1.45 + 1.46 +using std::make_pair; 1.47 + 1.48 +using ::testing::_; 1.49 +using ::testing::ContainerEq; 1.50 +using ::testing::ElementsAreArray; 1.51 +using ::testing::Eq; 1.52 +using ::testing::InSequence; 1.53 +using ::testing::Return; 1.54 +using ::testing::Sequence; 1.55 +using ::testing::StrEq; 1.56 + 1.57 +using dwarf2reader::DIEDispatcher; 1.58 +using dwarf2reader::DIEHandler; 1.59 +using dwarf2reader::DwarfAttribute; 1.60 +using dwarf2reader::DwarfForm; 1.61 +using dwarf2reader::DwarfTag; 1.62 +using dwarf2reader::RootDIEHandler; 1.63 + 1.64 +class MockDIEHandler: public DIEHandler { 1.65 + public: 1.66 + MOCK_METHOD3(ProcessAttributeUnsigned, 1.67 + void(DwarfAttribute, DwarfForm, uint64)); 1.68 + MOCK_METHOD3(ProcessAttributeSigned, 1.69 + void(DwarfAttribute, DwarfForm, int64)); 1.70 + MOCK_METHOD3(ProcessAttributeReference, 1.71 + void(DwarfAttribute, DwarfForm, uint64)); 1.72 + MOCK_METHOD4(ProcessAttributeBuffer, 1.73 + void(DwarfAttribute, DwarfForm, const char *, uint64)); 1.74 + MOCK_METHOD3(ProcessAttributeString, 1.75 + void(DwarfAttribute, DwarfForm, const string &)); 1.76 + MOCK_METHOD3(ProcessAttributeSignature, 1.77 + void(DwarfAttribute, DwarfForm, uint64)); 1.78 + MOCK_METHOD0(EndAttributes, bool()); 1.79 + MOCK_METHOD2(FindChildHandler, DIEHandler *(uint64, DwarfTag)); 1.80 + MOCK_METHOD0(Finish, void()); 1.81 +}; 1.82 + 1.83 +class MockRootDIEHandler: public RootDIEHandler { 1.84 + public: 1.85 + MOCK_METHOD3(ProcessAttributeUnsigned, 1.86 + void(DwarfAttribute, DwarfForm, uint64)); 1.87 + MOCK_METHOD3(ProcessAttributeSigned, 1.88 + void(DwarfAttribute, DwarfForm, int64)); 1.89 + MOCK_METHOD3(ProcessAttributeReference, 1.90 + void(DwarfAttribute, DwarfForm, uint64)); 1.91 + MOCK_METHOD4(ProcessAttributeBuffer, 1.92 + void(DwarfAttribute, DwarfForm, const char *, uint64)); 1.93 + MOCK_METHOD3(ProcessAttributeString, 1.94 + void(DwarfAttribute, DwarfForm, const string &)); 1.95 + MOCK_METHOD3(ProcessAttributeSignature, 1.96 + void(DwarfAttribute, DwarfForm, uint64)); 1.97 + MOCK_METHOD0(EndAttributes, bool()); 1.98 + MOCK_METHOD2(FindChildHandler, DIEHandler *(uint64, DwarfTag)); 1.99 + MOCK_METHOD0(Finish, void()); 1.100 + MOCK_METHOD5(StartCompilationUnit, bool(uint64, uint8, uint8, uint64, uint8)); 1.101 + MOCK_METHOD2(StartRootDIE, bool(uint64, DwarfTag)); 1.102 +}; 1.103 + 1.104 +// If the handler elects to skip the compilation unit, the dispatcher 1.105 +// should tell the reader so. 1.106 +TEST(Dwarf2DIEHandler, SkipCompilationUnit) { 1.107 + Sequence s; 1.108 + MockRootDIEHandler mock_root_handler; 1.109 + DIEDispatcher die_dispatcher(&mock_root_handler); 1.110 + 1.111 + EXPECT_CALL(mock_root_handler, 1.112 + StartCompilationUnit(0x8d42aed77cfccf3eLL, 1.113 + 0x89, 0xdc, 1.114 + 0x2ecb4dc778a80f21LL, 1.115 + 0x66)) 1.116 + .InSequence(s) 1.117 + .WillOnce(Return(false)); 1.118 + 1.119 + EXPECT_FALSE(die_dispatcher.StartCompilationUnit(0x8d42aed77cfccf3eLL, 1.120 + 0x89, 0xdc, 1.121 + 0x2ecb4dc778a80f21LL, 1.122 + 0x66)); 1.123 +} 1.124 + 1.125 +// If the handler elects to skip the root DIE, the dispatcher should 1.126 +// tell the reader so. 1.127 +TEST(Dwarf2DIEHandler, SkipRootDIE) { 1.128 + Sequence s; 1.129 + MockRootDIEHandler mock_root_handler; 1.130 + DIEDispatcher die_dispatcher(&mock_root_handler); 1.131 + 1.132 + EXPECT_CALL(mock_root_handler, 1.133 + StartCompilationUnit(0xde8994029fc8b999LL, 0xf4, 0x02, 1.134 + 0xb00febffa76e2b2bLL, 0x5c)) 1.135 + .InSequence(s) 1.136 + .WillOnce(Return(true)); 1.137 + EXPECT_CALL(mock_root_handler, 1.138 + StartRootDIE(0x7d08242b4b510cf2LL, (DwarfTag) 0xb4f98da6)) 1.139 + .InSequence(s) 1.140 + .WillOnce(Return(false)); 1.141 + 1.142 + EXPECT_TRUE(die_dispatcher.StartCompilationUnit(0xde8994029fc8b999LL, 1.143 + 0xf4, 0x02, 1.144 + 0xb00febffa76e2b2bLL, 0x5c)); 1.145 + EXPECT_FALSE(die_dispatcher.StartDIE(0x7d08242b4b510cf2LL, 1.146 + (DwarfTag) 0xb4f98da6)); 1.147 + die_dispatcher.EndDIE(0x7d08242b4b510cf2LL); 1.148 +} 1.149 + 1.150 +// If the handler elects to skip the root DIE's children, the 1.151 +// dispatcher should tell the reader so --- and avoid deleting the 1.152 +// root handler. 1.153 +TEST(Dwarf2DIEHandler, SkipRootDIEChildren) { 1.154 + MockRootDIEHandler mock_root_handler; 1.155 + DIEDispatcher die_dispatcher(&mock_root_handler); 1.156 + 1.157 + { 1.158 + InSequence s; 1.159 + 1.160 + EXPECT_CALL(mock_root_handler, 1.161 + StartCompilationUnit(0x15d6897480cc65a7LL, 0x26, 0xa0, 1.162 + 0x09f8bf0767f91675LL, 0xdb)) 1.163 + .WillOnce(Return(true)); 1.164 + EXPECT_CALL(mock_root_handler, 1.165 + StartRootDIE(0x7d08242b4b510cf2LL, (DwarfTag) 0xb4f98da6)) 1.166 + .WillOnce(Return(true)); 1.167 + // Please don't tell me about my children. 1.168 + EXPECT_CALL(mock_root_handler, EndAttributes()) 1.169 + .WillOnce(Return(false)); 1.170 + EXPECT_CALL(mock_root_handler, Finish()) 1.171 + .WillOnce(Return()); 1.172 + } 1.173 + 1.174 + EXPECT_TRUE(die_dispatcher.StartCompilationUnit(0x15d6897480cc65a7LL, 1.175 + 0x26, 0xa0, 1.176 + 0x09f8bf0767f91675LL, 0xdb)); 1.177 + EXPECT_TRUE(die_dispatcher.StartDIE(0x7d08242b4b510cf2LL, 1.178 + (DwarfTag) 0xb4f98da6)); 1.179 + EXPECT_FALSE(die_dispatcher.StartDIE(0x435150ceedccda18LL, 1.180 + (DwarfTag) 0xc3a17bba)); 1.181 + die_dispatcher.EndDIE(0x435150ceedccda18LL); 1.182 + die_dispatcher.EndDIE(0x7d08242b4b510cf2LL); 1.183 +} 1.184 + 1.185 +// The dispatcher should pass attribute values through to the die 1.186 +// handler accurately. 1.187 +TEST(Dwarf2DIEHandler, PassAttributeValues) { 1.188 + MockRootDIEHandler mock_root_handler; 1.189 + DIEDispatcher die_dispatcher(&mock_root_handler); 1.190 + 1.191 + const char buffer[10] = { 0x24, 0x24, 0x35, 0x9a, 0xca, 1.192 + 0xcf, 0xa8, 0x84, 0xa7, 0x18 }; 1.193 + string str = "\xc8\x26\x2e\x0d\xa4\x9c\x37\xd6\xfb\x1d"; 1.194 + 1.195 + // Set expectations. 1.196 + { 1.197 + InSequence s; 1.198 + 1.199 + // We'll like the compilation unit header. 1.200 + EXPECT_CALL(mock_root_handler, 1.201 + StartCompilationUnit(0x8d42aed77cfccf3eLL, 0x89, 0xdc, 1.202 + 0x2ecb4dc778a80f21LL, 0x66)) 1.203 + .WillOnce(Return(true)); 1.204 + 1.205 + // We'll like the root DIE. 1.206 + EXPECT_CALL(mock_root_handler, 1.207 + StartRootDIE(0xe2222da01e29f2a9LL, (DwarfTag) 0x9829445c)) 1.208 + .WillOnce(Return(true)); 1.209 + 1.210 + // Expect some attribute values. 1.211 + EXPECT_CALL(mock_root_handler, 1.212 + ProcessAttributeUnsigned((DwarfAttribute) 0x1cc0bfed, 1.213 + (DwarfForm) 0x424f1468, 1.214 + 0xa592571997facda1ULL)) 1.215 + .WillOnce(Return()); 1.216 + EXPECT_CALL(mock_root_handler, 1.217 + ProcessAttributeSigned((DwarfAttribute) 0x43694dc9, 1.218 + (DwarfForm) 0xf6f78901L, 1.219 + 0x92602a4e3bf1f446LL)) 1.220 + .WillOnce(Return()); 1.221 + EXPECT_CALL(mock_root_handler, 1.222 + ProcessAttributeReference((DwarfAttribute) 0x4033e8cL, 1.223 + (DwarfForm) 0xf66fbe0bL, 1.224 + 0x50fddef44734fdecULL)) 1.225 + .WillOnce(Return()); 1.226 + EXPECT_CALL(mock_root_handler, 1.227 + ProcessAttributeBuffer((DwarfAttribute) 0x25d7e0af, 1.228 + (DwarfForm) 0xe99a539a, 1.229 + buffer, sizeof(buffer))) 1.230 + .WillOnce(Return()); 1.231 + EXPECT_CALL(mock_root_handler, 1.232 + ProcessAttributeString((DwarfAttribute) 0x310ed065, 1.233 + (DwarfForm) 0x15762fec, 1.234 + StrEq(str))) 1.235 + .WillOnce(Return()); 1.236 + EXPECT_CALL(mock_root_handler, 1.237 + ProcessAttributeSignature((DwarfAttribute) 0x58790d72, 1.238 + (DwarfForm) 0x4159f138, 1.239 + 0x94682463613e6a5fULL)) 1.240 + .WillOnce(Return()); 1.241 + EXPECT_CALL(mock_root_handler, EndAttributes()) 1.242 + .WillOnce(Return(true)); 1.243 + EXPECT_CALL(mock_root_handler, FindChildHandler(_, _)) 1.244 + .Times(0); 1.245 + EXPECT_CALL(mock_root_handler, Finish()) 1.246 + .WillOnce(Return()); 1.247 + } 1.248 + 1.249 + // Drive the dispatcher. 1.250 + 1.251 + // Report the CU header. 1.252 + EXPECT_TRUE(die_dispatcher.StartCompilationUnit(0x8d42aed77cfccf3eLL, 1.253 + 0x89, 0xdc, 1.254 + 0x2ecb4dc778a80f21LL, 1.255 + 0x66)); 1.256 + // Report the root DIE. 1.257 + EXPECT_TRUE(die_dispatcher.StartDIE(0xe2222da01e29f2a9LL, 1.258 + (DwarfTag) 0x9829445c)); 1.259 + 1.260 + // Report some attribute values. 1.261 + die_dispatcher.ProcessAttributeUnsigned(0xe2222da01e29f2a9LL, 1.262 + (DwarfAttribute) 0x1cc0bfed, 1.263 + (DwarfForm) 0x424f1468, 1.264 + 0xa592571997facda1ULL); 1.265 + die_dispatcher.ProcessAttributeSigned(0xe2222da01e29f2a9LL, 1.266 + (DwarfAttribute) 0x43694dc9, 1.267 + (DwarfForm) 0xf6f78901, 1.268 + 0x92602a4e3bf1f446LL); 1.269 + die_dispatcher.ProcessAttributeReference(0xe2222da01e29f2a9LL, 1.270 + (DwarfAttribute) 0x4033e8c, 1.271 + (DwarfForm) 0xf66fbe0b, 1.272 + 0x50fddef44734fdecULL); 1.273 + die_dispatcher.ProcessAttributeBuffer(0xe2222da01e29f2a9LL, 1.274 + (DwarfAttribute) 0x25d7e0af, 1.275 + (DwarfForm) 0xe99a539a, 1.276 + buffer, sizeof(buffer)); 1.277 + die_dispatcher.ProcessAttributeString(0xe2222da01e29f2a9LL, 1.278 + (DwarfAttribute) 0x310ed065, 1.279 + (DwarfForm) 0x15762fec, 1.280 + str); 1.281 + die_dispatcher.ProcessAttributeSignature(0xe2222da01e29f2a9LL, 1.282 + (DwarfAttribute) 0x58790d72, 1.283 + (DwarfForm) 0x4159f138, 1.284 + 0x94682463613e6a5fULL); 1.285 + 1.286 + // Finish the root DIE (and thus the CU). 1.287 + die_dispatcher.EndDIE(0xe2222da01e29f2a9LL); 1.288 +} 1.289 + 1.290 +TEST(Dwarf2DIEHandler, FindAndSkipChildren) { 1.291 + MockRootDIEHandler mock_root_handler; 1.292 + MockDIEHandler *mock_child1_handler = new(MockDIEHandler); 1.293 + MockDIEHandler *mock_child3_handler = new(MockDIEHandler); 1.294 + DIEDispatcher die_dispatcher(&mock_root_handler); 1.295 + 1.296 + { 1.297 + InSequence s; 1.298 + 1.299 + // We'll like the compilation unit header. 1.300 + EXPECT_CALL(mock_root_handler, 1.301 + StartCompilationUnit(0x9ec1e6d05e434a0eLL, 0xeb, 0x21, 1.302 + 0x47dd3c764275a216LL, 0xa5)) 1.303 + .WillOnce(Return(true)); 1.304 + 1.305 + // Root DIE. 1.306 + { 1.307 + EXPECT_CALL(mock_root_handler, 1.308 + StartRootDIE(0x15f0e06bdfe3c372LL, (DwarfTag) 0xf5d60c59)) 1.309 + .WillOnce(Return(true)); 1.310 + EXPECT_CALL(mock_root_handler, 1.311 + ProcessAttributeSigned((DwarfAttribute) 0xf779a642, 1.312 + (DwarfForm) 0x2cb63027, 1.313 + 0x18e744661769d08fLL)) 1.314 + .WillOnce(Return()); 1.315 + EXPECT_CALL(mock_root_handler, EndAttributes()) 1.316 + .WillOnce(Return(true)); 1.317 + 1.318 + // First child DIE. 1.319 + EXPECT_CALL(mock_root_handler, 1.320 + FindChildHandler(0x149f644f8116fe8cLL, 1.321 + (DwarfTag) 0xac2cbd8c)) 1.322 + .WillOnce(Return(mock_child1_handler)); 1.323 + { 1.324 + EXPECT_CALL(*mock_child1_handler, 1.325 + ProcessAttributeSigned((DwarfAttribute) 0xa6fd6f65, 1.326 + (DwarfForm) 0xe4f64c41, 1.327 + 0x1b04e5444a55fe67LL)) 1.328 + .WillOnce(Return()); 1.329 + EXPECT_CALL(*mock_child1_handler, EndAttributes()) 1.330 + .WillOnce(Return(false)); 1.331 + // Skip first grandchild DIE and first great-grandchild DIE. 1.332 + EXPECT_CALL(*mock_child1_handler, Finish()) 1.333 + .WillOnce(Return()); 1.334 + } 1.335 + 1.336 + // Second child DIE. Root handler will decline to return a handler 1.337 + // for this child. 1.338 + EXPECT_CALL(mock_root_handler, 1.339 + FindChildHandler(0x97412be24875de9dLL, 1.340 + (DwarfTag) 0x505a068b)) 1.341 + .WillOnce(Return((DIEHandler *) NULL)); 1.342 + 1.343 + // Third child DIE. 1.344 + EXPECT_CALL(mock_root_handler, 1.345 + FindChildHandler(0x753c964c8ab538aeLL, 1.346 + (DwarfTag) 0x8c22970e)) 1.347 + .WillOnce(Return(mock_child3_handler)); 1.348 + { 1.349 + EXPECT_CALL(*mock_child3_handler, 1.350 + ProcessAttributeSigned((DwarfAttribute) 0x4e2b7cfb, 1.351 + (DwarfForm) 0x610b7ae1, 1.352 + 0x3ea5c609d7d7560fLL)) 1.353 + .WillOnce(Return()); 1.354 + EXPECT_CALL(*mock_child3_handler, EndAttributes()) 1.355 + .WillOnce(Return(true)); 1.356 + EXPECT_CALL(*mock_child3_handler, Finish()) 1.357 + .WillOnce(Return()); 1.358 + } 1.359 + 1.360 + EXPECT_CALL(mock_root_handler, Finish()) 1.361 + .WillOnce(Return()); 1.362 + } 1.363 + } 1.364 + 1.365 + 1.366 + // Drive the dispatcher. 1.367 + 1.368 + // Report the CU header. 1.369 + EXPECT_TRUE(die_dispatcher 1.370 + .StartCompilationUnit(0x9ec1e6d05e434a0eLL, 0xeb, 0x21, 1.371 + 0x47dd3c764275a216LL, 0xa5)); 1.372 + // Report the root DIE. 1.373 + { 1.374 + EXPECT_TRUE(die_dispatcher.StartDIE(0x15f0e06bdfe3c372LL, 1.375 + (DwarfTag) 0xf5d60c59)); 1.376 + die_dispatcher.ProcessAttributeSigned(0x15f0e06bdfe3c372LL, 1.377 + (DwarfAttribute) 0xf779a642, 1.378 + (DwarfForm) 0x2cb63027, 1.379 + 0x18e744661769d08fLL); 1.380 + 1.381 + // First child DIE. 1.382 + { 1.383 + EXPECT_TRUE(die_dispatcher.StartDIE(0x149f644f8116fe8cLL, 1.384 + (DwarfTag) 0xac2cbd8c)); 1.385 + die_dispatcher.ProcessAttributeSigned(0x149f644f8116fe8cLL, 1.386 + (DwarfAttribute) 0xa6fd6f65, 1.387 + (DwarfForm) 0xe4f64c41, 1.388 + 0x1b04e5444a55fe67LL); 1.389 + 1.390 + // First grandchild DIE. Will be skipped. 1.391 + { 1.392 + EXPECT_FALSE(die_dispatcher.StartDIE(0xd68de1ee0bd29419LL, 1.393 + (DwarfTag) 0x22f05a15)); 1.394 + // First great-grandchild DIE. Will be skipped without being 1.395 + // mentioned to any handler. 1.396 + { 1.397 + EXPECT_FALSE(die_dispatcher 1.398 + .StartDIE(0xb3076285d25cac25LL, 1.399 + (DwarfTag) 0xcff4061b)); 1.400 + die_dispatcher.EndDIE(0xb3076285d25cac25LL); 1.401 + } 1.402 + die_dispatcher.EndDIE(0xd68de1ee0bd29419LL); 1.403 + } 1.404 + die_dispatcher.EndDIE(0x149f644f8116fe8cLL); 1.405 + } 1.406 + 1.407 + // Second child DIE. Root handler will decline to find a handler for it. 1.408 + { 1.409 + EXPECT_FALSE(die_dispatcher.StartDIE(0x97412be24875de9dLL, 1.410 + (DwarfTag) 0x505a068b)); 1.411 + die_dispatcher.EndDIE(0x97412be24875de9dLL); 1.412 + } 1.413 + 1.414 + // Third child DIE. 1.415 + { 1.416 + EXPECT_TRUE(die_dispatcher.StartDIE(0x753c964c8ab538aeLL, 1.417 + (DwarfTag) 0x8c22970e)); 1.418 + die_dispatcher.ProcessAttributeSigned(0x753c964c8ab538aeLL, 1.419 + (DwarfAttribute) 0x4e2b7cfb, 1.420 + (DwarfForm) 0x610b7ae1, 1.421 + 0x3ea5c609d7d7560fLL); 1.422 + die_dispatcher.EndDIE(0x753c964c8ab538aeLL); 1.423 + } 1.424 + 1.425 + // Finish the root DIE (and thus the CU). 1.426 + die_dispatcher.EndDIE(0x15f0e06bdfe3c372LL); 1.427 + } 1.428 +} 1.429 + 1.430 +// The DIEDispatcher destructor is supposed to delete all handlers on 1.431 +// the stack, except for the root. 1.432 +TEST(Dwarf2DIEHandler, FreeHandlersOnStack) { 1.433 + MockRootDIEHandler mock_root_handler; 1.434 + MockDIEHandler *mock_child_handler = new(MockDIEHandler); 1.435 + MockDIEHandler *mock_grandchild_handler = new(MockDIEHandler); 1.436 + 1.437 + { 1.438 + InSequence s; 1.439 + 1.440 + // We'll like the compilation unit header. 1.441 + EXPECT_CALL(mock_root_handler, 1.442 + StartCompilationUnit(0x87b41ba8381cd71cLL, 0xff, 0x89, 1.443 + 0x76d392ff393ddda2LL, 0xbf)) 1.444 + .WillOnce(Return(true)); 1.445 + 1.446 + // Root DIE. 1.447 + { 1.448 + EXPECT_CALL(mock_root_handler, 1.449 + StartRootDIE(0xbf13b761691ddc91LL, (DwarfTag) 0x98980361)) 1.450 + .WillOnce(Return(true)); 1.451 + EXPECT_CALL(mock_root_handler, EndAttributes()) 1.452 + .WillOnce(Return(true)); 1.453 + 1.454 + // Child DIE. 1.455 + EXPECT_CALL(mock_root_handler, 1.456 + FindChildHandler(0x058f09240c5fc8c9LL, 1.457 + (DwarfTag) 0x898bf0d0)) 1.458 + .WillOnce(Return(mock_child_handler)); 1.459 + { 1.460 + EXPECT_CALL(*mock_child_handler, EndAttributes()) 1.461 + .WillOnce(Return(true)); 1.462 + 1.463 + // Grandchild DIE. 1.464 + EXPECT_CALL(*mock_child_handler, 1.465 + FindChildHandler(0x32dc00c9945dc0c8LL, 1.466 + (DwarfTag) 0x2802d007)) 1.467 + .WillOnce(Return(mock_grandchild_handler)); 1.468 + { 1.469 + EXPECT_CALL(*mock_grandchild_handler, 1.470 + ProcessAttributeSigned((DwarfAttribute) 0x4e2b7cfb, 1.471 + (DwarfForm) 0x610b7ae1, 1.472 + 0x3ea5c609d7d7560fLL)) 1.473 + .WillOnce(Return()); 1.474 + 1.475 + // At this point, we abandon the traversal, so none of the 1.476 + // usual stuff should get called. 1.477 + EXPECT_CALL(*mock_grandchild_handler, EndAttributes()) 1.478 + .Times(0); 1.479 + EXPECT_CALL(*mock_grandchild_handler, Finish()) 1.480 + .Times(0); 1.481 + } 1.482 + 1.483 + EXPECT_CALL(*mock_child_handler, Finish()) 1.484 + .Times(0); 1.485 + } 1.486 + 1.487 + EXPECT_CALL(mock_root_handler, Finish()) 1.488 + .Times(0); 1.489 + } 1.490 + } 1.491 + 1.492 + // The dispatcher. 1.493 + DIEDispatcher die_dispatcher(&mock_root_handler); 1.494 + 1.495 + // Report the CU header. 1.496 + EXPECT_TRUE(die_dispatcher 1.497 + .StartCompilationUnit(0x87b41ba8381cd71cLL, 0xff, 0x89, 1.498 + 0x76d392ff393ddda2LL, 0xbf)); 1.499 + // Report the root DIE. 1.500 + { 1.501 + EXPECT_TRUE(die_dispatcher.StartDIE(0xbf13b761691ddc91LL, 1.502 + (DwarfTag) 0x98980361)); 1.503 + 1.504 + // Child DIE. 1.505 + { 1.506 + EXPECT_TRUE(die_dispatcher.StartDIE(0x058f09240c5fc8c9LL, 1.507 + (DwarfTag) 0x898bf0d0)); 1.508 + 1.509 + // Grandchild DIE. 1.510 + { 1.511 + EXPECT_TRUE(die_dispatcher.StartDIE(0x32dc00c9945dc0c8LL, 1.512 + (DwarfTag) 0x2802d007)); 1.513 + die_dispatcher.ProcessAttributeSigned(0x32dc00c9945dc0c8LL, 1.514 + (DwarfAttribute) 0x4e2b7cfb, 1.515 + (DwarfForm) 0x610b7ae1, 1.516 + 0x3ea5c609d7d7560fLL); 1.517 + 1.518 + // Stop the traversal abruptly, so that there will still be 1.519 + // handlers on the stack when the dispatcher is destructed. 1.520 + 1.521 + // No EndDIE call... 1.522 + } 1.523 + // No EndDIE call... 1.524 + } 1.525 + // No EndDIE call... 1.526 + } 1.527 +}