Home | History | Annotate | Download | only in dwarf
      1 // -*- mode: c++ -*-
      2 
      3 // Copyright (c) 2010 Google Inc. 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 
     31 // Original author: Jim Blandy <jimb (at) mozilla.com> <jimb (at) red-bean.com>
     32 
     33 // dwarf2diehander_unittest.cc: Unit tests for google_breakpad::DIEDispatcher.
     34 
     35 #include <string>
     36 #include <utility>
     37 
     38 #include "breakpad_googletest_includes.h"
     39 
     40 #include "common/dwarf/dwarf2diehandler.h"
     41 #include "common/using_std_string.h"
     42 
     43 using std::make_pair;
     44 
     45 using ::testing::_;
     46 using ::testing::ContainerEq;
     47 using ::testing::ElementsAreArray;
     48 using ::testing::Eq;
     49 using ::testing::InSequence;
     50 using ::testing::Return;
     51 using ::testing::Sequence;
     52 using ::testing::StrEq;
     53 
     54 using dwarf2reader::DIEDispatcher;
     55 using dwarf2reader::DIEHandler;
     56 using dwarf2reader::DwarfAttribute;
     57 using dwarf2reader::DwarfForm;
     58 using dwarf2reader::DwarfTag;
     59 using dwarf2reader::RootDIEHandler;
     60 
     61 class MockDIEHandler: public DIEHandler {
     62  public:
     63   MOCK_METHOD3(ProcessAttributeUnsigned,
     64                void(DwarfAttribute, DwarfForm, uint64));
     65   MOCK_METHOD3(ProcessAttributeSigned,
     66                void(DwarfAttribute, DwarfForm, int64));
     67   MOCK_METHOD3(ProcessAttributeReference,
     68                void(DwarfAttribute, DwarfForm, uint64));
     69   MOCK_METHOD4(ProcessAttributeBuffer,
     70                void(DwarfAttribute, DwarfForm, const char *, uint64));
     71   MOCK_METHOD3(ProcessAttributeString,
     72                void(DwarfAttribute, DwarfForm, const string &));
     73   MOCK_METHOD3(ProcessAttributeSignature,
     74                void(DwarfAttribute, DwarfForm, uint64));
     75   MOCK_METHOD0(EndAttributes, bool());
     76   MOCK_METHOD2(FindChildHandler, DIEHandler *(uint64, DwarfTag));
     77   MOCK_METHOD0(Finish, void());
     78 };
     79 
     80 class MockRootDIEHandler: public RootDIEHandler {
     81  public:
     82   MOCK_METHOD3(ProcessAttributeUnsigned,
     83                void(DwarfAttribute, DwarfForm, uint64));
     84   MOCK_METHOD3(ProcessAttributeSigned,
     85                void(DwarfAttribute, DwarfForm, int64));
     86   MOCK_METHOD3(ProcessAttributeReference,
     87                void(DwarfAttribute, DwarfForm, uint64));
     88   MOCK_METHOD4(ProcessAttributeBuffer,
     89                void(DwarfAttribute, DwarfForm, const char *, uint64));
     90   MOCK_METHOD3(ProcessAttributeString,
     91                void(DwarfAttribute, DwarfForm, const string &));
     92   MOCK_METHOD3(ProcessAttributeSignature,
     93                void(DwarfAttribute, DwarfForm, uint64));
     94   MOCK_METHOD0(EndAttributes, bool());
     95   MOCK_METHOD2(FindChildHandler, DIEHandler *(uint64, DwarfTag));
     96   MOCK_METHOD0(Finish, void());
     97   MOCK_METHOD5(StartCompilationUnit, bool(uint64, uint8, uint8, uint64, uint8));
     98   MOCK_METHOD2(StartRootDIE, bool(uint64, DwarfTag));
     99 };
    100 
    101 // If the handler elects to skip the compilation unit, the dispatcher
    102 // should tell the reader so.
    103 TEST(Dwarf2DIEHandler, SkipCompilationUnit) {
    104   Sequence s;
    105   MockRootDIEHandler mock_root_handler;
    106   DIEDispatcher die_dispatcher(&mock_root_handler);
    107 
    108   EXPECT_CALL(mock_root_handler,
    109               StartCompilationUnit(0x8d42aed77cfccf3eLL,
    110                                    0x89, 0xdc,
    111                                    0x2ecb4dc778a80f21LL,
    112                                    0x66))
    113       .InSequence(s)
    114       .WillOnce(Return(false));
    115 
    116   EXPECT_FALSE(die_dispatcher.StartCompilationUnit(0x8d42aed77cfccf3eLL,
    117                                                    0x89, 0xdc,
    118                                                    0x2ecb4dc778a80f21LL,
    119                                                    0x66));
    120 }
    121 
    122 // If the handler elects to skip the root DIE, the dispatcher should
    123 // tell the reader so.
    124 TEST(Dwarf2DIEHandler, SkipRootDIE) {
    125   Sequence s;
    126   MockRootDIEHandler mock_root_handler;
    127   DIEDispatcher die_dispatcher(&mock_root_handler);
    128 
    129   EXPECT_CALL(mock_root_handler,
    130               StartCompilationUnit(0xde8994029fc8b999LL, 0xf4, 0x02,
    131                                    0xb00febffa76e2b2bLL, 0x5c))
    132       .InSequence(s)
    133       .WillOnce(Return(true));
    134   EXPECT_CALL(mock_root_handler,
    135               StartRootDIE(0x7d08242b4b510cf2LL, (DwarfTag) 0xb4f98da6))
    136       .InSequence(s)
    137       .WillOnce(Return(false));
    138 
    139   EXPECT_TRUE(die_dispatcher.StartCompilationUnit(0xde8994029fc8b999LL,
    140                                                   0xf4, 0x02,
    141                                                   0xb00febffa76e2b2bLL, 0x5c));
    142   EXPECT_FALSE(die_dispatcher.StartDIE(0x7d08242b4b510cf2LL,
    143                                        (DwarfTag) 0xb4f98da6));
    144   die_dispatcher.EndDIE(0x7d08242b4b510cf2LL);
    145 }
    146 
    147 // If the handler elects to skip the root DIE's children, the
    148 // dispatcher should tell the reader so --- and avoid deleting the
    149 // root handler.
    150 TEST(Dwarf2DIEHandler, SkipRootDIEChildren) {
    151   MockRootDIEHandler mock_root_handler;
    152   DIEDispatcher die_dispatcher(&mock_root_handler);
    153 
    154   {
    155     InSequence s;
    156 
    157     EXPECT_CALL(mock_root_handler,
    158                 StartCompilationUnit(0x15d6897480cc65a7LL, 0x26, 0xa0,
    159                                      0x09f8bf0767f91675LL, 0xdb))
    160       .WillOnce(Return(true));
    161     EXPECT_CALL(mock_root_handler,
    162                 StartRootDIE(0x7d08242b4b510cf2LL, (DwarfTag) 0xb4f98da6))
    163       .WillOnce(Return(true));
    164     // Please don't tell me about my children.
    165     EXPECT_CALL(mock_root_handler, EndAttributes())
    166       .WillOnce(Return(false));
    167     EXPECT_CALL(mock_root_handler, Finish())
    168       .WillOnce(Return());
    169   }
    170 
    171   EXPECT_TRUE(die_dispatcher.StartCompilationUnit(0x15d6897480cc65a7LL,
    172                                                   0x26, 0xa0,
    173                                                   0x09f8bf0767f91675LL, 0xdb));
    174   EXPECT_TRUE(die_dispatcher.StartDIE(0x7d08242b4b510cf2LL,
    175                                       (DwarfTag) 0xb4f98da6));
    176   EXPECT_FALSE(die_dispatcher.StartDIE(0x435150ceedccda18LL,
    177                                        (DwarfTag) 0xc3a17bba));
    178   die_dispatcher.EndDIE(0x435150ceedccda18LL);
    179   die_dispatcher.EndDIE(0x7d08242b4b510cf2LL);
    180 }
    181 
    182 // The dispatcher should pass attribute values through to the die
    183 // handler accurately.
    184 TEST(Dwarf2DIEHandler, PassAttributeValues) {
    185   MockRootDIEHandler mock_root_handler;
    186   DIEDispatcher die_dispatcher(&mock_root_handler);
    187 
    188   const char buffer[10] = { 0x24, 0x24, 0x35, 0x9a, 0xca,
    189                             0xcf, 0xa8, 0x84, 0xa7, 0x18 };
    190   string str = "\xc8\x26\x2e\x0d\xa4\x9c\x37\xd6\xfb\x1d";
    191 
    192   // Set expectations.
    193   {
    194     InSequence s;
    195 
    196     // We'll like the compilation unit header.
    197     EXPECT_CALL(mock_root_handler,
    198                 StartCompilationUnit(0x8d42aed77cfccf3eLL, 0x89, 0xdc,
    199                                      0x2ecb4dc778a80f21LL, 0x66))
    200       .WillOnce(Return(true));
    201 
    202     // We'll like the root DIE.
    203     EXPECT_CALL(mock_root_handler,
    204                 StartRootDIE(0xe2222da01e29f2a9LL, (DwarfTag) 0x9829445c))
    205       .WillOnce(Return(true));
    206 
    207     // Expect some attribute values.
    208     EXPECT_CALL(mock_root_handler,
    209                 ProcessAttributeUnsigned((DwarfAttribute) 0x1cc0bfed,
    210                                          (DwarfForm) 0x424f1468,
    211                                          0xa592571997facda1ULL))
    212       .WillOnce(Return());
    213     EXPECT_CALL(mock_root_handler,
    214                 ProcessAttributeSigned((DwarfAttribute) 0x43694dc9,
    215                                        (DwarfForm) 0xf6f78901L,
    216                                        0x92602a4e3bf1f446LL))
    217       .WillOnce(Return());
    218     EXPECT_CALL(mock_root_handler,
    219                 ProcessAttributeReference((DwarfAttribute) 0x4033e8cL,
    220                                           (DwarfForm) 0xf66fbe0bL,
    221                                           0x50fddef44734fdecULL))
    222       .WillOnce(Return());
    223     EXPECT_CALL(mock_root_handler,
    224                 ProcessAttributeBuffer((DwarfAttribute) 0x25d7e0af,
    225                                        (DwarfForm) 0xe99a539a,
    226                                        buffer, sizeof(buffer)))
    227       .WillOnce(Return());
    228     EXPECT_CALL(mock_root_handler,
    229                 ProcessAttributeString((DwarfAttribute) 0x310ed065,
    230                                        (DwarfForm) 0x15762fec,
    231                                        StrEq(str)))
    232       .WillOnce(Return());
    233     EXPECT_CALL(mock_root_handler,
    234                 ProcessAttributeSignature((DwarfAttribute) 0x58790d72,
    235                                           (DwarfForm) 0x4159f138,
    236                                           0x94682463613e6a5fULL))
    237       .WillOnce(Return());
    238     EXPECT_CALL(mock_root_handler, EndAttributes())
    239       .WillOnce(Return(true));
    240     EXPECT_CALL(mock_root_handler, FindChildHandler(_, _))
    241       .Times(0);
    242     EXPECT_CALL(mock_root_handler, Finish())
    243       .WillOnce(Return());
    244   }
    245 
    246   // Drive the dispatcher.
    247 
    248   // Report the CU header.
    249   EXPECT_TRUE(die_dispatcher.StartCompilationUnit(0x8d42aed77cfccf3eLL,
    250                                                   0x89, 0xdc,
    251                                                   0x2ecb4dc778a80f21LL,
    252                                                   0x66));
    253   // Report the root DIE.
    254   EXPECT_TRUE(die_dispatcher.StartDIE(0xe2222da01e29f2a9LL,
    255                                       (DwarfTag) 0x9829445c));
    256 
    257   // Report some attribute values.
    258   die_dispatcher.ProcessAttributeUnsigned(0xe2222da01e29f2a9LL,
    259                                           (DwarfAttribute) 0x1cc0bfed,
    260                                           (DwarfForm) 0x424f1468,
    261                                           0xa592571997facda1ULL);
    262   die_dispatcher.ProcessAttributeSigned(0xe2222da01e29f2a9LL,
    263                                         (DwarfAttribute) 0x43694dc9,
    264                                         (DwarfForm) 0xf6f78901,
    265                                         0x92602a4e3bf1f446LL);
    266   die_dispatcher.ProcessAttributeReference(0xe2222da01e29f2a9LL,
    267                                            (DwarfAttribute) 0x4033e8c,
    268                                            (DwarfForm) 0xf66fbe0b,
    269                                            0x50fddef44734fdecULL);
    270   die_dispatcher.ProcessAttributeBuffer(0xe2222da01e29f2a9LL,
    271                                         (DwarfAttribute) 0x25d7e0af,
    272                                         (DwarfForm) 0xe99a539a,
    273                                         buffer, sizeof(buffer));
    274   die_dispatcher.ProcessAttributeString(0xe2222da01e29f2a9LL,
    275                                         (DwarfAttribute) 0x310ed065,
    276                                         (DwarfForm) 0x15762fec,
    277                                         str);
    278   die_dispatcher.ProcessAttributeSignature(0xe2222da01e29f2a9LL,
    279                                            (DwarfAttribute) 0x58790d72,
    280                                            (DwarfForm) 0x4159f138,
    281                                            0x94682463613e6a5fULL);
    282 
    283   // Finish the root DIE (and thus the CU).
    284   die_dispatcher.EndDIE(0xe2222da01e29f2a9LL);
    285 }
    286 
    287 TEST(Dwarf2DIEHandler, FindAndSkipChildren) {
    288   MockRootDIEHandler mock_root_handler;
    289   MockDIEHandler *mock_child1_handler = new(MockDIEHandler);
    290   MockDIEHandler *mock_child3_handler = new(MockDIEHandler);
    291   DIEDispatcher die_dispatcher(&mock_root_handler);
    292 
    293   {
    294     InSequence s;
    295 
    296     // We'll like the compilation unit header.
    297     EXPECT_CALL(mock_root_handler,
    298                 StartCompilationUnit(0x9ec1e6d05e434a0eLL, 0xeb, 0x21,
    299                                      0x47dd3c764275a216LL, 0xa5))
    300       .WillOnce(Return(true));
    301 
    302     // Root DIE.
    303     {
    304       EXPECT_CALL(mock_root_handler,
    305                   StartRootDIE(0x15f0e06bdfe3c372LL, (DwarfTag) 0xf5d60c59))
    306         .WillOnce(Return(true));
    307       EXPECT_CALL(mock_root_handler,
    308                   ProcessAttributeSigned((DwarfAttribute) 0xf779a642,
    309                                          (DwarfForm) 0x2cb63027,
    310                                          0x18e744661769d08fLL))
    311         .WillOnce(Return());
    312       EXPECT_CALL(mock_root_handler, EndAttributes())
    313         .WillOnce(Return(true));
    314 
    315       // First child DIE.
    316       EXPECT_CALL(mock_root_handler,
    317                   FindChildHandler(0x149f644f8116fe8cLL,
    318                                    (DwarfTag) 0xac2cbd8c))
    319         .WillOnce(Return(mock_child1_handler));
    320       {
    321         EXPECT_CALL(*mock_child1_handler,
    322                     ProcessAttributeSigned((DwarfAttribute) 0xa6fd6f65,
    323                                            (DwarfForm) 0xe4f64c41,
    324                                            0x1b04e5444a55fe67LL))
    325           .WillOnce(Return());
    326         EXPECT_CALL(*mock_child1_handler, EndAttributes())
    327           .WillOnce(Return(false));
    328         // Skip first grandchild DIE and first great-grandchild DIE.
    329         EXPECT_CALL(*mock_child1_handler, Finish())
    330           .WillOnce(Return());
    331       }
    332 
    333       // Second child DIE.  Root handler will decline to return a handler
    334       // for this child.
    335       EXPECT_CALL(mock_root_handler,
    336                   FindChildHandler(0x97412be24875de9dLL,
    337                                    (DwarfTag) 0x505a068b))
    338         .WillOnce(Return((DIEHandler *) NULL));
    339 
    340       // Third child DIE.
    341       EXPECT_CALL(mock_root_handler,
    342                   FindChildHandler(0x753c964c8ab538aeLL,
    343                                    (DwarfTag) 0x8c22970e))
    344         .WillOnce(Return(mock_child3_handler));
    345       {
    346         EXPECT_CALL(*mock_child3_handler,
    347                     ProcessAttributeSigned((DwarfAttribute) 0x4e2b7cfb,
    348                                            (DwarfForm) 0x610b7ae1,
    349                                            0x3ea5c609d7d7560fLL))
    350           .WillOnce(Return());
    351         EXPECT_CALL(*mock_child3_handler, EndAttributes())
    352           .WillOnce(Return(true));
    353         EXPECT_CALL(*mock_child3_handler, Finish())
    354           .WillOnce(Return());
    355       }
    356 
    357       EXPECT_CALL(mock_root_handler, Finish())
    358         .WillOnce(Return());
    359     }
    360   }
    361 
    362 
    363   // Drive the dispatcher.
    364 
    365   // Report the CU header.
    366   EXPECT_TRUE(die_dispatcher
    367               .StartCompilationUnit(0x9ec1e6d05e434a0eLL, 0xeb, 0x21,
    368                                     0x47dd3c764275a216LL, 0xa5));
    369   // Report the root DIE.
    370   {
    371     EXPECT_TRUE(die_dispatcher.StartDIE(0x15f0e06bdfe3c372LL,
    372                                         (DwarfTag) 0xf5d60c59));
    373     die_dispatcher.ProcessAttributeSigned(0x15f0e06bdfe3c372LL,
    374                                           (DwarfAttribute) 0xf779a642,
    375                                           (DwarfForm) 0x2cb63027,
    376                                           0x18e744661769d08fLL);
    377 
    378     // First child DIE.
    379     {
    380       EXPECT_TRUE(die_dispatcher.StartDIE(0x149f644f8116fe8cLL,
    381                                           (DwarfTag) 0xac2cbd8c));
    382       die_dispatcher.ProcessAttributeSigned(0x149f644f8116fe8cLL,
    383                                             (DwarfAttribute) 0xa6fd6f65,
    384                                             (DwarfForm) 0xe4f64c41,
    385                                             0x1b04e5444a55fe67LL);
    386 
    387       // First grandchild DIE.  Will be skipped.
    388       {
    389         EXPECT_FALSE(die_dispatcher.StartDIE(0xd68de1ee0bd29419LL,
    390                                             (DwarfTag) 0x22f05a15));
    391         // First great-grandchild DIE.  Will be skipped without being
    392         // mentioned to any handler.
    393         {
    394           EXPECT_FALSE(die_dispatcher
    395                        .StartDIE(0xb3076285d25cac25LL,
    396                                  (DwarfTag) 0xcff4061b));
    397           die_dispatcher.EndDIE(0xb3076285d25cac25LL);
    398         }
    399         die_dispatcher.EndDIE(0xd68de1ee0bd29419LL);
    400       }
    401       die_dispatcher.EndDIE(0x149f644f8116fe8cLL);
    402     }
    403 
    404     // Second child DIE.  Root handler will decline to find a handler for it.
    405     {
    406       EXPECT_FALSE(die_dispatcher.StartDIE(0x97412be24875de9dLL,
    407                                            (DwarfTag) 0x505a068b));
    408       die_dispatcher.EndDIE(0x97412be24875de9dLL);
    409     }
    410 
    411     // Third child DIE.
    412     {
    413       EXPECT_TRUE(die_dispatcher.StartDIE(0x753c964c8ab538aeLL,
    414                                           (DwarfTag) 0x8c22970e));
    415       die_dispatcher.ProcessAttributeSigned(0x753c964c8ab538aeLL,
    416                                             (DwarfAttribute) 0x4e2b7cfb,
    417                                             (DwarfForm) 0x610b7ae1,
    418                                             0x3ea5c609d7d7560fLL);
    419       die_dispatcher.EndDIE(0x753c964c8ab538aeLL);
    420     }
    421 
    422     // Finish the root DIE (and thus the CU).
    423     die_dispatcher.EndDIE(0x15f0e06bdfe3c372LL);
    424   }
    425 }
    426 
    427 // The DIEDispatcher destructor is supposed to delete all handlers on
    428 // the stack, except for the root.
    429 TEST(Dwarf2DIEHandler, FreeHandlersOnStack) {
    430   MockRootDIEHandler mock_root_handler;
    431   MockDIEHandler *mock_child_handler = new(MockDIEHandler);
    432   MockDIEHandler *mock_grandchild_handler = new(MockDIEHandler);
    433 
    434   {
    435     InSequence s;
    436 
    437     // We'll like the compilation unit header.
    438     EXPECT_CALL(mock_root_handler,
    439                 StartCompilationUnit(0x87b41ba8381cd71cLL, 0xff, 0x89,
    440                                      0x76d392ff393ddda2LL, 0xbf))
    441       .WillOnce(Return(true));
    442 
    443     // Root DIE.
    444     {
    445       EXPECT_CALL(mock_root_handler,
    446                   StartRootDIE(0xbf13b761691ddc91LL, (DwarfTag) 0x98980361))
    447         .WillOnce(Return(true));
    448       EXPECT_CALL(mock_root_handler, EndAttributes())
    449         .WillOnce(Return(true));
    450 
    451       // Child DIE.
    452       EXPECT_CALL(mock_root_handler,
    453                   FindChildHandler(0x058f09240c5fc8c9LL,
    454                                    (DwarfTag) 0x898bf0d0))
    455         .WillOnce(Return(mock_child_handler));
    456       {
    457         EXPECT_CALL(*mock_child_handler, EndAttributes())
    458           .WillOnce(Return(true));
    459 
    460         // Grandchild DIE.
    461         EXPECT_CALL(*mock_child_handler,
    462                     FindChildHandler(0x32dc00c9945dc0c8LL,
    463                                      (DwarfTag) 0x2802d007))
    464           .WillOnce(Return(mock_grandchild_handler));
    465         {
    466           EXPECT_CALL(*mock_grandchild_handler,
    467                       ProcessAttributeSigned((DwarfAttribute) 0x4e2b7cfb,
    468                                              (DwarfForm) 0x610b7ae1,
    469                                              0x3ea5c609d7d7560fLL))
    470             .WillOnce(Return());
    471 
    472           // At this point, we abandon the traversal, so none of the
    473           // usual stuff should get called.
    474           EXPECT_CALL(*mock_grandchild_handler, EndAttributes())
    475             .Times(0);
    476           EXPECT_CALL(*mock_grandchild_handler, Finish())
    477             .Times(0);
    478         }
    479 
    480         EXPECT_CALL(*mock_child_handler, Finish())
    481           .Times(0);
    482       }
    483 
    484       EXPECT_CALL(mock_root_handler, Finish())
    485         .Times(0);
    486     }
    487   }
    488 
    489   // The dispatcher.
    490   DIEDispatcher die_dispatcher(&mock_root_handler);
    491 
    492   // Report the CU header.
    493   EXPECT_TRUE(die_dispatcher
    494               .StartCompilationUnit(0x87b41ba8381cd71cLL, 0xff, 0x89,
    495                                     0x76d392ff393ddda2LL, 0xbf));
    496   // Report the root DIE.
    497   {
    498     EXPECT_TRUE(die_dispatcher.StartDIE(0xbf13b761691ddc91LL,
    499                                         (DwarfTag) 0x98980361));
    500 
    501     // Child DIE.
    502     {
    503       EXPECT_TRUE(die_dispatcher.StartDIE(0x058f09240c5fc8c9LL,
    504                                           (DwarfTag) 0x898bf0d0));
    505 
    506       // Grandchild DIE.
    507       {
    508         EXPECT_TRUE(die_dispatcher.StartDIE(0x32dc00c9945dc0c8LL,
    509                                             (DwarfTag) 0x2802d007));
    510         die_dispatcher.ProcessAttributeSigned(0x32dc00c9945dc0c8LL,
    511                                               (DwarfAttribute) 0x4e2b7cfb,
    512                                               (DwarfForm) 0x610b7ae1,
    513                                               0x3ea5c609d7d7560fLL);
    514 
    515         // Stop the traversal abruptly, so that there will still be
    516         // handlers on the stack when the dispatcher is destructed.
    517 
    518         // No EndDIE call...
    519       }
    520       // No EndDIE call...
    521     }
    522     // No EndDIE call...
    523   }
    524 }
    525