From 66eac83cd99ff92ec89639dfd83ec99312096b21 Mon Sep 17 00:00:00 2001 From: wupengyong Date: Thu, 23 Dec 2021 09:56:25 +0800 Subject: [PATCH] add change from wagner Signed-off-by: wupengyong Change-Id: I336e83a58ea007deeb7a8b8ba0f99f977a3006d0 --- VERSION => VERSION.info | 0 debugger.c | 59 ++++++++++++++++++++++------------------- debugger.h | 6 ++--- message_server.cpp | 47 ++++++++++++++++++++++---------- message_server.h | 9 ++++--- quickjs.c | 15 ++++++++--- 6 files changed, 84 insertions(+), 52 deletions(-) rename VERSION => VERSION.info (100%) diff --git a/VERSION b/VERSION.info similarity index 100% rename from VERSION rename to VERSION.info diff --git a/debugger.c b/debugger.c index 0d6a28f..ca5ed02 100644 --- a/debugger.c +++ b/debugger.c @@ -32,22 +32,13 @@ #include "message_server.h" -static int g_connectFlag = 0; -static int g_client = 0; -void DBG_SetConnectFlag(int flag, int client) -{ - g_connectFlag = flag; - g_client = client; -} - -static int DBG_IsConnect() -{ - return g_connectFlag; -} +static __thread bool g_isServerStarted = 0; +static __thread bool g_isBreakPointSet = 0; +static __thread bool g_isAttachMode = 0; -static int DBG_GetClient() +void DBG_SetDebugMode(bool isAttachMode) { - return g_client; + g_isAttachMode = isAttachMode; } static int DBG_ConnectToIde() @@ -102,14 +93,14 @@ static JSValue DBG_ReadMsg(DebuggerInfo *debuggerInfo) DEBUGGER_LOGE("DBG_ReadMsg fail debuggerInfo=NULL"); return JS_UNDEFINED; } - while (QueueIsEmpty()) { + while (QueueIsEmpty(debuggerInfo->client)) { usleep(DBG_WAITING_TIME); } - const char *message = QueueFront(); + const char *message = QueueFront(debuggerInfo->client); DEBUGGER_LOGI("DBG_ReadMsg %s", message); JSValue msg = JS_ParseJSON(debuggerInfo->cx, message, strlen(message), ""); - QueuePop(); + QueuePop(debuggerInfo->client); return msg; } @@ -850,9 +841,9 @@ static void DBG_Entry(JSContext *cx, int client) return; } debuggerInfo->cx = cx; - debuggerInfo->client = client; + // debuggerInfo->client = client; debuggerInfo->breakpoints = JS_NewObject(cx); - debuggerInfo->isConnected = 1; + // debuggerInfo->isConnected = 1; DBG_SendStopMsg(debuggerInfo, "entry"); } @@ -954,21 +945,33 @@ void DBG_CallDebugger(JSContext *cx, const uint8_t *pc) DEBUGGER_LOGE("DBG_CallDebugger fail debuggerInfo=NULL"); return; } - if (debuggerInfo->isConnected == 0) { + + if (!g_isServerStarted) { pthread_t tid; - if (pthread_create(&tid, NULL, &DBG_StartAgent, NULL) != 0) { + if (pthread_create(&tid, NULL, &DBG_StartAgent, (void*)debuggerInfo) != 0) { DEBUGGER_LOGE("pthread_create fail!"); return; } - while (DBG_IsConnect() == 0) { - usleep(DBG_WAITING_TIME); + g_isServerStarted = true; + if (!g_isAttachMode) { + while (debuggerInfo->isConnected != 1) { + usleep(DBG_WAITING_TIME); + } + DBG_Entry(cx, debuggerInfo->client); + // read msg when first time must be breakpoints msg, and set breakpoints to debugger + DBG_ProcessMsg(debuggerInfo, pc, 0); + g_isBreakPointSet = true; } - DBG_Entry(cx, DBG_GetClient()); - // read msg when first time must be breakpoints msg, and set breakpoints to debugger - DBG_ProcessMsg(debuggerInfo, pc, 0); } - if (QueueIsEmpty() == 0) { + if (g_isAttachMode && (debuggerInfo->isConnected == 1 && !g_isBreakPointSet)) { + // ide attached, accept breakpoints msg + DBG_Entry(cx, debuggerInfo->client); + DBG_ProcessMsg(debuggerInfo, pc, 0); + g_isBreakPointSet = true; + } + + if (QueueIsEmpty(debuggerInfo->client) == 0) { DBG_ProcessMsg(debuggerInfo, pc, 1); } @@ -982,7 +985,7 @@ void DBG_CallDebugger(JSContext *cx, const uint8_t *pc) } } // must check breakpotint first, then process step operation - if (JS_HitBreakpoint(cx, pc) && JS_JudgeConditionBreakPoint(cx, pc)) { + if (g_isBreakPointSet && JS_HitBreakpoint(cx, pc) && JS_JudgeConditionBreakPoint(cx, pc)) { LocInfo loc = JS_GetCurrentLocation(cx, pc); DEBUGGER_LOGI("DBG_CallDebugger hit breakpoint at line %d", loc.line); diff --git a/debugger.h b/debugger.h index 193be98..05550d2 100644 --- a/debugger.h +++ b/debugger.h @@ -84,13 +84,13 @@ typedef struct LocInfo { typedef struct DebuggerInfo { JSContext *cx; - int client; + volatile int client; int stepOperation; uint32_t depth; LocInfo loc; JSValue breakpoints; int buildConnect; - int isConnected; + volatile int isConnected; } DebuggerInfo; typedef struct DebuggerVariableState { @@ -108,7 +108,7 @@ JSValue JS_DebuggerEvaluate(JSContext *ctx, int stackIndex, JSValue expression); void DBG_FreeSources(JSContext *cx, DebuggerInfo *debuggerInfo); void DBG_CallDebugger(JSContext *cx, const uint8_t *pc); uint32_t DBG_GetValueAsUint32Type(JSContext *cx, JSValue obj, const char *property); -void DBG_SetConnectFlag(int flag, int client); +void DBG_SetDebugMode(bool isAttachMode); #ifdef __cplusplus } diff --git a/message_server.cpp b/message_server.cpp index 317c386..4f0332a 100644 --- a/message_server.cpp +++ b/message_server.cpp @@ -26,6 +26,7 @@ #include #include #include +#include #include #include #include @@ -36,7 +37,7 @@ #include "securec.h" static std::mutex g_mtx; -static std::list g_readMsgQueue; +static std::map> g_readMsgQueues; static constexpr int MSG_LEN = 9; static constexpr int MAX_CONNECT_CLIENT_NUM = 1; @@ -49,25 +50,25 @@ bool DBG_CopyComponentNameFromAce(const char *srcStr, char *destStr, int maxLen) return true; } -const char* QueueFront() +const char* QueueFront(int client) { g_mtx.lock(); - const char* res = g_readMsgQueue.front().c_str(); + const char* res = g_readMsgQueues[client].front().c_str(); g_mtx.unlock(); return res; } -void QueuePop() +void QueuePop(int client) { g_mtx.lock(); - g_readMsgQueue.pop_front(); + g_readMsgQueues[client].pop_front(); g_mtx.unlock(); } -int QueueIsEmpty() +int QueueIsEmpty(int client) { g_mtx.lock(); - int ret = g_readMsgQueue.empty(); + int ret = g_readMsgQueues[client].empty(); g_mtx.unlock(); return ret; } @@ -132,21 +133,30 @@ static void ReadMsg(int client) msgBuf.get()[msgLen] = '\0'; DEBUGGER_LOGI("dbg msg %s", msgBuf.get()); std::string message(msgBuf.get()); - g_readMsgQueue.push_back(message); + g_readMsgQueues[client].push_back(message); g_mtx.unlock(); return; } + static std::string g_componentName; +static int g_instanceId; -void DBG_SetComponentName(const char *name, int size) +void DBG_SetComponentNameAndInstanceId(const char *name, int size, int instanceId) { if (size <= 0) { DEBUGGER_LOGE("DBG_SetComponentName fail"); return; } g_componentName = name; + g_instanceId = instanceId; +} + +void DBG_SetNeedDebugBreakPoint(bool needDebugBreakPoint) +{ + DEBUGGER_LOGI("NeedDebugBreakPoint: %d", needDebugBreakPoint); + DBG_SetDebugMode(!needDebugBreakPoint); } static std::string DBG_GetComponentName() @@ -164,10 +174,10 @@ static int DBG_StartServer() if (fd < 0) { return FAIL_CAUSE_SOCKET_COMMON_FAIL; } - int appPid = getpid(); - std::string pidStr = std::to_string(appPid); + + std::string instanceIdStr = std::to_string(g_instanceId); std::string component = DBG_GetComponentName(); - std::string sockName = pidStr + component; + std::string sockName = instanceIdStr + component; struct sockaddr_un un; if (memset_s(&un, sizeof(un), 0, sizeof(un)) != EOK) { DEBUGGER_LOGE("DBG_StartServer memset_s fail"); @@ -201,12 +211,21 @@ static int DBG_StartServer() void *DBG_StartAgent(void *args) { int client = DBG_StartServer(); - DEBUGGER_LOGI("DBG_StartAgent client = %d", client); if (client < 0) { DEBUGGER_LOGE("DBG_StartAgent fail"); return nullptr; } - DBG_SetConnectFlag(1, client); + + auto debugger_info = (DebuggerInfo*)args; + g_mtx.lock(); + debugger_info->client = client; + debugger_info->isConnected = 1; + g_mtx.unlock(); + + std::list messageList; + g_readMsgQueues[client] = messageList; + DEBUGGER_LOGI("DBG_StartAgent client = %d", client); + while (true) { ReadMsg(client); } diff --git a/message_server.h b/message_server.h index 225b6e0..6ef7e52 100644 --- a/message_server.h +++ b/message_server.h @@ -27,12 +27,13 @@ extern "C" { #endif /* End of #ifdef __cplusplus */ -const char* QueueFront(); -void QueuePop(); -int QueueIsEmpty(); +const char* QueueFront(int client); +void QueuePop(int client); +int QueueIsEmpty(int client); void *DBG_StartAgent(void *args); bool DBG_CopyComponentNameFromAce(const char *srcStr, char *destStr, int maxLen); -void DBG_SetComponentName(const char *name, int size); +void DBG_SetComponentNameAndInstanceId(const char *name, int size, int instanceId); +void DBG_SetNeedDebugBreakPoint(bool needDebugBreakPoint); #ifdef __cplusplus } diff --git a/quickjs.c b/quickjs.c index 40024dc..eca45d4 100644 --- a/quickjs.c +++ b/quickjs.c @@ -426,7 +426,7 @@ struct JSContext { JSShape *array_shape; /* initial shape for Array objects */ #ifdef ENABLE_JS_DEBUG - DebuggerInfo debugger_info; + DebuggerInfo *debugger_info; #endif JSValue *class_proto; @@ -2146,8 +2146,17 @@ JSContext *JS_NewContextRaw(JSRuntime *rt) ctx->header.ref_count = 1; add_gc_object(rt, &ctx->header, JS_GC_OBJ_TYPE_JS_CONTEXT); +#ifdef ENABLE_JS_DEBUG + ctx->debugger_info = js_malloc_rt(rt, sizeof(DebuggerInfo)); + if (!ctx->debugger_info) { + DEBUGGER_LOGE("Create debugger_info failed!"); + return NULL; + } +#endif + ctx->class_proto = js_malloc_rt(rt, sizeof(ctx->class_proto[0]) * rt->class_count); + if (!ctx->class_proto) { js_free_rt(rt, ctx); return NULL; @@ -16204,7 +16213,7 @@ static JSValue JS_CallInternal(JSContext *caller_ctx, JSValueConst func_obj, }; #define SWITCH(pc) goto *active_dispatch_table[opcode = *pc++]; #define CASE(op) case_debugger_ ## op: DBG_CallDebugger(caller_ctx, pc); case_ ## op - const void * const * active_dispatch_table = caller_ctx->debugger_info.isConnected + const void * const * active_dispatch_table = caller_ctx->debugger_info->isConnected ? debugger_dispatch_table : dispatch_table; #else #define SWITCH(pc) goto *dispatch_table[opcode = *pc++]; @@ -54209,7 +54218,7 @@ DebuggerInfo *JS_GetDebuggerInfo(JSContext *cx) if (cx == NULL) { return NULL; } - return &cx->debugger_info; + return cx->debugger_info; } static int JS_FunctionDefineInit(JSContext *ctx, JSFunctionDef *fd, JSFunctionBytecode *byte_code) -- Gitee