SpBase.cpp 27 KB

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