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