backtrace_offline_test.cpp 15 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397
  1. /*
  2. * Copyright (C) 2015 The Android Open Source Project
  3. *
  4. * Licensed under the Apache License, Version 2.0 (the "License");
  5. * you may not use this file except in compliance with the License.
  6. * You may obtain a copy of the License at
  7. *
  8. * http://www.apache.org/licenses/LICENSE-2.0
  9. *
  10. * Unless required by applicable law or agreed to in writing, software
  11. * distributed under the License is distributed on an "AS IS" BASIS,
  12. * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  13. * See the License for the specific language governing permissions and
  14. * limitations under the License.
  15. */
  16. #include <inttypes.h>
  17. #include <pthread.h>
  18. #include <stdint.h>
  19. #include <stdlib.h>
  20. #include <string.h>
  21. #include <functional>
  22. #include <memory>
  23. #include <string>
  24. #include <utility>
  25. #include <vector>
  26. #include <android-base/file.h>
  27. #include <android-base/logging.h>
  28. #include <android-base/macros.h>
  29. #include <android-base/stringprintf.h>
  30. #include <android-base/strings.h>
  31. #include <android-base/threads.h>
  32. #include <backtrace/Backtrace.h>
  33. #include <backtrace/BacktraceMap.h>
  34. #include <gtest/gtest.h>
  35. #include "BacktraceTest.h"
  36. struct FunctionSymbol {
  37. std::string name;
  38. uint64_t start;
  39. uint64_t end;
  40. };
  41. static std::vector<FunctionSymbol> GetFunctionSymbols() {
  42. std::vector<FunctionSymbol> symbols = {
  43. {"unknown_start", 0, 0},
  44. {"test_level_one", reinterpret_cast<uint64_t>(&BacktraceTest::test_level_one_), 0},
  45. {"test_level_two", reinterpret_cast<uint64_t>(&BacktraceTest::test_level_two_), 0},
  46. {"test_level_three", reinterpret_cast<uint64_t>(&BacktraceTest::test_level_three_), 0},
  47. {"test_level_four", reinterpret_cast<uint64_t>(&BacktraceTest::test_level_four_), 0},
  48. {"test_recursive_call", reinterpret_cast<uint64_t>(&BacktraceTest::test_recursive_call_), 0},
  49. {"test_get_context_and_wait",
  50. reinterpret_cast<uint64_t>(&BacktraceTest::test_get_context_and_wait_), 0},
  51. {"unknown_end", static_cast<uint64_t>(-1), static_cast<uint64_t>(-1)},
  52. };
  53. std::sort(
  54. symbols.begin(), symbols.end(),
  55. [](const FunctionSymbol& s1, const FunctionSymbol& s2) { return s1.start < s2.start; });
  56. for (size_t i = 0; i + 1 < symbols.size(); ++i) {
  57. symbols[i].end = symbols[i + 1].start;
  58. }
  59. return symbols;
  60. }
  61. static std::string RawDataToHexString(const void* data, size_t size) {
  62. const uint8_t* p = static_cast<const uint8_t*>(data);
  63. std::string s;
  64. for (size_t i = 0; i < size; ++i) {
  65. s += android::base::StringPrintf("%02x", p[i]);
  66. }
  67. return s;
  68. }
  69. static void HexStringToRawData(const char* s, std::vector<uint8_t>* data, size_t size) {
  70. for (size_t i = 0; i < size; ++i) {
  71. int value;
  72. sscanf(s, "%02x", &value);
  73. data->push_back(value);
  74. s += 2;
  75. }
  76. }
  77. struct OfflineThreadArg {
  78. std::vector<uint8_t> ucontext;
  79. pid_t tid;
  80. volatile int exit_flag;
  81. };
  82. static void* OfflineThreadFunc(void* arg) {
  83. OfflineThreadArg* fn_arg = reinterpret_cast<OfflineThreadArg*>(arg);
  84. fn_arg->tid = android::base::GetThreadId();
  85. BacktraceTest::test_get_context_and_wait_(&fn_arg->ucontext, &fn_arg->exit_flag);
  86. return nullptr;
  87. }
  88. std::string GetTestPath(const std::string& arch, const std::string& path) {
  89. return android::base::GetExecutableDirectory() + "/testdata/" + arch + '/' + path;
  90. }
  91. // This test is disable because it is for generating test data.
  92. TEST_F(BacktraceTest, DISABLED_generate_offline_testdata) {
  93. // Create a thread to generate the needed stack and registers information.
  94. const size_t stack_size = 16 * 1024;
  95. void* stack = mmap(NULL, stack_size, PROT_READ | PROT_WRITE, MAP_PRIVATE | MAP_ANONYMOUS, -1, 0);
  96. ASSERT_NE(MAP_FAILED, stack);
  97. uint64_t stack_addr = reinterpret_cast<uint64_t>(stack);
  98. pthread_attr_t attr;
  99. ASSERT_EQ(0, pthread_attr_init(&attr));
  100. ASSERT_EQ(0, pthread_attr_setstack(&attr, reinterpret_cast<void*>(stack), stack_size));
  101. pthread_t thread;
  102. OfflineThreadArg arg;
  103. arg.exit_flag = 0;
  104. ASSERT_EQ(0, pthread_create(&thread, &attr, OfflineThreadFunc, &arg));
  105. // Wait for the offline thread to generate the stack and context information.
  106. sleep(1);
  107. // Copy the stack information.
  108. std::vector<uint8_t> stack_data(reinterpret_cast<uint8_t*>(stack),
  109. reinterpret_cast<uint8_t*>(stack) + stack_size);
  110. arg.exit_flag = 1;
  111. ASSERT_EQ(0, pthread_join(thread, nullptr));
  112. ASSERT_EQ(0, munmap(stack, stack_size));
  113. std::unique_ptr<BacktraceMap> map(BacktraceMap::Create(getpid()));
  114. ASSERT_TRUE(map != nullptr);
  115. backtrace_stackinfo_t stack_info;
  116. stack_info.start = stack_addr;
  117. stack_info.end = stack_addr + stack_size;
  118. stack_info.data = stack_data.data();
  119. // Generate offline testdata.
  120. std::string testdata;
  121. // 1. Dump pid, tid
  122. testdata += android::base::StringPrintf("pid: %d tid: %d\n", getpid(), arg.tid);
  123. // 2. Dump maps
  124. for (auto it = map->begin(); it != map->end(); ++it) {
  125. const backtrace_map_t* entry = *it;
  126. testdata +=
  127. android::base::StringPrintf("map: start: %" PRIx64 " end: %" PRIx64 " offset: %" PRIx64
  128. " load_bias: %" PRIx64 " flags: %d name: %s\n",
  129. entry->start, entry->end, entry->offset, entry->load_bias,
  130. entry->flags, entry->name.c_str());
  131. }
  132. // 3. Dump ucontext
  133. testdata += android::base::StringPrintf("ucontext: %zu ", arg.ucontext.size());
  134. testdata += RawDataToHexString(arg.ucontext.data(), arg.ucontext.size());
  135. testdata.push_back('\n');
  136. // 4. Dump stack
  137. testdata += android::base::StringPrintf(
  138. "stack: start: %" PRIx64 " end: %" PRIx64 " size: %zu ",
  139. stack_info.start, stack_info.end, stack_data.size());
  140. testdata += RawDataToHexString(stack_data.data(), stack_data.size());
  141. testdata.push_back('\n');
  142. // 5. Dump function symbols
  143. std::vector<FunctionSymbol> function_symbols = GetFunctionSymbols();
  144. for (const auto& symbol : function_symbols) {
  145. testdata +=
  146. android::base::StringPrintf("function: start: %" PRIx64 " end: %" PRIx64 " name: %s\n",
  147. symbol.start, symbol.end, symbol.name.c_str());
  148. }
  149. ASSERT_TRUE(android::base::WriteStringToFile(testdata, "offline_testdata"));
  150. }
  151. // Return the name of the function which matches the address. Although we don't know the
  152. // exact end of each function, it is accurate enough for the tests.
  153. static std::string FunctionNameForAddress(uint64_t addr,
  154. const std::vector<FunctionSymbol>& symbols) {
  155. for (auto& symbol : symbols) {
  156. if (addr >= symbol.start && addr < symbol.end) {
  157. return symbol.name;
  158. }
  159. }
  160. return "";
  161. }
  162. struct OfflineTestData {
  163. int pid;
  164. int tid;
  165. std::vector<backtrace_map_t> maps;
  166. std::vector<uint8_t> ucontext;
  167. backtrace_stackinfo_t stack_info;
  168. std::vector<uint8_t> stack;
  169. std::vector<FunctionSymbol> symbols;
  170. };
  171. bool ReadOfflineTestData(const std::string offline_testdata_path, OfflineTestData* testdata) {
  172. std::string s;
  173. if (!android::base::ReadFileToString(offline_testdata_path, &s)) {
  174. return false;
  175. }
  176. // Parse offline_testdata.
  177. std::vector<std::string> lines = android::base::Split(s, "\n");
  178. for (const auto& line : lines) {
  179. if (android::base::StartsWith(line, "pid:")) {
  180. sscanf(line.c_str(), "pid: %d tid: %d", &testdata->pid, &testdata->tid);
  181. } else if (android::base::StartsWith(line, "map:")) {
  182. testdata->maps.resize(testdata->maps.size() + 1);
  183. backtrace_map_t& map = testdata->maps.back();
  184. int pos;
  185. sscanf(line.c_str(),
  186. "map: start: %" SCNx64 " end: %" SCNx64 " offset: %" SCNx64 " load_bias: %" SCNx64
  187. " flags: %d name: %n",
  188. &map.start, &map.end, &map.offset, &map.load_bias, &map.flags, &pos);
  189. map.name = android::base::Trim(line.substr(pos));
  190. } else if (android::base::StartsWith(line, "ucontext:")) {
  191. size_t size;
  192. int pos;
  193. testdata->ucontext.clear();
  194. sscanf(line.c_str(), "ucontext: %zu %n", &size, &pos);
  195. HexStringToRawData(&line[pos], &testdata->ucontext, size);
  196. } else if (android::base::StartsWith(line, "stack:")) {
  197. size_t size;
  198. int pos;
  199. sscanf(line.c_str(),
  200. "stack: start: %" SCNx64 " end: %" SCNx64 " size: %zu %n",
  201. &testdata->stack_info.start, &testdata->stack_info.end, &size, &pos);
  202. CHECK_EQ(testdata->stack_info.end - testdata->stack_info.start, size);
  203. testdata->stack.clear();
  204. HexStringToRawData(&line[pos], &testdata->stack, size);
  205. testdata->stack_info.data = testdata->stack.data();
  206. } else if (android::base::StartsWith(line, "function:")) {
  207. testdata->symbols.resize(testdata->symbols.size() + 1);
  208. FunctionSymbol& symbol = testdata->symbols.back();
  209. int pos;
  210. sscanf(line.c_str(), "function: start: %" SCNx64 " end: %" SCNx64 " name: %n", &symbol.start,
  211. &symbol.end, &pos);
  212. symbol.name = line.substr(pos);
  213. }
  214. }
  215. return true;
  216. }
  217. static void BacktraceOfflineTest(std::string arch_str, const std::string& testlib_name) {
  218. const std::string testlib_path(GetTestPath(arch_str, testlib_name));
  219. const std::string offline_testdata_path(GetTestPath(arch_str, "offline_testdata"));
  220. OfflineTestData testdata;
  221. ASSERT_TRUE(ReadOfflineTestData(offline_testdata_path, &testdata)) << "Failed " << arch_str;
  222. // Fix path of libbacktrace_testlib.so.
  223. for (auto& map : testdata.maps) {
  224. if (map.name.find("libbacktrace_test.so") != std::string::npos) {
  225. map.name = testlib_path;
  226. }
  227. }
  228. Backtrace::ArchEnum arch;
  229. if (arch_str == "arm") {
  230. arch = Backtrace::ARCH_ARM;
  231. } else if (arch_str == "arm64") {
  232. arch = Backtrace::ARCH_ARM64;
  233. } else if (arch_str == "x86") {
  234. arch = Backtrace::ARCH_X86;
  235. } else if (arch_str == "x86_64") {
  236. arch = Backtrace::ARCH_X86_64;
  237. } else {
  238. abort();
  239. }
  240. std::unique_ptr<Backtrace> backtrace(Backtrace::CreateOffline(
  241. arch, testdata.pid, testdata.tid, testdata.maps, testdata.stack_info));
  242. ASSERT_TRUE(backtrace != nullptr) << "Failed " << arch_str;
  243. ASSERT_TRUE(backtrace->Unwind(0, testdata.ucontext.data())) << "Failed " << arch_str;
  244. // Collect pc values of the call stack frames.
  245. std::vector<uint64_t> pc_values;
  246. for (size_t i = 0; i < backtrace->NumFrames(); ++i) {
  247. pc_values.push_back(backtrace->GetFrame(i)->pc);
  248. }
  249. size_t test_one_index = 0;
  250. for (size_t i = 0; i < pc_values.size(); ++i) {
  251. if (FunctionNameForAddress(pc_values[i], testdata.symbols) == "test_level_one") {
  252. test_one_index = i;
  253. break;
  254. }
  255. }
  256. ASSERT_GE(test_one_index, 3u) << "Failed " << arch_str;
  257. ASSERT_EQ("test_level_one", FunctionNameForAddress(pc_values[test_one_index], testdata.symbols))
  258. << "Failed " << arch_str;
  259. ASSERT_EQ("test_level_two", FunctionNameForAddress(pc_values[test_one_index - 1], testdata.symbols))
  260. << "Failed " << arch_str;
  261. ASSERT_EQ("test_level_three",
  262. FunctionNameForAddress(pc_values[test_one_index - 2], testdata.symbols))
  263. << "Failed " << arch_str;
  264. ASSERT_EQ("test_level_four",
  265. FunctionNameForAddress(pc_values[test_one_index - 3], testdata.symbols))
  266. << "Failed " << arch_str;
  267. }
  268. // For now, these tests can only run on the given architectures.
  269. TEST_F(BacktraceTest, offline_eh_frame) {
  270. BacktraceOfflineTest("arm64", "libbacktrace_test_eh_frame.so");
  271. BacktraceOfflineTest("x86_64", "libbacktrace_test_eh_frame.so");
  272. }
  273. TEST_F(BacktraceTest, offline_debug_frame) {
  274. BacktraceOfflineTest("arm", "libbacktrace_test_debug_frame.so");
  275. BacktraceOfflineTest("x86", "libbacktrace_test_debug_frame.so");
  276. }
  277. TEST_F(BacktraceTest, offline_gnu_debugdata) {
  278. BacktraceOfflineTest("arm", "libbacktrace_test_gnu_debugdata.so");
  279. BacktraceOfflineTest("x86", "libbacktrace_test_gnu_debugdata.so");
  280. }
  281. TEST_F(BacktraceTest, offline_arm_exidx) {
  282. BacktraceOfflineTest("arm", "libbacktrace_test_arm_exidx.so");
  283. }
  284. static void LibUnwindingTest(const std::string& arch_str, const std::string& testdata_name,
  285. const std::string& testlib_name) {
  286. const std::string testlib_path(GetTestPath(arch_str, testlib_name));
  287. struct stat st;
  288. ASSERT_EQ(0, stat(testlib_path.c_str(), &st)) << "can't find testlib " << testlib_path;
  289. const std::string offline_testdata_path(GetTestPath(arch_str, testdata_name));
  290. OfflineTestData testdata;
  291. ASSERT_TRUE(ReadOfflineTestData(offline_testdata_path, &testdata));
  292. // Fix path of the testlib.
  293. for (auto& map : testdata.maps) {
  294. if (map.name.find(testlib_name) != std::string::npos) {
  295. map.name = testlib_path;
  296. }
  297. }
  298. Backtrace::ArchEnum arch;
  299. if (arch_str == "arm") {
  300. arch = Backtrace::ARCH_ARM;
  301. } else if (arch_str == "arm64") {
  302. arch = Backtrace::ARCH_ARM64;
  303. } else if (arch_str == "x86") {
  304. arch = Backtrace::ARCH_X86;
  305. } else if (arch_str == "x86_64") {
  306. arch = Backtrace::ARCH_X86_64;
  307. } else {
  308. ASSERT_TRUE(false) << "Unsupported arch " << arch_str;
  309. abort();
  310. }
  311. // Do offline backtrace.
  312. std::unique_ptr<Backtrace> backtrace(Backtrace::CreateOffline(
  313. arch, testdata.pid, testdata.tid, testdata.maps, testdata.stack_info));
  314. ASSERT_TRUE(backtrace != nullptr);
  315. ASSERT_TRUE(backtrace->Unwind(0, testdata.ucontext.data()));
  316. ASSERT_EQ(testdata.symbols.size(), backtrace->NumFrames());
  317. for (size_t i = 0; i < backtrace->NumFrames(); ++i) {
  318. std::string name = FunctionNameForAddress(backtrace->GetFrame(i)->rel_pc, testdata.symbols);
  319. ASSERT_EQ(name, testdata.symbols[i].name);
  320. }
  321. ASSERT_TRUE(backtrace->GetError().error_code == BACKTRACE_UNWIND_ERROR_ACCESS_MEM_FAILED ||
  322. backtrace->GetError().error_code == BACKTRACE_UNWIND_ERROR_MAP_MISSING ||
  323. backtrace->GetError().error_code == BACKTRACE_UNWIND_ERROR_REPEATED_FRAME);
  324. }
  325. // This test tests the situation that ranges of functions covered by .eh_frame and .ARM.exidx
  326. // overlap with each other, which appears in /system/lib/libart.so.
  327. TEST_F(BacktraceTest, offline_unwind_mix_eh_frame_and_arm_exidx) {
  328. LibUnwindingTest("arm", "offline_testdata_for_libart", "libart.so");
  329. }
  330. TEST_F(BacktraceTest, offline_debug_frame_with_load_bias) {
  331. LibUnwindingTest("arm", "offline_testdata_for_libandroid_runtime", "libandroid_runtime.so");
  332. }
  333. TEST_F(BacktraceTest, offline_try_armexidx_after_debug_frame) {
  334. LibUnwindingTest("arm", "offline_testdata_for_libGLESv2_adreno", "libGLESv2_adreno.so");
  335. }
  336. TEST_F(BacktraceTest, offline_cie_with_P_augmentation) {
  337. // Make sure we can unwind through functions with CIE entry containing P augmentation, which
  338. // makes unwinding library reading personality handler from memory. One example is
  339. // /system/lib64/libskia.so.
  340. LibUnwindingTest("arm64", "offline_testdata_for_libskia", "libskia.so");
  341. }
  342. TEST_F(BacktraceTest, offline_empty_eh_frame_hdr) {
  343. // Make sure we can unwind through libraries with empty .eh_frame_hdr section. One example is
  344. // /vendor/lib64/egl/eglSubDriverAndroid.so.
  345. LibUnwindingTest("arm64", "offline_testdata_for_eglSubDriverAndroid", "eglSubDriverAndroid.so");
  346. }
  347. TEST_F(BacktraceTest, offline_max_frames_limit) {
  348. // The length of callchain can reach 256 when recording an application.
  349. ASSERT_GE(MAX_BACKTRACE_FRAMES, 256);
  350. }