Keine Beschreibung
Du kannst nicht mehr als 25 Themen auswählen Themen müssen mit entweder einem Buchstaben oder einer Ziffer beginnen. Sie können Bindestriche („-“) enthalten und bis zu 35 Zeichen lang sein.

StackTrace.cpp 3.5KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128
  1. #include "il2cpp-config.h"
  2. #if IL2CPP_TARGET_ANDROID
  3. #include "os/StackTrace.h"
  4. #include "os/Image.h"
  5. #include <unwind.h>
  6. #include <dlfcn.h>
  7. #include <link.h>
  8. #include <pthread.h>
  9. #include <string.h>
  10. namespace il2cpp
  11. {
  12. namespace os
  13. {
  14. const int kMaxStackFrames = 128;
  15. namespace
  16. {
  17. extern "C" char end;
  18. uintptr_t s_BaseAddress;
  19. uintptr_t s_EndAddress;
  20. uintptr_t s_LibUnityBaseAddress;
  21. uintptr_t s_LibUnityEndAddress;
  22. pthread_once_t s_InitKnownSymbolInfoOnceFlag = PTHREAD_ONCE_INIT;
  23. static int
  24. libUnityLookupCallback(struct dl_phdr_info *info, size_t size, void *data)
  25. {
  26. int j;
  27. uintptr_t endAddr;
  28. // dlpi_name can have different values depending on Android OS:
  29. // Google Pixel 2 Android 10, dlpi_name will be "/data/app/com.unity.stopaskingforpackagename-uRHSDLXYA4cnHxyTNT30-g==/lib/arm/libunity.so"
  30. // Samsung GT-I9505 Android 5, dlpi_name will be "libunity.so"
  31. if (info->dlpi_name == NULL || strstr(info->dlpi_name, "libunity.so") == NULL)
  32. return 0;
  33. s_LibUnityBaseAddress = s_LibUnityEndAddress = info->dlpi_addr;
  34. for (j = 0; j < info->dlpi_phnum; j++)
  35. {
  36. endAddr = (uintptr_t)(((char*)info->dlpi_addr) + info->dlpi_phdr[j].p_vaddr + info->dlpi_phdr[j].p_memsz);
  37. if (s_LibUnityEndAddress < endAddr)
  38. s_LibUnityEndAddress = endAddr;
  39. }
  40. return 0;
  41. }
  42. static void InitKnownSymbolInfo()
  43. {
  44. s_BaseAddress = reinterpret_cast<uintptr_t>(os::Image::GetImageBase());
  45. s_EndAddress = reinterpret_cast<uintptr_t>(&end);
  46. dl_iterate_phdr(libUnityLookupCallback, NULL);
  47. }
  48. static bool KnownSymbol(const uintptr_t addr)
  49. {
  50. pthread_once(&s_InitKnownSymbolInfoOnceFlag, &InitKnownSymbolInfo);
  51. if (addr >= s_BaseAddress && addr <= s_EndAddress)
  52. return true;
  53. if (addr >= s_LibUnityBaseAddress && addr <= s_LibUnityEndAddress)
  54. return true;
  55. return false;
  56. }
  57. struct AndroidStackTrace
  58. {
  59. size_t size;
  60. Il2CppMethodPointer addrs[kMaxStackFrames];
  61. bool PushStackFrameAddress(const uintptr_t addr)
  62. {
  63. if (size >= kMaxStackFrames)
  64. return false;
  65. addrs[size++] = reinterpret_cast<Il2CppMethodPointer>(addr);
  66. return true;
  67. }
  68. static _Unwind_Reason_Code Callback(struct _Unwind_Context* context, void* self)
  69. {
  70. const uintptr_t addr = _Unwind_GetIP(context);
  71. // Workaround to avoid crash when generating stack trace in some third-party libraries
  72. if (!KnownSymbol(addr))
  73. return _URC_END_OF_STACK;
  74. if (static_cast<AndroidStackTrace*>(self)->PushStackFrameAddress(addr))
  75. return _URC_NO_REASON;
  76. else
  77. return _URC_END_OF_STACK;
  78. }
  79. };
  80. }
  81. void StackTrace::WalkStackNative(WalkStackCallback callback, void* context, WalkOrder walkOrder)
  82. {
  83. AndroidStackTrace callstack = {};
  84. _Unwind_Backtrace(AndroidStackTrace::Callback, &callstack);
  85. for (size_t i = 0; i < callstack.size; ++i)
  86. {
  87. const size_t index = (walkOrder == kFirstCalledToLastCalled) ? (callstack.size - i - 1) : i;
  88. if (!callback(callstack.addrs[index], context))
  89. break;
  90. }
  91. }
  92. std::string StackTrace::NativeStackTrace()
  93. {
  94. return std::string();
  95. }
  96. const void* StackTrace::GetStackPointer()
  97. {
  98. return __builtin_frame_address(0);
  99. }
  100. }
  101. }
  102. #endif