mirror of
https://github.com/Ylianst/MeshAgent
synced 2025-12-06 00:13:33 +00:00
1. Added additional memory check helpers
2. Updated Process exit detection to check apc flags
This commit is contained in:
@@ -1595,13 +1595,14 @@ duk_ret_t ILibDuktape_MeshAgent_eval(duk_context *ctx)
|
||||
}
|
||||
duk_context* ScriptEngine_Stop(MeshAgentHostContainer *agent, char *contextGUID);
|
||||
|
||||
int dumpcount = 0;
|
||||
void ILibDuktape_MeshAgent_dumpCoreModuleEx(void *chain, void *user)
|
||||
{
|
||||
MeshAgentHostContainer* agentHost = (MeshAgentHostContainer*)user;
|
||||
char *CoreModule;
|
||||
|
||||
ScriptEngine_Stop((MeshAgentHostContainer*)user, MeshAgent_JavaCore_ContextGuid);
|
||||
printf("CoreModule was manually dumped, restarting!\n");
|
||||
printf("CoreModule was manually dumped %d times, restarting!\n", ++dumpcount);
|
||||
|
||||
int CoreModuleLen = ILibSimpleDataStore_Get(agentHost->masterDb, "CoreModule", NULL, 0);
|
||||
if (CoreModuleLen > 0)
|
||||
|
||||
@@ -94,12 +94,34 @@ void ILibDuktape_ChildProcess_SubProcess_StdIn_EndHandler(ILibDuktape_WritableSt
|
||||
ILibProcessPipe_Process_CloseStdIn(p->childProcess);
|
||||
}
|
||||
}
|
||||
void ILibDuktape_ChildProcess_SubProcess_ExitHandler(ILibProcessPipe_Process sender, int exitCode, void* user);
|
||||
void ILibDuktape_ChildProcess_SubProcess_ExitHandler_sink1(void *chain, void *user)
|
||||
{
|
||||
ILibDuktape_ChildProcess_SubProcess *p = (ILibDuktape_ChildProcess_SubProcess*)user;
|
||||
if (!ILibMemory_CanaryOK(p)) { return; }
|
||||
|
||||
ILibDuktape_ChildProcess_SubProcess_ExitHandler(NULL, p->exitCode, p);
|
||||
}
|
||||
void ILibDuktape_ChildProcess_SubProcess_ExitHandler(ILibProcessPipe_Process sender, int exitCode, void* user)
|
||||
{
|
||||
ILibDuktape_ChildProcess_SubProcess *p = (ILibDuktape_ChildProcess_SubProcess*)user;
|
||||
if (!ILibMemory_CanaryOK(p)) { return; }
|
||||
|
||||
#ifdef WIN32
|
||||
if (duk_ctx_context_data(p->ctx)->apc_flags == 0)
|
||||
{
|
||||
// This method was called with an APC, but this thread was running an unknown alertable method when it was interrupted
|
||||
// So we must unwind the stack, and use a non-apc method to re-dispatch to this thread, becuase we can't risk
|
||||
// calling a winsock method, in case this thread was inside winsock when it was interrupted, because otherwise, it
|
||||
// will corrupt memory, resulting in a possible crash.
|
||||
//
|
||||
// We had to do the APC first, becuase otherwise child_process.waitExit() will not work, becuase that method is blocking
|
||||
// the event loop thread with an alertable wait object, so APC is the only way to propagate this event
|
||||
p->exitCode = exitCode;
|
||||
Duktape_RunOnEventLoop(p->chain, duk_ctx_nonce(p->ctx), p->ctx, ILibDuktape_ChildProcess_SubProcess_ExitHandler_sink1, NULL, p);
|
||||
}
|
||||
#endif
|
||||
|
||||
p->exitCode = exitCode;
|
||||
p->childProcess = NULL;
|
||||
duk_push_heapptr(p->ctx, p->subProcess); // [childProcess]
|
||||
@@ -181,8 +203,13 @@ duk_ret_t ILibDuktape_ChildProcess_waitExit(duk_context *ctx)
|
||||
duk_put_prop_string(ctx, -2, "\xFF_WaitExit"); // [spawnedProcess]
|
||||
|
||||
#ifdef WIN32
|
||||
duk_thread_state ts;
|
||||
duk_suspend(ctx, &ts);
|
||||
duk_ctx_context_data(ctx)->apc_flags = 1;
|
||||
while ((result=WaitForSingleObjectEx(eptr, duk_is_number(ctx, 0) ? duk_require_int(ctx, 0) : INFINITE, TRUE)) != WAIT_OBJECT_0 && result != WAIT_TIMEOUT);
|
||||
duk_ctx_context_data(ctx)->apc_flags = 0;
|
||||
CloseHandle(eptr);
|
||||
duk_resume(ctx, &ts);
|
||||
if (result == WAIT_TIMEOUT) { return(ILibDuktape_Error(ctx, "timeout")); }
|
||||
#else
|
||||
void *mods[] = { ILibGetBaseTimer(Duktape_GetChain(ctx)), Duktape_GetPointerProperty(ctx, -1, ILibDuktape_ChildProcess_Manager) };
|
||||
|
||||
@@ -50,6 +50,9 @@ typedef struct ILibDuktape_ContextData
|
||||
{
|
||||
uintptr_t nonce;
|
||||
uint32_t flags;
|
||||
#ifdef WIN32
|
||||
uint32_t apc_flags;
|
||||
#endif
|
||||
void *chain;
|
||||
void *user;
|
||||
}ILibDuktape_ContextData;
|
||||
|
||||
@@ -1645,7 +1645,7 @@ void ILibDuktape_Stream_Init(duk_context *ctx, void *chain)
|
||||
}
|
||||
void ILibDuktape_Polyfills_debugGC2(duk_context *ctx, void ** args, int argsLen)
|
||||
{
|
||||
if (duk_ctx_is_alive((duk_context*)args[1]) && duk_ctx_is_valid((uintptr_t)args[2], ctx))
|
||||
if (duk_ctx_is_alive((duk_context*)args[1]) && duk_ctx_is_valid((uintptr_t)args[2], ctx) && duk_ctx_shutting_down(ctx)==0)
|
||||
{
|
||||
if (g_displayFinalizerMessages) { printf("=> GC();\n"); }
|
||||
duk_gc(ctx, 0);
|
||||
|
||||
@@ -279,9 +279,9 @@ void __stdcall ILibDuktape_readableStream_WriteData_OnData_ChainThread_APC(ULONG
|
||||
ILibDuktape_readableStream_bufferedData *data = (ILibDuktape_readableStream_bufferedData*)obj;
|
||||
void *chain = ((void**)ILibMemory_GetExtraMemory((void*)obj, sizeof(ILibDuktape_readableStream_bufferedData) + data->bufferLen))[0];
|
||||
|
||||
if (ILibChain_SelectInterrupted(chain) != 0)
|
||||
if (duk_ctx_context_data(data->ctx)->apc_flags == 0)
|
||||
{
|
||||
// This APC interrupted a winsock (select) call, so we must unroll the callstack to continue,
|
||||
// This APC interrupted an unknown alertable method, so we must unroll the callstack to continue,
|
||||
// because winsock is not re-entrant, so we cannot risk making another winsock call directly.
|
||||
//
|
||||
Duktape_RunOnEventLoop(chain, duk_ctx_nonce(data->ctx), data->ctx, ILibDuktape_readableStream_WriteData_OnData_ChainThread, NULL, (void*)obj);
|
||||
|
||||
Reference in New Issue
Block a user