Crasheye.hpp 15 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478
  1. #pragma once
  2. #ifdef _WIN32
  3. #include <Windows.h>
  4. #ifdef _DEBUG // is debug.
  5. #ifdef _WIN64 // is x64
  6. #define DUMPER_DLL L".\\CrasheyeD64.dll"
  7. #else // is x86
  8. #define DUMPER_DLL L".\\CrasheyeD.dll"
  9. #endif // _WIN64
  10. #else // is release.
  11. #ifdef _WIN64 // is x64
  12. #define DUMPER_DLL L".\\Crasheye64.dll"
  13. #else // is x86
  14. #define DUMPER_DLL L".\\Crasheye.dll"
  15. #endif // _WIN64
  16. #endif // _DEBUG
  17. namespace Crasheye
  18. {
  19. typedef void (*FnOnCrashCallback)(BOOL bCaptureSucceed, const char* cpszCrashReportFile);
  20. struct ApiHolder
  21. {
  22. enum DumpCommandType
  23. {
  24. enumDump_Begin = 0,
  25. enumDump_BackgroundExecutionFlag = enumDump_Begin, // 后台上传宕机信息(不显示DumpReport界面)
  26. enumDump_ForceUpload, // Dump是否强制上报(忽略玩家在DumpReport界面上的选择)
  27. enumDump_LogDirectory, // 设置log文件路径
  28. enumDump_CollectFile, // 设置需收集的文件名
  29. enumDump_LogDirectory_UTF8, // 设置log文件路径(传入参数为UTF8,Unity/UE 使用此参数)
  30. enumDump_CollectFile_UTF8, // 设置需收集的文件名(传入参数为UTF8,Unity/UE 使用此参数)
  31. enumDump_SetURL, // 设置上传url (internal_cn|internal_us|external|internal_oversea) => (国内|海外|外部项目)
  32. enumDump_SetBeta, // 设置 beta
  33. enumDump_SetUserIdentifier, // 设置 UserIdentifier
  34. enumDump_SetUserIdentifier_UTF8, // 设置 UserIdentifier(传入参数为UTF8,Unity/UE 使用此参数)
  35. enumDump_AddExtraData, // 添加额外数据
  36. enumDump_AddExtraData_UTF8, // 添加额外数据(传入参数为UTF8,Unity/UE 使用此参数)
  37. enumDump_leaveBreadcrumbType, // 设置面包屑传入字符串的格式
  38. enumDump_GM_TEST, // GM测试指令
  39. enumDump_Count
  40. };
  41. // 面包屑传入字符串的格式
  42. enum leaveBreadcrumbType
  43. {
  44. leaveBreadcrumbType_begin = 0,
  45. leaveBreadcrumbType_other = leaveBreadcrumbType_begin,
  46. leaveBreadcrumbType_ANSI,
  47. leaveBreadcrumbType_UTF8,
  48. leaveBreadcrumbType_count
  49. };
  50. typedef BOOL(*pfnInitDumperCrasheyeType)(const char* strAppkey, const char* strVersion, const char* strChannel, const BOOL bHookUnHandledExceptionFilter);
  51. typedef void (*pfnUnInitDumperType)();
  52. typedef BOOL(*pfnSetOnMiniDumpCreateCallBackType)(FnOnCrashCallback pCallback);
  53. typedef BOOL(*pfnSetConfigType)(const int nCommandType, const void* pArg);
  54. typedef BOOL(*pfnSendScriptExceptionType)(const char* strErrorTitle, const char* strStackTrace, const char* strLanguage);
  55. typedef LONG(*pfnHandleExceptionType)(EXCEPTION_POINTERS* pExceptionInfo);
  56. typedef BOOL(*pfnPushLogTraceType)(const char* cpszMessage);
  57. typedef void (*pfnleaveBreadcrumbType)(const char* cpszMessage);
  58. ApiHolder() :pInitFunction(nullptr), pfnSetOnMiniDumpCreateCallBack(nullptr), pfnSetConfig(nullptr), pUnInitFunction(nullptr), pfnSendScriptException(nullptr)
  59. , pfnHandleException(nullptr), pfnPushLogTrace(nullptr),pfnleaveBreadcrumb(nullptr)
  60. {
  61. hDumper = LoadLibraryW(DUMPER_DLL);
  62. if (hDumper)
  63. {
  64. pInitFunction = (pfnInitDumperCrasheyeType)::GetProcAddress(hDumper, "InitDumperCrasheye");
  65. pfnSetOnMiniDumpCreateCallBack = (pfnSetOnMiniDumpCreateCallBackType)::GetProcAddress(hDumper, "SetOnMiniDumpCreateCallBack");
  66. pfnSetConfig = (pfnSetConfigType)::GetProcAddress(hDumper, "SetConfig");
  67. pUnInitFunction = (pfnUnInitDumperType)::GetProcAddress(hDumper, "UnInitDumper");
  68. pfnSendScriptException = (pfnSendScriptExceptionType)::GetProcAddress(hDumper, "SendScriptException");
  69. pfnHandleException = (pfnHandleExceptionType)::GetProcAddress(hDumper, "HandleException");
  70. pfnPushLogTrace = (pfnPushLogTraceType)::GetProcAddress(hDumper, "PushLogTrace");
  71. pfnleaveBreadcrumb = (pfnleaveBreadcrumbType)::GetProcAddress(hDumper, "leaveBreadcrumb");
  72. }
  73. }
  74. ~ApiHolder()
  75. {
  76. if (hDumper)
  77. {
  78. if (pUnInitFunction)
  79. {
  80. pUnInitFunction();
  81. pUnInitFunction = nullptr;
  82. }
  83. FreeLibrary(hDumper);
  84. hDumper = NULL;
  85. }
  86. }
  87. HMODULE hDumper;
  88. pfnInitDumperCrasheyeType pInitFunction;
  89. pfnSetOnMiniDumpCreateCallBackType pfnSetOnMiniDumpCreateCallBack;
  90. pfnSetConfigType pfnSetConfig;
  91. pfnUnInitDumperType pUnInitFunction;
  92. pfnSendScriptExceptionType pfnSendScriptException;
  93. pfnHandleExceptionType pfnHandleException;
  94. pfnPushLogTraceType pfnPushLogTrace;
  95. pfnleaveBreadcrumbType pfnleaveBreadcrumb;
  96. };
  97. // The non-static inline function declaration refers to the same function in every translation unit (source file) that uses it.
  98. inline ApiHolder* get_api()
  99. {
  100. static ApiHolder s_api;
  101. return &s_api;
  102. }
  103. /**
  104. * 初始化 CrasheyeSdk.
  105. *
  106. * 崩溃收集相关的(如设置SEH,VEH等)一系列初始化操作.
  107. *
  108. * 本接口调用后会产生一条报活信息, 如需设置 url,
  109. * 请先调用 SetURL, 再调用本接口.
  110. *
  111. * @param strAppkey 平台申请的当前应用 appkey
  112. * @param strVersion 应用当前版本号
  113. * @param strChannel 应用的渠道号
  114. * @return 是否成功初始化
  115. */
  116. inline BOOL Init(const char* strAppkey, const char* strVersion, const char* strChannel, const BOOL bHookUnHandledExceptionFilter = FALSE)
  117. {
  118. if (get_api()->pInitFunction)
  119. {
  120. return get_api()->pInitFunction(strAppkey, strVersion, strChannel, bHookUnHandledExceptionFilter);
  121. }
  122. return FALSE;
  123. }
  124. /**
  125. * 反初始化 CrasheyeSdk.
  126. *
  127. * 释放 Init 阶段注册的异常处理器.
  128. * 在程序正常退出时调用.
  129. *
  130. */
  131. inline void UnInit()
  132. {
  133. if (get_api()->pUnInitFunction)
  134. {
  135. get_api()->pUnInitFunction();
  136. }
  137. }
  138. /**
  139. * 设置上报路径.
  140. *
  141. * 目前支持 3 种路径
  142. * internal_cn => 国内自研项目
  143. * internal_us => 海外自研项目
  144. * external => 外部项目
  145. *
  146. * 若不设置, 默认是 external
  147. *
  148. * 若要设置, 建议在 Init 之前调用.
  149. *
  150. * @param szUrl internal_cn/internal_us/external 三选一.
  151. * @return 是否成功设置
  152. */
  153. inline BOOL SetURL(const char* szUrl)
  154. {
  155. if (get_api()->pfnSetConfig)
  156. {
  157. return get_api()->pfnSetConfig(ApiHolder::enumDump_SetURL, szUrl);
  158. }
  159. return FALSE;
  160. }
  161. /**
  162. * 标记当前版本为调试版本
  163. *
  164. * 若要设置, 建议在 Init 之前调用.
  165. *
  166. * @return 是否成功设置
  167. */
  168. inline BOOL SetBeta()
  169. {
  170. if (get_api()->pfnSetConfig)
  171. {
  172. int dummy;
  173. return get_api()->pfnSetConfig(ApiHolder::enumDump_SetBeta, &dummy);
  174. }
  175. return FALSE;
  176. }
  177. /**
  178. * 设置用户id.
  179. *
  180. * @param szUserIdentifier 项目内部的用户id
  181. * @return 是否成功设置
  182. */
  183. inline BOOL SetUserIdentifier(const char* szUserIdentifier)
  184. {
  185. if (get_api()->pfnSetConfig)
  186. {
  187. return get_api()->pfnSetConfig(ApiHolder::enumDump_SetUserIdentifier, szUserIdentifier);
  188. }
  189. return FALSE;
  190. }
  191. /**
  192. * 设置用户id.
  193. * 传入参数为UTF8,Unity/UE 使用此参数
  194. *
  195. * @param szUserIdentifier 项目内部的用户id
  196. * @return 是否成功设置
  197. */
  198. inline BOOL SetUserIdentifier_UTF8(const char* szUserIdentifier)
  199. {
  200. if (get_api()->pfnSetConfig)
  201. {
  202. return get_api()->pfnSetConfig(ApiHolder::enumDump_SetUserIdentifier_UTF8, szUserIdentifier);
  203. }
  204. return FALSE;
  205. }
  206. /**
  207. * 添加额外上报信息.
  208. *
  209. * 以键值对的形式添加额外信息, 添加的信息会被包含着崩溃报告中随报告一同上报.
  210. *
  211. * @param szKey 键
  212. * @param szValue 值
  213. * @return 是否成功添加
  214. */
  215. inline BOOL AddExtraData(const char* szKey, const char* szValue)
  216. {
  217. if (get_api()->pfnSetConfig)
  218. {
  219. const char* packed[2] = { szKey, szValue };
  220. return get_api()->pfnSetConfig(ApiHolder::enumDump_AddExtraData, packed);
  221. }
  222. return FALSE;
  223. }
  224. /**
  225. * 添加额外上报信息.
  226. *
  227. * 传入参数为UTF8,Unity/UE 使用此参数
  228. *
  229. * 以键值对的形式添加额外信息, 添加的信息会被包含着崩溃报告中随报告一同上报.
  230. *
  231. * @param szKey 键
  232. * @param szValue 值
  233. * @return 是否成功添加
  234. */
  235. inline BOOL AddExtraData_UTF8(const char* szKey, const char* szValue)
  236. {
  237. if (get_api()->pfnSetConfig)
  238. {
  239. const char* packed[2] = { szKey, szValue };
  240. return get_api()->pfnSetConfig(ApiHolder::enumDump_AddExtraData_UTF8, packed);
  241. }
  242. return FALSE;
  243. }
  244. /**
  245. * 添加额外上报日志(文件).
  246. *
  247. * 添加的文件会被包含着崩溃报告中随报告一同上报.
  248. *
  249. * @param szCollectFile 需要额外收集的文件
  250. * @return 是否成功添加
  251. */
  252. inline BOOL AddCustomLog(const char* szCollectFile)
  253. {
  254. if (get_api()->pfnSetConfig)
  255. {
  256. return get_api()->pfnSetConfig(static_cast<int>(ApiHolder::enumDump_CollectFile), szCollectFile);
  257. }
  258. return FALSE;
  259. }
  260. /**
  261. * 添加额外上报日志(文件).
  262. *
  263. * 传入参数为UTF8,Unity/UE 使用此参数
  264. *
  265. * 添加的文件会被包含着崩溃报告中随报告一同上报.
  266. *
  267. * @param szCollectFile 需要额外收集的文件
  268. * @return 是否成功添加
  269. */
  270. inline BOOL AddCustomLog_UTF8(const char* szCollectFile)
  271. {
  272. if (get_api()->pfnSetConfig)
  273. {
  274. return get_api()->pfnSetConfig(static_cast<int>(ApiHolder::enumDump_CollectFile_UTF8), szCollectFile);
  275. }
  276. return FALSE;
  277. }
  278. /**
  279. * 添加自定义日志文件夹.
  280. *
  281. * 最新的log文件会被包含着崩溃报告中随报告一同上报.
  282. *
  283. * @param szCollectLogDirectory 需要收集的自定义log文件夹
  284. * @return 是否成功添加
  285. */
  286. inline BOOL AddCustomLogDirectory(const char* szCollectLogDirectory)
  287. {
  288. if (get_api()->pfnSetConfig)
  289. {
  290. return get_api()->pfnSetConfig(static_cast<int>(ApiHolder::enumDump_LogDirectory), szCollectLogDirectory);
  291. }
  292. return FALSE;
  293. }
  294. /**
  295. * 添加自定义日志文件夹.
  296. *
  297. * * 传入参数为UTF8,Unity/UE 使用此参数
  298. *
  299. * 最新的log文件会被包含着崩溃报告中随报告一同上报.
  300. *
  301. * @param szCollectLogDirectory 需要收集的自定义log文件夹
  302. * @return 是否成功添加
  303. */
  304. inline BOOL AddCustomLogDirectory_UTF8(const char* szCollectLogDirectory)
  305. {
  306. if (get_api()->pfnSetConfig)
  307. {
  308. return get_api()->pfnSetConfig(static_cast<int>(ApiHolder::enumDump_LogDirectory_UTF8), szCollectLogDirectory);
  309. }
  310. return FALSE;
  311. }
  312. /**
  313. * 设置Dump是否强制上报(忽略玩家在DumpReport界面上的选择)
  314. *
  315. * 若要设置, 建议在 Init 之前调用.
  316. *
  317. * @param isForceUpload 是否设置Dump强制上报
  318. * @return 是否成功设置
  319. */
  320. inline BOOL SetForceUpload(BOOL isForceUpload)
  321. {
  322. if (get_api()->pfnSetConfig)
  323. {
  324. return get_api()->pfnSetConfig(ApiHolder::enumDump_ForceUpload, &isForceUpload);
  325. }
  326. return FALSE;
  327. }
  328. /**
  329. * 设置Dump是否后台上报(不弹出DumpReport界面)
  330. *
  331. * 若要设置, 建议在 Init 之前调用.
  332. *
  333. * @param isBackgroundUpload 是否设置Dump后台上报
  334. * @return 是否成功设置
  335. */
  336. inline BOOL SetBackgroundUpload(BOOL isBackgroundUpload)
  337. {
  338. if (get_api()->pfnSetConfig)
  339. {
  340. return get_api()->pfnSetConfig(ApiHolder::enumDump_BackgroundExecutionFlag, &isBackgroundUpload);
  341. }
  342. return FALSE;
  343. }
  344. /**
  345. * 设置崩溃回调
  346. *
  347. * 设置崩溃发生时的回调, 回调会在报告文件写入完成后被调用.
  348. * 回调函数签名为
  349. * void(*FnOnCrashCallback)(BOOL bCaptureSucceed, const char* cpszCrashReportFile);
  350. * // @param bCaptureSucceed 是否成功捕获
  351. * // @param cpszCrashReportFile 报告文件名
  352. *
  353. * 注意: 回调发生时报告文件已经生成, 此时再调用 AddExtraData 和 AddCustomLog 添加的内
  354. * 容, 不会被加到报告中. 如果想崩溃发生时添加信息, 可以在初始化时调用
  355. * AddCustomLog("after_crash.log")
  356. * 然后在回调中, 把信息写入 after_crash.log
  357. *
  358. * @param szCollectFile 需要额外收集的文件
  359. * @return 是否成功添加
  360. */
  361. inline BOOL SetCrashCallback(FnOnCrashCallback pCallback)
  362. {
  363. if (get_api()->pfnSetOnMiniDumpCreateCallBack)
  364. {
  365. return get_api()->pfnSetOnMiniDumpCreateCallBack(pCallback);
  366. }
  367. return FALSE;
  368. }
  369. /**
  370. * 发送脚本异常
  371. *
  372. * @param errorTitle 错误的标题
  373. * @param stacktrace 异常的详细内容
  374. * @param language 脚本语言
  375. * @return 是否成功设置
  376. */
  377. inline BOOL SendScriptException(const char* strErrorTitle, const char* strStackTrace, const char* strLanguage)
  378. {
  379. if (get_api()->pfnSendScriptException)
  380. {
  381. return get_api()->pfnSendScriptException(strErrorTitle, strStackTrace, strLanguage);
  382. }
  383. return FALSE;
  384. }
  385. /**
  386. * 处理系统的异常指针
  387. *(此指针指向的结构体包含与计算机无关的异常说明和异常发生时处理器状态的特定于处理器的说明)
  388. * @param ExceptionInfo
  389. * @return 是否成功设置
  390. */
  391. inline BOOL OnCrashCallback(LPEXCEPTION_POINTERS ExceptionInfo)
  392. {
  393. if (get_api()->pfnHandleException)
  394. {
  395. return get_api()->pfnHandleException(ExceptionInfo);
  396. }
  397. return FALSE;
  398. }
  399. /**
  400. * 推送log信息流给dump模块(宕机时会写到dumper日志中)
  401. *
  402. * @param cpszMessage log信息流
  403. * @return 是否成功设置
  404. */
  405. inline BOOL PushLogTrace(const char* cpszMessage)
  406. {
  407. if (get_api()->pfnPushLogTrace)
  408. {
  409. return get_api()->pfnPushLogTrace(cpszMessage);
  410. }
  411. return FALSE;
  412. }
  413. /**
  414. * 推送面包屑信息流给dump模块(一般用于记录加载地图的信息域顺序)
  415. *
  416. * @param cpszMessage 面包屑信息流
  417. * @return 无返回值
  418. * 使用前必需调用SetConfig对enumDump_leaveBreadcrumbType进行设置
  419. *
  420. */
  421. inline void leaveBreadcrumb(const char* cpszMessage)
  422. {
  423. if (get_api()->pfnleaveBreadcrumb)
  424. {
  425. return get_api()->pfnleaveBreadcrumb(cpszMessage);
  426. }
  427. }
  428. /**
  429. * 推送自定义的配置信息流给dump模块
  430. *
  431. * @param nCommandType 要设置的Crasheye配置选项
  432. * @param pArg 要设置的Crasheye配置选项的值
  433. * @return 是否成功设置
  434. */
  435. inline BOOL setConfig(const int nCommandType, const void* pArg)
  436. {
  437. if (get_api()->pfnSetConfig)
  438. {
  439. return get_api()->pfnSetConfig(nCommandType, pArg);
  440. }
  441. return FALSE;
  442. }
  443. }
  444. #endif // _WIN32