debug_utils.h 9.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227
  1. /*************************************************************************/ /*!
  2. @File
  3. @Title Debug Utilities
  4. @Copyright Copyright (c) Imagination Technologies Ltd. All Rights Reserved
  5. @License Strictly Confidential.
  6. @Description Various debug helper functions
  7. This module adds functions for dumping stack traces to the client DDK. There
  8. are two sets of functions: native and non-native.
  9. The native functions use functions native to a specific operating system, e.g.:
  10. Android version uses android::CallStack class. Those functions in general should
  11. show more accurate stack traces than the non-native counterpart (this not always
  12. has to be true, e.g.: for Linux libunwind (non-native) in general yields better
  13. results than sacktrace() (native)).
  14. The non-native functions are based on libunwind and should show same results
  15. in different operating system (this is true for Android and Linux but not
  16. necessarily for other OSes). The results in most cases should be accurate
  17. enough.
  18. Downside to non-native approach is that not always is available in the system.
  19. For example starting from Android O it's not allowed to link to libunwind
  20. so the native functions have to be used in all cases.
  21. Native functions are enabled with PVRSRV_NEED_PVR_STACKTRACE_NATIVE compilation
  22. switch and non-native functions with PVRSRV_NEED_PVR_STACKTRACE.
  23. Usage examples:
  24. 1) Dump current stack trace to the stdout (or system log):
  25. a) native
  26. // dumps the current stack trace without first frame, and doesn't print
  27. // custom header
  28. PVRSRVNativeDumpStackTrace(1, NULL);
  29. b) non-native (libunwind)
  30. // dumps up to 25 frames of current stack while not including the first
  31. // frame, includes "Example stack trace" string in the stack trace header
  32. PVRSRVDumpStackTrace(1, 25, "Example stack trace");
  33. 2) Save current stack trace and print it somewhen later
  34. a) native
  35. // saves current stack trace and returns pointer to the allocated memory,
  36. // skips two first frames
  37. void *st = PVRSRVNativeSaveStackTrace(2);
  38. // prints the saves tack trace with generic header and frees the memory
  39. // (after this call 'sp' pointer should not be used)
  40. PVRSRVNativePrintStackTrace(st, NULL);
  41. b) non-native (libunwind)
  42. # define SKIP_FRAMES 2
  43. # define MAX_FRAMES 25
  44. // buffer used for storing the stack trace
  45. uintptr_t stack_trace[MAX_FRAMES];
  46. // saves up to 25 frames of current stack while not including the two first
  47. // frames
  48. PVRSRVSaveStackTrace(stack_trace, SKIP_FRAMES, MAX_FRAMES);
  49. // prints stack trace from 'stack_trace' buffer while not including
  50. // the two first frames, includes "Stack trace" string in the stack trace
  51. // header
  52. PVRSRVPrintStackTrace(stack_trace, SKIP_FRAMES, MAX_FRAMES, "Stack trace");
  53. */ /**************************************************************************/
  54. #ifndef _DEBUG_UTILS_H_
  55. #define _DEBUG_UTILS_H_
  56. #include "img_types.h"
  57. #include "img_defs.h"
  58. #ifdef __cplusplus
  59. extern "C" {
  60. #endif
  61. /* The PVRSRV_NEED_PVR_STACKTRACE_NATIVE=1 build option enables stack tracing that
  62. * requires functionality that is natively provided/allowed by the target
  63. * OS.
  64. */
  65. #if defined(PVRSRV_NEED_PVR_STACKTRACE_NATIVE)
  66. /** Prints stack trace.
  67. *
  68. * This is the platform dependent stack trace function.
  69. *
  70. * For Android it will use CallStack.h API which yields the best results when
  71. * it comes to printing complete stack trace. This function is able to resolve
  72. * symbols in most of the cases (sometimes even in release builds). For C++ it
  73. * even demangles the function names.
  74. *
  75. * In case of Linux execinfo.h API is used. This is not as good as Android's
  76. * API and sometimes not event as good as PVRSRVDumpStackTrace. The restriction
  77. * in case of this function is that the executable should be build with
  78. * -rdynamic linker option. If the linker option is not used in most of the
  79. * cases symbols will not be resolved.
  80. *
  81. * @param uiSkipFrames number of skipped top frames form the stack trace
  82. * @param pszHeader zero terminated string that will be included in a stack
  83. * trace header in a following way: "Call stack (%s):".
  84. * If pointer is NULL the " (%s)" part is omitted.
  85. */
  86. void PVRSRVNativeDumpStackTrace(size_t uiSkipFrames, const char *pszHeader);
  87. /** Saves stack trace.
  88. *
  89. * This function is similar to PVRSRVNativeDumpStackTrace but instead of
  90. * printing the stack trace it saves it and returns a pointer to the stack
  91. * trace. The stack trace is kept in internal format and can be printed
  92. * by PVRSRVNativePrintStackTrace.
  93. *
  94. * The pointer can point to heap memory and is freed once print function
  95. * is called. This means that it might not be reusable after the stack trace
  96. * is printed.
  97. *
  98. * @param uiSkipFrames number of skipped top frames form the stack trace
  99. * @return pointer to stack trace representation
  100. */
  101. void *PVRSRVNativeSaveStackTrace(size_t uiSkipFrames);
  102. /** Prints stack trace.
  103. *
  104. * Prints stack trace captured with PVRSRVNativeDumpStackTrace.
  105. *
  106. * The pointer pvStackTrace cannot be used again after this function is called.
  107. * It should be nulled and discarted after one use.
  108. *
  109. * @param pvStackTrace pointer to stack trace representation
  110. * @param pszHeader zero terminated string that will be included in a stack
  111. * trace header in a following way: "Call stack (%s):".
  112. * If pointer is NULL the " (%s)" part is omitted.
  113. */
  114. void PVRSRVNativePrintStackTrace(void *pvStackTrace, const char *pszHeader);
  115. #else /* defined(PVRSRV_NEED_PVR_STACKTRACE_NATIVE) */
  116. #define PVRSRVNativeDumpStackTrace(uiSkipFrames, pszHeader) \
  117. static_assert(0, "Please enable PVRSRV_NEED_PVR_STACKTRACE_NATIVE to use PVRSRVNativeDumpStackTrace")
  118. #define PVRSRVNativeSaveStackTrace(uiSkipFrames) \
  119. static_assert(0, "Please enable PVRSRV_NEED_PVR_STACKTRACE_NATIVE to use PVRSRVNativeSaveStackTrace")
  120. #define PVRSRVNativePrintStackTrace(pvStackTrace, pszHeader) \
  121. static_assert(0, "Please enable PVRSRV_NEED_PVR_STACKTRACE_NATIVE to use PVRSRVNativePrintStackTrace")
  122. #endif /* defined(PVRSRV_NEED_PVR_STACKTRACE_NATIVE) */
  123. /* The PVRSRV_NEED_PVR_STACKTRACE=1 build option enables stack
  124. * tracing that requires functionality that is either natively provided/allowed
  125. * by the target OS, OR requires hand-written code or additional dependencies.
  126. * If your OS needs to avoid additional dependencies, do not set this option.
  127. */
  128. #if defined(PVRSRV_NEED_PVR_STACKTRACE)
  129. /** Prints stack trace.
  130. *
  131. * This function uses libunwind to unwind the stack. This is the cross-platform
  132. * approach even though the library does not always work as expected.
  133. *
  134. * Known issue is that in Android M it doesn't resolve symbols at all. It should
  135. * be however possible to resolve them offline when binaries are available.
  136. * The trace will print offset of the symbol in the library/executable and
  137. * the name of the library/executable. Sometimes it will also print the symbol
  138. * itself if the dladdr was able to retrieve it.
  139. *
  140. * @param uiSkipFrames number of skipped top frames
  141. * @param uiMaxFrames number of printed frames in total (0 means all)
  142. * @param pszHeader zero terminated string that will be included in a stack
  143. * trace header in a following way: "Call stack (%s):".
  144. * If pointer is NULL the " (%s)" part is omitted.
  145. */
  146. void PVRSRVDumpStackTrace(size_t uiSkipFrames, size_t uiMaxFrames,
  147. const char *pszHeader);
  148. /** Saves stack trace in the array.
  149. *
  150. * This function is similar to PVRSRVDumpStackTrace but instead of printing
  151. * the stack trace it saves it to the given array (in a form of array of
  152. * program counter values).
  153. *
  154. * @param atCallStack buffer that should be large enough to fit either all
  155. * or uiMexFrmames (if given as not 0) unwound frames
  156. * @param uiSkipFrames number of skipped top frames
  157. * @param uiMaxFarmes maximum number of frames that should be unwind (0 means
  158. * all)
  159. * @return number of saved frames
  160. */
  161. size_t PVRSRVSaveStackTrace(uintptr_t puiCallStack[], size_t uiSkipFrames,
  162. size_t uiMaxFrames);
  163. /** Prints stack trace form the array.
  164. *
  165. * Prints stack trace captured with PVRSRVSaveStackTrace.
  166. *
  167. * @param atCallStack buffer with saved stack trace
  168. * @param uiSkipFrames number of skipped top frames
  169. * @param uiFramesCount number of frames returned by PVRSRVSaveStackTrace
  170. * @param pszHeader zero terminated string that will be included in a stack
  171. * trace header in a following way: "Call stack (%s):".
  172. * If pointer is NULL the " (%s)" part is omitted.
  173. */
  174. void PVRSRVPrintStackTrace(uintptr_t puiCallStack[], size_t uiSkipFrames,
  175. size_t uiFramesCount, const char *pszHeader);
  176. #else /* defined(PVRSRV_NEED_PVR_STACKTRACE) */
  177. #define PVRSRVDumpStackTrace(uiSkipFrames, uiMaxFrames, pszHeader) \
  178. static_assert(0, "Please enable PVRSRV_NEED_PVR_STACKTRACE to use PVRSRVDumpStackTrace")
  179. #define PVRSRVSaveStackTrace(puiCallStack, uiSkipFrames, uiMaxFrames) \
  180. static_assert(0, "Please enable PVRSRV_NEED_PVR_STACKTRACE to use PVRSRVSaveStackTrace")
  181. #define PVRSRVPrintStackTrace(puiCallStack, uiSkipFrames, uiFramesCount, pszHeader) \
  182. static_assert(0, "Please enable PVRSRV_NEED_PVR_STACKTRACE to use PVRSRVPrintStackTrace")
  183. #endif /* defined(PVRSRV_NEED_PVR_STACKTRACE) */
  184. #ifdef __cplusplus
  185. }
  186. #endif
  187. #endif /* _DEBUG_UTILS_H_ */