SpBase.cpp 28 KB

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