/thirdparty/breakpad/common/dwarf_line_to_module_unittest.cc

http://github.com/tomahawk-player/tomahawk · C++ · 343 lines · 235 code · 65 blank · 43 comment · 8 complexity · 3be950fb944e354501c38bc46c61d41a MD5 · raw file

  1. // Copyright (c) 2010 Google Inc.
  2. // 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. // dwarf_line_to_module.cc: Unit tests for google_breakpad::DwarfLineToModule.
  31. #include <vector>
  32. #include "breakpad_googletest_includes.h"
  33. #include "common/dwarf_line_to_module.h"
  34. using std::vector;
  35. using google_breakpad::DwarfLineToModule;
  36. using google_breakpad::Module;
  37. using google_breakpad::Module;
  38. TEST(SimpleModule, One) {
  39. Module m("name", "os", "architecture", "id");
  40. vector<Module::Line> lines;
  41. DwarfLineToModule h(&m, &lines);
  42. h.DefineFile("file1", 0x30bf0f27, 0, 0, 0);
  43. h.AddLine(0x6fd126fbf74f2680LL, 0x63c9a14cf556712bLL, 0x30bf0f27,
  44. 0x4c090cbf, 0x1cf9fe0d);
  45. vector<Module::File *> files;
  46. m.GetFiles(&files);
  47. EXPECT_EQ(1U, files.size());
  48. EXPECT_STREQ("file1", files[0]->name.c_str());
  49. EXPECT_EQ(1U, lines.size());
  50. EXPECT_EQ(0x6fd126fbf74f2680ULL, lines[0].address);
  51. EXPECT_EQ(0x63c9a14cf556712bULL, lines[0].size);
  52. EXPECT_TRUE(lines[0].file == files[0]);
  53. EXPECT_EQ(0x4c090cbf, lines[0].number);
  54. }
  55. TEST(SimpleModule, Many) {
  56. Module m("name", "os", "architecture", "id");
  57. vector<Module::Line> lines;
  58. DwarfLineToModule h(&m, &lines);
  59. h.DefineDir("directory1", 0x838299ab);
  60. h.DefineDir("directory2", 0xf85de023);
  61. h.DefineFile("file1", 0x2b80377a, 0x838299ab, 0, 0);
  62. h.DefineFile("file1", 0x63beb4a4, 0xf85de023, 0, 0);
  63. h.DefineFile("file2", 0x1d161d56, 0x838299ab, 0, 0);
  64. h.DefineFile("file2", 0x1e7a667c, 0xf85de023, 0, 0);
  65. h.AddLine(0x69900c5d553b7274ULL, 0x90fded183f0d0d3cULL, 0x2b80377a,
  66. 0x15b0f0a9U, 0x3ff5abd6U);
  67. h.AddLine(0x45811219a39b7101ULL, 0x25a5e6a924afc41fULL, 0x63beb4a4,
  68. 0x4d259ce9U, 0x41c5ee32U);
  69. h.AddLine(0xfa90514c1dc9704bULL, 0x0063efeabc02f313ULL, 0x1d161d56,
  70. 0x1ee9fa4fU, 0xbf70e46aU);
  71. h.AddLine(0x556b55fb6a647b10ULL, 0x3f3089ca2bfd80f5ULL, 0x1e7a667c,
  72. 0x77fc280eU, 0x2c4a728cU);
  73. h.DefineFile("file3", -1, 0, 0, 0);
  74. h.AddLine(0xe2d72a37f8d9403aULL, 0x034dfab5b0d4d236ULL, 0x63beb4a5,
  75. 0x75047044U, 0xb6a0016cU);
  76. vector<Module::File *> files;
  77. m.GetFiles(&files);
  78. ASSERT_EQ(5U, files.size());
  79. EXPECT_STREQ("directory1/file1", files[0]->name.c_str());
  80. EXPECT_STREQ("directory1/file2", files[1]->name.c_str());
  81. EXPECT_STREQ("directory2/file1", files[2]->name.c_str());
  82. EXPECT_STREQ("directory2/file2", files[3]->name.c_str());
  83. EXPECT_STREQ("file3", files[4]->name.c_str());
  84. ASSERT_EQ(5U, lines.size());
  85. EXPECT_EQ(0x69900c5d553b7274ULL, lines[0].address);
  86. EXPECT_EQ(0x90fded183f0d0d3cULL, lines[0].size);
  87. EXPECT_TRUE(lines[0].file == files[0]);
  88. EXPECT_EQ(0x15b0f0a9, lines[0].number);
  89. EXPECT_EQ(0x45811219a39b7101ULL, lines[1].address);
  90. EXPECT_EQ(0x25a5e6a924afc41fULL, lines[1].size);
  91. EXPECT_TRUE(lines[1].file == files[2]);
  92. EXPECT_EQ(0x4d259ce9, lines[1].number);
  93. EXPECT_EQ(0xfa90514c1dc9704bULL, lines[2].address);
  94. EXPECT_EQ(0x0063efeabc02f313ULL, lines[2].size);
  95. EXPECT_TRUE(lines[2].file == files[1]);
  96. EXPECT_EQ(0x1ee9fa4f, lines[2].number);
  97. EXPECT_EQ(0x556b55fb6a647b10ULL, lines[3].address);
  98. EXPECT_EQ(0x3f3089ca2bfd80f5ULL, lines[3].size);
  99. EXPECT_TRUE(lines[3].file == files[3]);
  100. EXPECT_EQ(0x77fc280e, lines[3].number);
  101. EXPECT_EQ(0xe2d72a37f8d9403aULL, lines[4].address);
  102. EXPECT_EQ(0x034dfab5b0d4d236ULL, lines[4].size);
  103. EXPECT_TRUE(lines[4].file == files[4]);
  104. EXPECT_EQ(0x75047044, lines[4].number);
  105. }
  106. TEST(Filenames, Absolute) {
  107. Module m("name", "os", "architecture", "id");
  108. vector<Module::Line> lines;
  109. DwarfLineToModule h(&m, &lines);
  110. h.DefineDir("directory1", 1);
  111. h.DefineFile("/absolute", 1, 1, 0, 0);
  112. h.AddLine(1, 1, 1, 0, 0);
  113. vector<Module::File *> files;
  114. m.GetFiles(&files);
  115. ASSERT_EQ(1U, files.size());
  116. EXPECT_STREQ("/absolute", files[0]->name.c_str());
  117. ASSERT_EQ(1U, lines.size());
  118. EXPECT_TRUE(lines[0].file == files[0]);
  119. }
  120. TEST(Filenames, Relative) {
  121. Module m("name", "os", "architecture", "id");
  122. vector<Module::Line> lines;
  123. DwarfLineToModule h(&m, &lines);
  124. h.DefineDir("directory1", 1);
  125. h.DefineFile("relative", 1, 1, 0, 0);
  126. h.AddLine(1, 1, 1, 0, 0);
  127. vector<Module::File *> files;
  128. m.GetFiles(&files);
  129. ASSERT_EQ(1U, files.size());
  130. EXPECT_STREQ("directory1/relative", files[0]->name.c_str());
  131. ASSERT_EQ(1U, lines.size());
  132. EXPECT_TRUE(lines[0].file == files[0]);
  133. }
  134. TEST(Filenames, StrangeFile) {
  135. Module m("name", "os", "architecture", "id");
  136. vector<Module::Line> lines;
  137. DwarfLineToModule h(&m, &lines);
  138. h.DefineDir("directory1", 1);
  139. h.DefineFile("", 1, 1, 0, 0);
  140. h.AddLine(1, 1, 1, 0, 0);
  141. ASSERT_EQ(1U, lines.size());
  142. EXPECT_STREQ("directory1/", lines[0].file->name.c_str());
  143. }
  144. TEST(Filenames, StrangeDirectory) {
  145. Module m("name", "os", "architecture", "id");
  146. vector<Module::Line> lines;
  147. DwarfLineToModule h(&m, &lines);
  148. h.DefineDir("", 1);
  149. h.DefineFile("file1", 1, 1, 0, 0);
  150. h.AddLine(1, 1, 1, 0, 0);
  151. ASSERT_EQ(1U, lines.size());
  152. EXPECT_STREQ("/file1", lines[0].file->name.c_str());
  153. }
  154. TEST(Filenames, StrangeDirectoryAndFile) {
  155. Module m("name", "os", "architecture", "id");
  156. vector<Module::Line> lines;
  157. DwarfLineToModule h(&m, &lines);
  158. h.DefineDir("", 1);
  159. h.DefineFile("", 1, 1, 0, 0);
  160. h.AddLine(1, 1, 1, 0, 0);
  161. ASSERT_EQ(1U, lines.size());
  162. EXPECT_STREQ("/", lines[0].file->name.c_str());
  163. }
  164. // We should silently ignore attempts to define directory number zero,
  165. // since that is always the compilation directory.
  166. TEST(ModuleErrors, DirectoryZero) {
  167. Module m("name", "os", "architecture", "id");
  168. vector<Module::Line> lines;
  169. DwarfLineToModule h(&m, &lines);
  170. h.DefineDir("directory0", 0); // should be ignored
  171. h.DefineFile("relative", 1, 0, 0, 0);
  172. h.AddLine(1, 1, 1, 0, 0);
  173. ASSERT_EQ(1U, lines.size());
  174. EXPECT_STREQ("relative", lines[0].file->name.c_str());
  175. }
  176. // We should refuse to add lines with bogus file numbers. We should
  177. // produce only one warning, however.
  178. TEST(ModuleErrors, BadFileNumber) {
  179. Module m("name", "os", "architecture", "id");
  180. vector<Module::Line> lines;
  181. DwarfLineToModule h(&m, &lines);
  182. h.DefineFile("relative", 1, 0, 0, 0);
  183. h.AddLine(1, 1, 2, 0, 0); // bad file number
  184. h.AddLine(2, 1, 2, 0, 0); // bad file number (no duplicate warning)
  185. EXPECT_EQ(0U, lines.size());
  186. }
  187. // We should treat files with bogus directory numbers as relative to
  188. // the compilation unit.
  189. TEST(ModuleErrors, BadDirectoryNumber) {
  190. Module m("name", "os", "architecture", "id");
  191. vector<Module::Line> lines;
  192. DwarfLineToModule h(&m, &lines);
  193. h.DefineDir("directory1", 1);
  194. h.DefineFile("baddirnumber1", 1, 2, 0, 0); // bad directory number
  195. h.DefineFile("baddirnumber2", 2, 2, 0, 0); // bad dir number (no warning)
  196. h.AddLine(1, 1, 1, 0, 0);
  197. ASSERT_EQ(1U, lines.size());
  198. EXPECT_STREQ("baddirnumber1", lines[0].file->name.c_str());
  199. }
  200. // We promise not to report empty lines.
  201. TEST(ModuleErrors, EmptyLine) {
  202. Module m("name", "os", "architecture", "id");
  203. vector<Module::Line> lines;
  204. DwarfLineToModule h(&m, &lines);
  205. h.DefineFile("filename1", 1, 0, 0, 0);
  206. h.AddLine(1, 0, 1, 0, 0);
  207. ASSERT_EQ(0U, lines.size());
  208. }
  209. // We are supposed to clip lines that extend beyond the end of the
  210. // address space.
  211. TEST(ModuleErrors, BigLine) {
  212. Module m("name", "os", "architecture", "id");
  213. vector<Module::Line> lines;
  214. DwarfLineToModule h(&m, &lines);
  215. h.DefineFile("filename1", 1, 0, 0, 0);
  216. h.AddLine(0xffffffffffffffffULL, 2, 1, 0, 0);
  217. ASSERT_EQ(1U, lines.size());
  218. EXPECT_EQ(1U, lines[0].size);
  219. }
  220. // The 'Omitted' tests verify that we correctly omit line information
  221. // for code in sections that the linker has dropped. See "GNU
  222. // toolchain omitted sections support" at the top of the
  223. // DwarfLineToModule class.
  224. TEST(Omitted, DroppedThenGood) {
  225. Module m("name", "os", "architecture", "id");
  226. vector<Module::Line> lines;
  227. DwarfLineToModule h(&m, &lines);
  228. h.DefineFile("filename1", 1, 0, 0, 0);
  229. h.AddLine(0, 10, 1, 83816211, 0); // should be omitted
  230. h.AddLine(20, 10, 1, 13059195, 0); // should be recorded
  231. ASSERT_EQ(1U, lines.size());
  232. EXPECT_EQ(13059195, lines[0].number);
  233. }
  234. TEST(Omitted, GoodThenDropped) {
  235. Module m("name", "os", "architecture", "id");
  236. vector<Module::Line> lines;
  237. DwarfLineToModule h(&m, &lines);
  238. h.DefineFile("filename1", 1, 0, 0, 0);
  239. h.AddLine(0x9dd6a372, 10, 1, 41454594, 0); // should be recorded
  240. h.AddLine(0, 10, 1, 44793413, 0); // should be omitted
  241. ASSERT_EQ(1U, lines.size());
  242. EXPECT_EQ(41454594, lines[0].number);
  243. }
  244. TEST(Omitted, Mix1) {
  245. Module m("name", "os", "architecture", "id");
  246. vector<Module::Line> lines;
  247. DwarfLineToModule h(&m, &lines);
  248. h.DefineFile("filename1", 1, 0, 0, 0);
  249. h.AddLine(0x679ed72f, 10, 1, 58932642, 0); // should be recorded
  250. h.AddLine(0xdfb5a72d, 10, 1, 39847385, 0); // should be recorded
  251. h.AddLine(0, 0x78, 1, 23053829, 0); // should be omitted
  252. h.AddLine(0x78, 0x6a, 1, 65317783, 0); // should be omitted
  253. h.AddLine(0x78 + 0x6a, 0x2a, 1, 77601423, 0); // should be omitted
  254. h.AddLine(0x9fe0cea5, 10, 1, 91806582, 0); // should be recorded
  255. h.AddLine(0x7e41a109, 10, 1, 56169221, 0); // should be recorded
  256. ASSERT_EQ(4U, lines.size());
  257. EXPECT_EQ(58932642, lines[0].number);
  258. EXPECT_EQ(39847385, lines[1].number);
  259. EXPECT_EQ(91806582, lines[2].number);
  260. EXPECT_EQ(56169221, lines[3].number);
  261. }
  262. TEST(Omitted, Mix2) {
  263. Module m("name", "os", "architecture", "id");
  264. vector<Module::Line> lines;
  265. DwarfLineToModule h(&m, &lines);
  266. h.DefineFile("filename1", 1, 0, 0, 0);
  267. h.AddLine(0, 0xf2, 1, 58802211, 0); // should be omitted
  268. h.AddLine(0xf2, 0xb9, 1, 78958222, 0); // should be omitted
  269. h.AddLine(0xf2 + 0xb9, 0xf7, 1, 64861892, 0); // should be omitted
  270. h.AddLine(0x4e4d271e, 9, 1, 67355743, 0); // should be recorded
  271. h.AddLine(0xdfb5a72d, 30, 1, 23365776, 0); // should be recorded
  272. h.AddLine(0, 0x64, 1, 76196762, 0); // should be omitted
  273. h.AddLine(0x64, 0x33, 1, 71066611, 0); // should be omitted
  274. h.AddLine(0x64 + 0x33, 0xe3, 1, 61749337, 0); // should be omitted
  275. ASSERT_EQ(2U, lines.size());
  276. EXPECT_EQ(67355743, lines[0].number);
  277. EXPECT_EQ(23365776, lines[1].number);
  278. }