SpBase.cpp 27 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941
  1. #include "stdafx.h"
  2. #include "version.h"
  3. #include "SpBase.h"
  4. #include <base64File.hpp>
  5. #include "SpTimer.h"
  6. #include "SpEntity.h"
  7. #include "SpModule.h"
  8. #include "RVCEventCode.h"
  9. #ifdef WIN32
  10. #include "SpBaseRoutine.h"
  11. #endif
  12. #include "SpMisc.h"
  13. #include "SpClientSessionFunction.h"
  14. #include "sockutil.h"
  15. #include "fileutil.h"
  16. #include "memutil.h"
  17. #include "dbgutil.h"
  18. #include "sp_shm.h"
  19. #include "sp_dbg_export.h"
  20. #include "sp_def.h"
  21. #include "sp_env.h"
  22. #include "DumpException.h"
  23. #ifdef RVC_OS_WIN
  24. #include "sp_checkEntity.h"
  25. #pragma comment(lib, "dbghelp.lib")
  26. #include <DbgHelp.h>
  27. #else
  28. #include <exception>
  29. #include <RestfulFunc.h>
  30. #endif // RVC_OS_WIN
  31. #include "SpSecureClient.h"
  32. #include "IHttpFunc.h"
  33. #include<winpr/library.h>
  34. #include <winpr/locale.h>
  35. #include <winpr/exception.h>
  36. #ifndef RVC_OS_WIN
  37. static SpModule* g_module = NULL;
  38. #endif //NOT RVC_OS_WIN
  39. SpModule *GetSpModule()
  40. {
  41. #ifdef RVC_OS_WIN
  42. SpModule *curModule = NULL;
  43. if (findThreadModule(GetCurrentThreadId(), (void **)&curModule))
  44. return curModule;
  45. else
  46. {
  47. CSimpleStringA mod_name = TraceStack();
  48. if (CSimpleStringA("") == mod_name) {
  49. return NULL;
  50. }
  51. SetthreadGroup(GetCurrentThreadId(), mod_name);
  52. if (findThreadModule(GetCurrentThreadId(), (void**)&curModule))
  53. return curModule;
  54. }
  55. return NULL;
  56. #else
  57. return g_module;
  58. #endif //RVC_OS_WIN
  59. }
  60. #ifdef RVC_OS_WIN
  61. static LONG WINAPI SuppressError(struct _EXCEPTION_POINTERS* ExceptionInfo)
  62. {
  63. //get active ver
  64. char szIniPath[MAX_PATH] = { 0 };
  65. sp_version_t active_version = { 0 };
  66. auto rc = sp_dir_get_path(sp_get_env()->dir, SP_DIR_INSTALL_INI, NULL, szIniPath, MAX_PATH);
  67. TOOLKIT_ASSERT(rc == 0);
  68. sscanf(strrchr(sp_get_env()->dir->base_path, '\\') + 1, "%d.%d.%d.%d",
  69. &active_version.major, &active_version.minor, &active_version.revision, &active_version.build);
  70. std::string dmpFileStr;
  71. char tmp[MAX_PATH], tmpPath[MAX_PATH];
  72. GetModuleFileNameA(NULL, tmpPath, MAX_PATH);
  73. *strrchr(tmpPath, SPLIT_SLASH) = 0;
  74. *strrchr(tmpPath, SPLIT_SLASH) = 0;
  75. *strrchr(tmpPath, SPLIT_SLASH) = 0;
  76. *strrchr(tmpPath, SPLIT_SLASH) = 0;
  77. *strrchr(tmpPath, SPLIT_SLASH) = 0;
  78. wsprintfA(tmp, "%s\\rvc\\dmp\\expt.%d_%d_%d_%d.%s.%d.%d.log", tmpPath, active_version.major, active_version.minor
  79. , active_version.revision, active_version.build, GetSpModule() ? GetSpModule()->get_mod()->cfg->name : "", GetCurrentThreadId(), GetCurrentProcessId());
  80. HANDLE hLogFile = ::CreateFileA(tmp, GENERIC_WRITE, 0, NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL);
  81. if (hLogFile != INVALID_HANDLE_VALUE) {
  82. DumpExceptionInfo(ExceptionInfo, hLogFile);
  83. FlushFileBuffers(hLogFile);
  84. SetEndOfFile(hLogFile);
  85. CloseHandle(hLogFile);
  86. }
  87. wsprintfA(tmp, "%s\\rvc\\dmp\\expt.%d_%d_%d_%d.%s.%d.%d.dmp", tmpPath, active_version.major, active_version.minor
  88. , active_version.revision, active_version.build, GetSpModule() ? GetSpModule()->get_mod()->cfg->name : "", GetCurrentThreadId(), GetCurrentProcessId());
  89. HANDLE hDumpFile = CreateFileA( tmp, GENERIC_READ | GENERIC_WRITE, 0, NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL );
  90. if( ( hDumpFile != NULL ) && ( hDumpFile != INVALID_HANDLE_VALUE ) )
  91. {
  92. MINIDUMP_EXCEPTION_INFORMATION mdei;
  93. mdei.ThreadId = GetCurrentThreadId();
  94. mdei.ExceptionPointers = ExceptionInfo;
  95. mdei.ClientPointers = FALSE;
  96. MINIDUMP_TYPE mdt = MiniDumpWithIndirectlyReferencedMemory;
  97. BOOL rv = MiniDumpWriteDump( GetCurrentProcess(), GetCurrentProcessId(),
  98. hDumpFile, mdt, (ExceptionInfo != 0) ? &mdei : 0, 0, 0 );
  99. CloseHandle( hDumpFile );
  100. }
  101. DbgWithLink(LOG_LEVEL_WARN, LOG_TYPE_SYSTEM).setAPI(__FUNCTION__).setLogCode(ERR_ENTITY_EXCEPTION).setVtmCode(RTAERR_ENTITY_EXCEPTION)("exit entity exception, saveDmp, %s, detail:%d:%s"
  102. , tmp, dmpFileStr.length(), dmpFileStr.c_str());
  103. Sleep(1500);//wait until all log send
  104. ExitProcess(Error_Exception); // exit process to suppress reporting exception
  105. return EXCEPTION_EXECUTE_HANDLER;
  106. }
  107. #else
  108. #include <execinfo.h>
  109. static void HandleSignalCallback(int signalNo)
  110. {
  111. switch (signalNo) {
  112. case SIGSEGV:
  113. {
  114. DbgWithLink(LOG_LEVEL_ERROR, LOG_TYPE_SYSTEM)("=========>>> capture signal SIGSEGV <<<=========");
  115. void* l_buffer[512];
  116. char** l_ptrace;
  117. //char l_s8aBuff[128] = { 0x00 };
  118. //snprintf(l_s8aBuff, sizeof(l_s8aBuff), "cat /proc/%d/maps", getpid());
  119. //system(l_s8aBuff);
  120. //objdump -d libbacktrace.so > log.txt
  121. DbgWithLink(LOG_LEVEL_ERROR, LOG_TYPE_SYSTEM)("Dump stack start...");
  122. int size = backtrace(l_buffer, 512);
  123. l_ptrace = backtrace_symbols(l_buffer, size);
  124. if (NULL == l_ptrace) {
  125. DbgWithLink(LOG_LEVEL_ERROR, LOG_TYPE_SYSTEM)("backtrace_symbols");
  126. exit(1);
  127. }
  128. for (int i = 0; i < size; i++) {
  129. DbgWithLink(LOG_LEVEL_ERROR, LOG_TYPE_SYSTEM)(" [%02d] %s", i, l_ptrace[i]);
  130. }
  131. DbgWithLink(LOG_LEVEL_ERROR, LOG_TYPE_SYSTEM)("Dump stack end...");
  132. free(l_ptrace);
  133. exit(-1);
  134. break;
  135. }
  136. case SIGKILL:
  137. DbgWithLink(LOG_LEVEL_ERROR, LOG_TYPE_SYSTEM)("=========>>> capture signal SIGKILL <<<=========");
  138. break;
  139. case SIGTERM:
  140. DbgWithLink(LOG_LEVEL_ERROR, LOG_TYPE_SYSTEM)("=========>>> capture signal SIGTERM <<<=========");
  141. break;
  142. default:
  143. DbgWithLink(LOG_LEVEL_ERROR, LOG_TYPE_SYSTEM)("=========>>> capture signal %d <<<=========", signalNo);
  144. break;
  145. }
  146. return;
  147. }
  148. static LONG WINAPI SuppressError(struct _EXCEPTION_POINTERS* ExceptionInfo)
  149. {
  150. LONG result(0);
  151. #if 1
  152. struct sigaction siga;
  153. siga.sa_handler = HandleSignalCallback;
  154. siga.sa_flags = 0;
  155. sigemptyset(&siga.sa_mask);
  156. if (0 > sigaction(SIGSEGV, &siga, NULL)) {
  157. DbgWithLink(LOG_LEVEL_ERROR, LOG_TYPE_SYSTEM)("register signal 'SIGSEGV' failed! %s %d", strerror(errno), errno);
  158. result = -1;
  159. }
  160. //if (0 > sigaction(SIGTERM, &siga, NULL)) {
  161. // sp_dbg_error("register signal 'SIGTERM' failed! %s %d", strerror(errno), errno); result = -1;
  162. //}
  163. //if (0 > sigaction(SIGKILL, &siga, NULL)) {
  164. // sp_dbg_error("register signal 'SIGKILL' failed! %d", errno); result = -1;
  165. //}
  166. #endif
  167. return result;
  168. }
  169. #endif //RVC_OS_WIN
  170. SPBASE_API void GetLibVersion(CVersion& version)
  171. {
  172. CVersion ver(VER_Major, VER_Minor, VER_Revision, VER_Build);
  173. version = ver;
  174. }
  175. SPBASE_API LPCSTR GetLibBuildDate()
  176. {
  177. #if defined(WITH_DEBUG)
  178. static char buildDate[] = __DATE__ " " __TIME__ " Debug";
  179. #elif defined(WITH_NO_DEBUG)
  180. static char buildDate[] = __DATE__ " " __TIME__ " Release";
  181. #else
  182. static char buildDate[] = __DATE__ " " __TIME__;
  183. #endif // WITH_DEBUG
  184. return buildDate;
  185. }
  186. SPBASE_API void LogEvent(const SeverityLevelEnum eLevel,DWORD dwUserEventCode,const char *pszMessage)
  187. {//MAX string len < 1024
  188. SpModule *pModule = GetSpModule();
  189. if (pModule) {
  190. pModule->LogMessage(Log_Event, eLevel, 0, dwUserEventCode, pszMessage);
  191. }
  192. // write a copy in dbg log
  193. DbgWithLink(LOG_LEVEL_DEBUG, LOG_TYPE_SYSTEM).setAPI(__FUNCTION__).setVtmCode(DWORD2Hex(dwUserEventCode).GetData())
  194. ("Event: {%s}(uc=0x%X)", pszMessage, dwUserEventCode);
  195. }
  196. SPBASE_API void LogError(const SeverityLevelEnum eLevel, ErrorCodeEnum dwSysErrorCode,DWORD dwUserErrorCode,const char *pszMessage)
  197. {
  198. SpModule *pModule = GetSpModule();
  199. if (pModule) {
  200. pModule->LogMessage(Log_Error, eLevel, dwSysErrorCode, dwUserErrorCode, pszMessage);
  201. }
  202. else {
  203. DbgWithLink(LOG_LEVEL_ERROR, LOG_TYPE_SYSTEM).setAPI(__FUNCTION__)("LogError failed!can not find the module");
  204. }
  205. // write a copy in dbg log
  206. DbgWithLink(LOG_LEVEL_ERROR, LOG_TYPE_SYSTEM).setAPI(__FUNCTION__).setVtmCode(DWORD2Hex(dwUserErrorCode).GetData())
  207. ("Error: {%s}(sc=0x%X, uc=0x%X)", pszMessage, dwSysErrorCode, dwUserErrorCode);
  208. }
  209. SPBASE_API void LogFatal(const SeverityLevelEnum eLevel, ErrorCodeEnum dwSysErrorCode, DWORD dwUserErrorCode, const char* pszMessage)
  210. {
  211. SpModule* pModule = GetSpModule();
  212. if (pModule) {
  213. pModule->LogMessage(Log_Fatal, eLevel, dwSysErrorCode, dwUserErrorCode, pszMessage);
  214. } else
  215. sp_dbg_info("LogFatal failed!can not find the module");
  216. DbgWithLink(LOG_LEVEL_FATAL, LOG_TYPE_SYSTEM).setAPI(__FUNCTION__).setVtmCode(DWORD2Hex(dwUserErrorCode).GetData())
  217. ("Fatal: {%s}(sc=0x%X, uc=0x%X)", pszMessage, dwSysErrorCode, dwUserErrorCode);
  218. }
  219. SPBASE_API void LogNotify(const NotifyLevelEnum eLevel, ErrorCodeEnum dwSysErrorCode, DWORD dwUserErrorCode, const char* pszMessage)
  220. {
  221. SpModule* pModule = GetSpModule();
  222. if (pModule) {
  223. const SeverityLevelEnum severityLevel = (SeverityLevelEnum)(int)eLevel;
  224. pModule->LogMessage(Log_Notify, severityLevel, dwSysErrorCode, dwUserErrorCode, pszMessage);
  225. } else {
  226. sp_dbg_info("LogNotify failed!can not find the module");
  227. }
  228. switch (eLevel) {
  229. case Notify_Info:
  230. DbgWithLink(LOG_LEVEL_INFO, LOG_TYPE_SYSTEM).setAPI(__FUNCTION__).setVtmCode(DWORD2Hex(dwUserErrorCode).GetData())
  231. ("Notify: {%s}(sc=0x%X, uc=0x%X)", pszMessage, dwSysErrorCode, dwUserErrorCode);
  232. break;
  233. case Notify_Warn:
  234. DbgWithLink(LOG_LEVEL_WARN, LOG_TYPE_SYSTEM).setAPI(__FUNCTION__).setVtmCode(DWORD2Hex(dwUserErrorCode).GetData())
  235. ("Notify: {%s}(sc=0x%X, uc=0x%X)", pszMessage, dwSysErrorCode, dwUserErrorCode);
  236. break;
  237. case Notify_Error:
  238. DbgWithLink(LOG_LEVEL_ERROR, LOG_TYPE_SYSTEM).setAPI(__FUNCTION__).setVtmCode(DWORD2Hex(dwUserErrorCode).GetData())
  239. ("Notify: {%s}(sc=0x%X, uc=0x%X)", pszMessage, dwSysErrorCode, dwUserErrorCode);
  240. break;
  241. default:
  242. DbgWithLink(LOG_LEVEL_FATAL, LOG_TYPE_SYSTEM).setAPI(__FUNCTION__).setVtmCode(DWORD2Hex(dwUserErrorCode).GetData())
  243. ("Notify: {%s}(sc=0x%X, uc=0x%X)", pszMessage, dwSysErrorCode, dwUserErrorCode);
  244. break;
  245. }
  246. }
  247. SPBASE_API void LogWarn(const SeverityLevelEnum eLevel, ErrorCodeEnum dwSysErrorCode,DWORD dwUserErrorCode, const char *pszMessage)
  248. {
  249. SpModule *pModule = GetSpModule();
  250. if (pModule) {
  251. pModule->LogMessage(Log_Warning, eLevel, dwSysErrorCode, dwUserErrorCode, pszMessage);
  252. }
  253. // write a copy in dbg log
  254. DbgWithLink(eLevel == Severity_Low ? LOG_LEVEL_INFO : LOG_LEVEL_WARN, LOG_TYPE_SYSTEM).setAPI(__FUNCTION__).setVtmCode(DWORD2Hex(dwUserErrorCode).GetData())
  255. ("Warn: {%s}(sc=0x%X, uc=0x%X)", pszMessage, dwSysErrorCode, dwUserErrorCode);
  256. }
  257. SPBASE_API void LogAssert(const char *pszMessage,const char *pszFile,const int nLine)
  258. {
  259. SpModule *pModule = GetSpModule();
  260. if (pModule) {
  261. pModule->LogMessage(Log_Debug, Severity_Middle, 0, 0,
  262. CSimpleStringA::Format("assert fail: {%s}, file: {%s}, line: {%d}, stack: {%s}",
  263. pszMessage, _GetFileName(pszFile), nLine,
  264. #ifdef RVC_OS_WIN
  265. (const char*)DumpStack(2)
  266. #else
  267. "not implement, TODO:"
  268. #endif //RVC_OS_WIN
  269. ));
  270. }
  271. // write a copy in dbg log
  272. DbgWithLink(LOG_LEVEL_ERROR, LOG_TYPE_SYSTEM).setAPI(__FUNCTION__).setVtmCode(DWORD2Hex(ERR_ENTITY_ASSERT).GetData())("Assert fail: {%s}, file: {%s}, line: {%d}, stack: {%s}",
  273. pszMessage, _GetFileName(pszFile), nLine,
  274. #ifdef RVC_OS_WIN
  275. (const char*)DumpStack(2)
  276. #else
  277. "not implement, TODO:"
  278. #endif //RVC_OS_WIN
  279. );
  280. }
  281. SPBASE_API void LogTrace(const char *pszMessage,const char *pszFile,const int nLine)
  282. {
  283. SpModule *pModule = GetSpModule();
  284. if (pModule) {
  285. pModule->LogMessage(Log_Debug, Severity_None, 0, 0, pszMessage);
  286. }
  287. // write a copy in dbg log
  288. DbgWithLink(LOG_LEVEL_INFO, LOG_TYPE_SYSTEM).setAPI(__FUNCTION__)("Trace: {%s}, file: {%s}, line: {%d}", pszMessage, _GetFileName(pszFile), nLine);
  289. }
  290. SPBASE_API void LogEvent(const SeverityLevelEnum eLevel, DWORD dwUserEventCode, const char* pszMessage, const linkContext& t_context)
  291. {
  292. SpModule* pModule = GetSpModule();
  293. if (pModule) {
  294. pModule->LogMessage(Log_Event, eLevel, 0, dwUserEventCode, pszMessage, t_context);
  295. }
  296. // write a copy in dbg log
  297. DbgWithLink(LOG_LEVEL_DEBUG, LOG_TYPE_SYSTEM).setAPI(__FUNCTION__).setVtmCode(DWORD2Hex(dwUserEventCode).GetData())
  298. ("Event: {%s}(uc=0x%X)", pszMessage, dwUserEventCode);
  299. }
  300. SPBASE_API void LogError(const SeverityLevelEnum eLevel, ErrorCodeEnum dwSysErrorCode, DWORD dwUserErrorCode, const char* pszMessage, const linkContext& t_context)
  301. {
  302. SpModule* pModule = GetSpModule();
  303. if (pModule) {
  304. pModule->LogMessage(Log_Error, eLevel, dwSysErrorCode, dwUserErrorCode, pszMessage, t_context);
  305. }
  306. else {
  307. DbgWithLink(LOG_LEVEL_ERROR, LOG_TYPE_SYSTEM).setAPI(__FUNCTION__)("LogError failed!can not find the module");
  308. }
  309. // write a copy in dbg log
  310. DbgWithLink(LOG_LEVEL_ERROR, LOG_TYPE_SYSTEM).setAPI(__FUNCTION__).setVtmCode(DWORD2Hex(dwSysErrorCode).GetData())
  311. ("Error: {%s}(sc=0x%X, uc=0x%X)", pszMessage, dwSysErrorCode, dwUserErrorCode);
  312. }
  313. SPBASE_API void LogWarn(const SeverityLevelEnum eLevel, ErrorCodeEnum dwSysErrorCode, DWORD dwUserErrorCode, const char* pszMessage, const linkContext& t_context)
  314. {
  315. SpModule* pModule = GetSpModule();
  316. if (pModule) {
  317. pModule->LogMessage(Log_Warning, eLevel, dwSysErrorCode, dwUserErrorCode, pszMessage, t_context);
  318. }
  319. // write a copy in dbg log
  320. DbgWithLink(eLevel == Severity_Low ? LOG_LEVEL_INFO : LOG_LEVEL_WARN, LOG_TYPE_SYSTEM).setVtmCode(DWORD2Hex(dwUserErrorCode).GetData())
  321. ("Warn: {%s}(sc=0x%X, uc=0x%X)", pszMessage, dwSysErrorCode, dwUserErrorCode);
  322. }
  323. SPBASE_API void LogAssert(const char* pszMessage, const char* pszFile, const int nLine, const linkContext& t_context)
  324. {
  325. SpModule* pModule = GetSpModule();
  326. if (pModule) {
  327. pModule->LogMessage(Log_Debug, Severity_Middle, 0, 0,
  328. CSimpleStringA::Format("assert fail: {%s}, file: {%s}, line: {%d}, stack: {%s}",
  329. pszMessage, _GetFileName(pszFile), nLine,
  330. #ifdef _WIN32
  331. (const char*)DumpStack(2)
  332. #else
  333. "not implement, TODO:"
  334. #endif //_WIN32
  335. ), t_context);
  336. }
  337. // write a copy in dbg log
  338. DbgWithLink(LOG_LEVEL_ERROR, LOG_TYPE_SYSTEM).setAPI(__FUNCTION__).setVtmCode(DWORD2Hex(ERR_ENTITY_ASSERT).GetData())("Assert fail: {%s}, file: {%s}, line: {%d}, stack: {%s}",
  339. pszMessage, _GetFileName(pszFile), nLine,
  340. #ifdef _WIN32
  341. (const char*)DumpStack(2)
  342. #else
  343. "not implement, TODO:"
  344. #endif //_WIN32
  345. );
  346. }
  347. SPBASE_API void LogTrace(const char* pszMessage, const char* pszFile, const int nLine, const linkContext& t_context)
  348. {
  349. SpModule* pModule = GetSpModule();
  350. if (pModule) {
  351. pModule->LogMessage(Log_Debug, Severity_None, 0, 0, pszMessage, t_context);
  352. }
  353. // write a copy in dbg log
  354. DbgWithLink(LOG_LEVEL_DEBUG, LOG_TYPE_SYSTEM).setAPI(__FUNCTION__)("Trace: {%s}, file: {%s}, line: {%d}", pszMessage, _GetFileName(pszFile), nLine);
  355. }
  356. #include "log.h"
  357. #ifdef RVC_OS_LINUX
  358. SPBASE_API void SpGetToken(char* channelId, char* token)
  359. {
  360. sp_env_t* env = sp_get_env();
  361. if (NULL != env && NULL != env->cfg && NULL != env->cfg->shell_ini &&
  362. env->cfg->shell_ini->channelId != NULL && env->cfg->shell_ini->token != NULL)
  363. {
  364. snprintf(channelId, MAX_TOKEN_LEN, "%s", env->cfg->shell_ini->channelId);
  365. snprintf(token, MAX_TOKEN_LEN, "%s", env->cfg->shell_ini->token);
  366. }
  367. else if (NULL == env)
  368. DbgWithLink(LOG_LEVEL_DEBUG, LOG_TYPE_SYSTEM)("SpGetToken can not get token!env == NULL");
  369. else if (NULL == env->cfg)
  370. DbgWithLink(LOG_LEVEL_DEBUG, LOG_TYPE_SYSTEM)("SpGetToken can not get token!env->cfg == NULL");
  371. else if (NULL == env->cfg->shell_ini)
  372. DbgWithLink(LOG_LEVEL_DEBUG, LOG_TYPE_SYSTEM)("SpGetToken can not get token!env->cfg->shell_ini == NULL");
  373. else if (NULL == env->cfg->shell_ini->channelId)
  374. DbgWithLink(LOG_LEVEL_DEBUG, LOG_TYPE_SYSTEM)("SpGetToken can not get token!env->cfg->shell_ini->channelId == NULL");
  375. else if (NULL == env->cfg->shell_ini->token)
  376. DbgWithLink(LOG_LEVEL_DEBUG, LOG_TYPE_SYSTEM)("SpGetToken can not get token!env->cfg->shell_ini->token == NULL");
  377. }
  378. #endif
  379. extern "C" SPBASE_API void Dbg(const char *str, ...)
  380. {
  381. if (str == nullptr)
  382. return;
  383. va_list arg;
  384. va_start(arg, str);
  385. vDbg(str, arg);
  386. va_end(arg);
  387. }
  388. extern "C" SPBASE_API void vDbg(const char *str, va_list list)
  389. {
  390. int n = _vscprintf(str, list);
  391. if (n > 1024)
  392. n = 1024;
  393. char *buf = (char*)_alloca(n + 1);
  394. memset(buf, '\0', n + 1);
  395. /*write at most n bytes(including the terminating null byte '\0') to buf*/
  396. vsnprintf(buf, n + 1, str, list); // plus 1 to n, never changed code but the log lost one char [4/1/2020 16:25 Gifur]
  397. buf[n] = '\0';
  398. #if defined(_MSC_VER)
  399. sp_dbg_debugNoOut("Debug: {%s}", buf); //打印到文件
  400. #else
  401. sp_dbg_debug("Debug: {%s}", buf);
  402. #endif //_MSC_VER
  403. #ifdef RVC_OS_WIN
  404. SpModule* pModule = GetSpModule();
  405. if (pModule) {
  406. SpEntity* pEntity = (SpEntity*)(getEntityResource()->m_Entity);
  407. if (pEntity != NULL) {
  408. auto pEntCfg = pEntity->get_cfg_ent();
  409. if (pEntCfg != NULL)
  410. pEntity->LogMessage(Log_Debug, Severity_None, 0, 0, buf);
  411. }
  412. }
  413. #endif // RVC_OS_WIN
  414. }
  415. static bool RegistMain(HMODULE hModule,EntryRoutine Main, EntryRoutine Exit)
  416. {
  417. SpModule::SetEntryRoutine(Main, Exit);
  418. return true;
  419. }
  420. static HMODULE LoadModuleLibrary(sp_mod_t *mod)
  421. {
  422. sp_env_t *env = sp_get_env();
  423. char tmp[MAX_PATH];
  424. sp_dir_get_path(env->dir, SP_DIR_MODULE_BIN, mod->cfg->name, tmp, sizeof(tmp));
  425. DbgWithLink(LOG_LEVEL_DEBUG, LOG_TYPE_SYSTEM)("load module library: %s", tmp);
  426. return LoadLibraryA(tmp);
  427. }
  428. /*It seems never been used anywhere.*/
  429. SPBASE_API HINSTANCE SpLoadLibrary(const char *file)
  430. {
  431. sp_env_t *env = sp_get_env();
  432. if (env) {
  433. char tmp[MAX_PATH];
  434. sprintf(tmp, "%s" SPLIT_SLASH_STR "%s", env->dir->dep_path, file);
  435. return LoadLibraryA(tmp);
  436. } else {
  437. return NULL;
  438. }
  439. }
  440. /*only sphost would invoke it.*/
  441. extern "C" SPBASE_API int __stdcall SpExit(const char* mod_name)
  442. {
  443. #ifdef RVC_OS_WIN
  444. DbgWithLink(LOG_LEVEL_DEBUG, LOG_TYPE_SYSTEM).setAPI(__FUNCTION__)("Do SpExit!");
  445. SetthreadGroup(GetCurrentThreadId(), mod_name);
  446. CleanModuleThread(mod_name);
  447. sp_iom_stop(GetSpModule()->get_iom());
  448. GetSpModule()->Term();
  449. sp_shm_term();
  450. sp_dbg_term();
  451. sp_iom_destroy(GetSpModule()->get_iom());
  452. delete GetSpModule();
  453. //winsock_term();
  454. FreeLibrary(getEntityResource()->m_Module);
  455. DestoryModuleInfo(mod_name);
  456. #else
  457. if (sp_shm_is_newalloc())
  458. return 0; /*spshell*/
  459. if (g_module) {
  460. delete g_module;
  461. g_module = nullptr;
  462. }
  463. #endif //RVC_OS_WIN
  464. return 0;
  465. }
  466. extern "C" SPBASE_API int __stdcall SpRun(const char *mod_name, int epid, int range, int group, int saveFile)
  467. {
  468. ErrorCodeEnum Error = Error_Unexpect;
  469. if (!mod_name) { return Error_Param; }
  470. if (epid == SP_INVALID_MOD_ID) { return Error_Param; }
  471. #ifdef RVC_OS_WIN
  472. if (findModuleByName(mod_name)) //检测实体是否已创建
  473. SpExit(mod_name);
  474. bool result = group == 0 ? CreateModuleInfo(ENTITY_SINGLE_GROUPNAME) : CreateModuleInfo(mod_name);
  475. //the SetthreadGroup routine would never return false, so the group variable must be not-zero
  476. if (!result || !SetthreadGroup(GetCurrentThreadId(), mod_name))
  477. return Error_Duplication;
  478. #else
  479. if (g_module) {
  480. return Error_Duplication;
  481. }
  482. #endif //RVC_OS_WIN
  483. void* hint_addr = NULL;
  484. HMODULE hModule = NULL;
  485. sp_env_t* env = NULL;
  486. sp_mod_t* mod = NULL;
  487. sp_cfg_shell_module_t* cfg_mod = NULL;
  488. SpModule* curModule = NULL;
  489. if (winsock_init() != 0) {
  490. sp_dbg_error("winsock init failed!");
  491. Error = Error_NetBroken;
  492. goto on_error;
  493. }
  494. SetTokenCallBack(getHttpToken);
  495. #ifdef RVC_OS_LINUX
  496. SetRestfulTokenCallBack(getHttpToken);
  497. #endif
  498. //need init shm first, because log_record save in shm
  499. hint_addr = sp_shm_init(range, FALSE);
  500. create_log_producer_default(mod_name, epid);
  501. if (saveFile)
  502. sp_dbg_init(mod_name, 1);
  503. else
  504. sp_dbg_init(mod_name, 0);
  505. EntityResource::setSaveFile(saveFile);
  506. sp_dbg_set_level(XLOG_LEVEL_DEBUG);
  507. if (!hint_addr) {
  508. DbgWithLink(LOG_LEVEL_ERROR, LOG_TYPE_SYSTEM).setAPI(__FUNCTION__)("shm init failed!");
  509. Error = Error_Null;
  510. goto on_error;
  511. }
  512. sp_trace_init();
  513. DbgWithLink(LOG_LEVEL_INFO, LOG_TYPE_SYSTEM)("==============SpRun(%s) start==============", mod_name);
  514. DbgWithLink(LOG_LEVEL_INFO, LOG_TYPE_SYSTEM)("process id: %d, curLogLevel:%d", GetCurrentProcessId(), getCurLogLevel());
  515. DbgWithLink(LOG_LEVEL_INFO, LOG_TYPE_SYSTEM).setAPI(__FUNCTION__)("shm init ok! hint_addr: %p", hint_addr);
  516. env = sp_get_env();
  517. if (!env) {
  518. DbgWithLink(LOG_LEVEL_ERROR, LOG_TYPE_SYSTEM).setAPI(__FUNCTION__)("module env object init failed(env is null)!");
  519. Error = Error_Unexpect;
  520. goto on_error;
  521. }
  522. DbgWithLink(LOG_LEVEL_DEBUG, LOG_TYPE_SYSTEM).setAPI(__FUNCTION__)("retrieve env object ok!");
  523. mod = sp_mod_mgr_find_module_by_idx(env->mod_mgr, epid);
  524. if (!mod) {
  525. DbgWithLink(LOG_LEVEL_ERROR, LOG_TYPE_SYSTEM).setAPI(__FUNCTION__)("find shm module object failed!");
  526. Error = Error_NotExist;
  527. goto on_error;
  528. }
  529. //sp_dbg_info("find module %s id %d ok!", mod->cfg->name, mod->cfg->idx);
  530. DbgWithLink(LOG_LEVEL_DEBUG, LOG_TYPE_SYSTEM).setAPI(__FUNCTION__)("module %s id %d static file version: %d.%d.%d.%d", mod->cfg->name, mod->cfg->idx,
  531. mod->cfg->version.major,
  532. mod->cfg->version.minor,
  533. mod->cfg->version.revision,
  534. mod->cfg->version.build);
  535. SpInitUUID((WORD)mod->cfg->idx);
  536. cfg_mod = sp_cfg_get_module_by_idx(env->cfg, epid);
  537. if (!cfg_mod) {
  538. DbgWithLink(LOG_LEVEL_ERROR, LOG_TYPE_SYSTEM).setAPI(__FUNCTION__)("get module %s cfg object failed!", mod->cfg->name);
  539. Error = Error_NotExist;
  540. goto on_error;
  541. }
  542. DbgWithLink(LOG_LEVEL_INFO, LOG_TYPE_SYSTEM).setAPI(__FUNCTION__)("find cfg module object %s id %d ok!", cfg_mod->name, cfg_mod->idx);
  543. #ifdef RVC_OS_WIN
  544. SetUnhandledExceptionFilter(&SuppressError);
  545. #else
  546. SuppressError(NULL);
  547. #endif //RVC_OS_WIN
  548. #ifdef RVC_OS_WIN
  549. curModule = new SpModule(mod, cfg_mod);
  550. getEntityResource()->m_Module = LoadModuleLibrary(mod);
  551. if (!getEntityResource()->m_Module) {
  552. DbgWithLink(LOG_LEVEL_ERROR, LOG_TYPE_SYSTEM).setAPI(__FUNCTION__)("load module library %s failed! GetLastError = %d", mod->cfg->name, GetLastError());
  553. Error = Error_Unregisted;
  554. goto on_error;
  555. }
  556. curModule->getEntryRoutine(&(getEntityResource()->m_pfMain), &(getEntityResource()->m_pfExit));
  557. Error = curModule->Init(env->url);
  558. if (Error) {
  559. delete curModule;
  560. curModule = NULL;
  561. goto on_error;
  562. }
  563. #else
  564. g_module = new SpModule(mod, cfg_mod);
  565. hModule = LoadModuleLibrary(mod);
  566. if (!hModule) {
  567. DbgWithLink(LOG_LEVEL_ERROR, LOG_TYPE_SYSTEM)("load module library %s failed! %s", mod->cfg->name, DLoadErrorString());
  568. Error = Error_Unregisted;
  569. goto on_error;
  570. }
  571. DbgWithLink(LOG_LEVEL_DEBUG, LOG_TYPE_SYSTEM)("to init module...");
  572. Error = g_module->Init(env->url);
  573. if (Error) {
  574. DbgWithLink(LOG_LEVEL_ERROR, LOG_TYPE_SYSTEM)("init moudle returned %s", SpStrError(Error));
  575. goto on_error;
  576. }
  577. DbgWithLink(LOG_LEVEL_INFO, LOG_TYPE_SYSTEM)("init moudle succ.");
  578. #endif //RVC_OS_WIN
  579. SetThreadPriority(GetCurrentThread(), THREAD_PRIORITY_ABOVE_NORMAL);
  580. #ifdef RVC_OS_WIN
  581. if (!SetSpModule(mod_name, curModule)) {
  582. Error = Error_Unexpect;
  583. goto on_error;
  584. }
  585. sp_trace_term();
  586. Error = curModule->Run();
  587. curModule->Term();
  588. FreeLibrary(getEntityResource()->m_Module);
  589. delete curModule;
  590. curModule = NULL;
  591. #else
  592. sp_trace_term();
  593. Error = g_module->Run();
  594. g_module->Term();
  595. #endif //RVC_OS_WIN
  596. on_error:
  597. #ifndef RVC_OS_WIN
  598. if (hModule) {
  599. FreeLibrary(hModule);
  600. hModule = NULL;
  601. }
  602. if (g_module) {
  603. delete g_module;
  604. g_module = nullptr;
  605. }
  606. #endif //NOT RVC_OS_WIN
  607. if (!!sp_trace_exist()) {
  608. char* last_err = NULL;
  609. sp_trace_retrieve(&last_err, NULL);
  610. if (last_err) {
  611. sp_mod_supress_last_err_for_all_entity(mod, last_err);
  612. FREE(last_err);
  613. }
  614. }
  615. sp_shm_term();
  616. //destroy_log_producer_default();
  617. return Error;
  618. }
  619. extern "C" SPBASE_API const char* SpStrError(ErrorCodeEnum errorCode)
  620. {
  621. return sp_strerror((int)errorCode);
  622. }
  623. SPBASE_API CSimpleStringA GetSysErrMsg(int nErrCode)
  624. {
  625. char szBuf[2048] = {};
  626. DWORD dwRet = FormatMessageA(
  627. FORMAT_MESSAGE_IGNORE_INSERTS | FORMAT_MESSAGE_FROM_SYSTEM,
  628. NULL,
  629. nErrCode,
  630. MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT),
  631. szBuf,
  632. sizeof(szBuf)-1,
  633. NULL);
  634. char *p = strrchr(szBuf, '\r');
  635. if (p != NULL)
  636. *p = ' ';
  637. p = strrchr(szBuf, '\n');
  638. if (p != NULL)
  639. *p = ' ';
  640. return dwRet > 0 ? szBuf : CSimpleStringA::Format("get error message fail: %d", GetLastError());
  641. }
  642. SPBASE_API const char *_GetFileName(const char *pszFilePath)
  643. {
  644. int i=strlen(pszFilePath);
  645. for( ; i>0 && pszFilePath[i-1]!=SPLIT_SLASH; i--)NULL;
  646. return pszFilePath+i;
  647. }
  648. #ifdef RVC_OS_WIN
  649. extern "C" BOOL APIENTRY DllMain(HMODULE hModule,
  650. DWORD ul_reason_for_call,
  651. LPVOID lpReserved)
  652. {
  653. switch (ul_reason_for_call) {
  654. case DLL_PROCESS_ATTACH:
  655. {
  656. DisableThreadLibraryCalls(hModule);
  657. break;
  658. }
  659. case DLL_THREAD_ATTACH:
  660. break;
  661. case DLL_THREAD_DETACH:
  662. break;
  663. case DLL_PROCESS_DETACH:
  664. break;
  665. }
  666. return TRUE;
  667. }
  668. #endif //RVC_OS_WIN
  669. ModuleBase::~ModuleBase()
  670. {
  671. #ifdef RVC_OS_WIN
  672. getEntityResource()->m_moduleBase = NULL;
  673. #else
  674. ModuleBase::s_pModuleInst = NULL;
  675. #endif //RVC_OS_WIN
  676. for (int i = 0; i < m_nEntityCount; ++i)
  677. {
  678. if (m_pEntityArray[i])
  679. {
  680. #ifdef RVC_OS_WIN
  681. //属于实体关闭掉,会自动清理,实际上不做对应的delete也行
  682. //基于该部分出了的问题,应该用share_ptr来处理
  683. //不过因为需要导出到spbase.h中,处理比较麻烦
  684. //__try {
  685. // delete m_pEntityArray[i];
  686. //}
  687. //__finally {
  688. // m_pEntityArray[i] = NULL;
  689. //}
  690. #else
  691. delete m_pEntityArray[i];
  692. m_pEntityArray[i] = NULL;
  693. #endif //RVC_OS_WIN
  694. }
  695. }
  696. m_nEntityCount = 0;
  697. }
  698. static ErrorCodeEnum __Init()
  699. {
  700. #ifdef RVC_OS_WIN
  701. ModuleBase* pThis = (ModuleBase*)(getEntityResource()->m_moduleBase);
  702. #else
  703. ModuleBase* pThis = ModuleBase::s_pModuleInst;
  704. #endif //RVC_OS_WIN
  705. _ASSERT(pThis);
  706. return pThis->Init();
  707. }
  708. static ErrorCodeEnum __Exit()
  709. {
  710. #ifdef RVC_OS_WIN
  711. ModuleBase* pThis = (ModuleBase*)(getEntityResource()->m_moduleBase);
  712. #else
  713. ModuleBase* pThis = ModuleBase::s_pModuleInst;
  714. #endif //RVC_OS_WIN
  715. _ASSERT(pThis);
  716. return pThis->Exit();
  717. }
  718. ErrorCodeEnum ModuleBase::Init()
  719. {
  720. ErrorCodeEnum Error = Error_Succeed;
  721. for (int i = 0; i < m_nEntityCount; ++i)
  722. {
  723. DbgWithLink(LOG_LEVEL_DEBUG, LOG_TYPE_SYSTEM)("to regist entity %s", m_pEntityArray[i]->GetEntityName());
  724. Error = RegistEntity(m_pEntityArray[i]);
  725. if (Error) {
  726. DbgWithLink(LOG_LEVEL_WARN, LOG_TYPE_SYSTEM)("regist entity %s returned %s", m_pEntityArray[i]->GetEntityName(), SpStrError(Error));
  727. break;
  728. }
  729. }
  730. return Error;
  731. }
  732. ErrorCodeEnum ModuleBase::Exit()
  733. {
  734. ErrorCodeEnum Error = Error_Succeed;
  735. for (int i = 0; i < m_nEntityCount; ++i)
  736. {
  737. Error = UnregistEntity(m_pEntityArray[i]);
  738. if (Error)
  739. break;
  740. }
  741. return Error;
  742. }
  743. BOOL ModuleBase::DllMain(HINSTANCE hInstance, DWORD dwReason, LPVOID lpReserved)
  744. {
  745. if (dwReason == DLL_PROCESS_ATTACH) {
  746. bool ret = RegistMain(hInstance, &__Init, &__Exit);
  747. if (!ret)
  748. return FALSE;
  749. DisableThreadLibraryCalls(hInstance);
  750. m_hInstance = hInstance;
  751. }
  752. return TRUE;
  753. }
  754. ErrorCodeEnum ModuleBase::RegistEntity(CEntityBase *pEntity)
  755. {
  756. SpModule *pModule = GetSpModule();
  757. SpSecureClient::SetSecureEntity(pEntity);
  758. if (!pModule)
  759. return Error_Null;
  760. return pModule->AddEntityBase(pEntity);
  761. }
  762. ErrorCodeEnum ModuleBase::UnregistEntity(CEntityBase *pEntity)
  763. {
  764. SpModule *pModule = GetSpModule();
  765. return pModule->RemoveEntityBase(pEntity);
  766. }
  767. ErrorCodeEnum ModuleBase::GetRegistEntity(const char *pszEntityName,CSmartPointer<CEntityBase> &pEntity)
  768. {
  769. SpModule *pModule = GetSpModule();
  770. return pModule->GetEntityBase(pszEntityName, pEntity);
  771. }
  772. #ifndef RVC_OS_WIN
  773. ModuleBase* ModuleBase::s_pModuleInst = NULL;
  774. #endif //NOT RVC_OS_WIN
  775. ModuleBase* ModuleBase::GetModuleBase()
  776. {
  777. #ifdef RVC_OS_WIN
  778. return (ModuleBase*)(getEntityResource()->m_moduleBase);
  779. #else
  780. return ModuleBase::s_pModuleInst;
  781. #endif //RVC_OS_WIN
  782. }
  783. ModuleBase::ModuleBase()
  784. :m_hInstance(NULL), m_nEntityCount(0)
  785. {
  786. #ifdef RVC_OS_WIN
  787. getEntityResource()->m_moduleBase = this;
  788. #else
  789. ModuleBase::s_pModuleInst = this;
  790. #endif //RVC_OS_WIN
  791. }
  792. CClientSessionBase::~CClientSessionBase()
  793. {
  794. if (m_pSessionFunction) {
  795. SpClientSessionFunction *pFunction = dynamic_cast<SpClientSessionFunction *>(m_pSessionFunction);
  796. m_pSessionFunction = NULL;
  797. pFunction->DecrementRef();
  798. }
  799. }