/thirdparty/breakpad/common/dwarf/dwarf2diehandler_unittest.cc

http://github.com/tomahawk-player/tomahawk · C++ · 579 lines · 430 code · 65 blank · 84 comment · 0 complexity · c13d872901f58aea86490e3664c2bd09 MD5 · raw file

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