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