diff options
author | Eugene Tarassov | 2019-11-14 20:38:17 +0000 |
---|---|---|
committer | Eugene Tarassov | 2019-11-17 18:06:27 +0000 |
commit | a5aeb971a3f36b65a2b49172bc1c85a5c83beadb (patch) | |
tree | 60512cc409157824948b3aac9c43b3393a46cda9 /agent/tcf | |
parent | ccff68c5f39a09e1ab3005620268add20661b557 (diff) | |
download | org.eclipse.tcf.agent-a5aeb971a3f36b65a2b49172bc1c85a5c83beadb.tar.gz org.eclipse.tcf.agent-a5aeb971a3f36b65a2b49172bc1c85a5c83beadb.tar.xz org.eclipse.tcf.agent-a5aeb971a3f36b65a2b49172bc1c85a5c83beadb.zip |
TCF Agent: fixed data caching for server side services
When Symbols and/or some other services are configured to run in TCF server,
MEM_ACCESS_RD_STOP can cause infinite loop of cache misses.
Need to lock run control until cache validation is done.
Diffstat (limited to 'agent/tcf')
-rw-r--r-- | agent/tcf/services/breakpoints.c | 7 | ||||
-rw-r--r-- | agent/tcf/services/disassembly.c | 8 | ||||
-rw-r--r-- | agent/tcf/services/expressions.c | 4 | ||||
-rw-r--r-- | agent/tcf/services/runctrl.c | 41 |
4 files changed, 51 insertions, 9 deletions
diff --git a/agent/tcf/services/breakpoints.c b/agent/tcf/services/breakpoints.c index a77f3d2d..4ae399d6 100644 --- a/agent/tcf/services/breakpoints.c +++ b/agent/tcf/services/breakpoints.c @@ -1,5 +1,5 @@ /******************************************************************************* - * Copyright (c) 2007-2017 Wind River Systems, Inc. and others. + * Copyright (c) 2007-2019 Wind River Systems, Inc. and others. * All rights reserved. This program and the accompanying materials * are made available under the terms of the Eclipse Public License v1.0 * and Eclipse Distribution License v1.0 which accompany this distribution. @@ -1627,19 +1627,21 @@ static void plant_at_address_expression(Context * ctx, ContextAddress ip, Breakp int error = 0; #if ENABLE_Expressions Value v; - SymbolProperties props; memset (&v, 0, sizeof (Value)); if (evaluate_expression(ctx, STACK_NO_FRAME, ip, bp->location, 1, &v) < 0) error = errno; if (!error && value_to_address(&v, &addr) < 0) error = errno; +#if ENABLE_Symbols if (!error && v.sym != NULL) { + SymbolProperties props; /* We want to add the LocalEntryOffset */ get_symbol_props(v.sym, &props); /* If the symbol is not a PPC64 function, offset should be 0, so it is safe to add */ addr += props.local_entry_offset; } #endif +#endif #if ENABLE_SkipPrologueWhenPlanting /* Even if addr is incremented by local_entry_offset, we still should be on right code area */ if (!error && bp->skip_prologue && v.sym != NULL && skip_function_prologue(ctx, v.sym, &addr) < 0) error = errno; @@ -1674,6 +1676,7 @@ static void plant_at_address_expression(Context * ctx, ContextAddress ip, Breakp while (v.sym_list[n] != NULL) { Symbol * sym = v.sym_list[n++]; if (get_symbol_address(sym, &addr) == 0) { + SymbolProperties props; /* We want to add the LocalEntryOffset */ get_symbol_props(sym, &props); /* If the symbol is not a PPC64 function, offset should be 0, so it is safe to add */ diff --git a/agent/tcf/services/disassembly.c b/agent/tcf/services/disassembly.c index c6c35653..07f018c8 100644 --- a/agent/tcf/services/disassembly.c +++ b/agent/tcf/services/disassembly.c @@ -278,7 +278,7 @@ static int disassemble_block(Context * ctx, OutputStream * out, uint8_t * mem_bu return 0; } -#if SERVICE_LineNumbers +#if ENABLE_LineNumbers static void address_to_line_cb(CodeArea * area, void * args) { CodeArea ** p = (CodeArea **)args; if (*p == NULL || (*p)->start_address < area->start_address) { @@ -325,7 +325,7 @@ static void disassemble_cache_client(void * x) { ContextAddress sym_size = 0; int sym_addr_ok = 0; int sym_size_ok = 0; -#if SERVICE_Symbols +#if ENABLE_Symbols { Symbol * sym = NULL; if (find_symbol_by_addr(ctx, STACK_NO_FRAME, args->addr, &sym) == 0) { @@ -338,7 +338,7 @@ static void disassemble_cache_client(void * x) { } } #endif -#if SERVICE_LineNumbers +#if ENABLE_LineNumbers if (!sym_addr_ok || !sym_size_ok) { CodeArea * area = NULL; address_to_line(ctx, args->addr, args->addr + 1, address_to_line_cb, &area); @@ -476,7 +476,7 @@ static void read_disassembly_params(InputStream * inp, const char * name, void * args->pseudo_instr = json_read_boolean(inp); } else if (strcmp(name, "OpcodeValue") == 0) { - args->opcode_value =json_read_boolean(inp); + args->opcode_value = json_read_boolean(inp); } else { json_skip_object(inp); diff --git a/agent/tcf/services/expressions.c b/agent/tcf/services/expressions.c index e9434607..81de0026 100644 --- a/agent/tcf/services/expressions.c +++ b/agent/tcf/services/expressions.c @@ -1574,6 +1574,7 @@ static void load_value(Value * v) { else if (v->value != NULL) { /* OK */ } +#if ENABLE_Symbols else if (v->loc != NULL) { size_t size = 0; void * value = NULL; @@ -1584,6 +1585,7 @@ static void load_value(Value * v) { v->size = (ContextAddress)size; sign_extend(v, loc); } +#endif else { error(ERR_OTHER, "Has no value"); } @@ -2041,7 +2043,9 @@ static void primary_expression(int mode, Value * v) { next_sy(); } else if (text_sy == SY_VAL) { +#if ENABLE_Symbols int flags = text_val_flags; +#endif *v = text_val; next_sy(); #if ENABLE_Symbols diff --git a/agent/tcf/services/runctrl.c b/agent/tcf/services/runctrl.c index 653381c0..695cf9fb 100644 --- a/agent/tcf/services/runctrl.c +++ b/agent/tcf/services/runctrl.c @@ -70,6 +70,7 @@ static unsigned listener_cnt = 0; static unsigned listener_max = 0; static const char RUN_CONTROL[] = "RunControl"; +static const char CONTEXT_PROXY[] = "ContextProxy"; typedef struct ContextExtensionRC { int pending_safe_event; /* safe events are waiting for this context to be stopped */ @@ -111,10 +112,16 @@ typedef struct ContextExtensionRC { } ContextExtensionRC; static size_t context_extension_offset = 0; - #define EXT(ctx) (ctx ? ((ContextExtensionRC *)((char *)(ctx) + context_extension_offset)) : NULL) #define link2ctx(lnk) ((Context *)((char *)(lnk) - offsetof(ContextExtensionRC, link) - context_extension_offset)) +typedef struct ChannelExtensionRC { + int cache_lock; +} ChannelExtensionRC; + +static size_t channel_extension_offset = 0; +#define EXT_CH(ch) ((ChannelExtensionRC *)((char *)(ch) + channel_extension_offset)) + typedef struct SafeEvent { Context * ctx; EventCallBack * done; @@ -2759,8 +2766,8 @@ static void clear_context_proxy_cache(Context * ctx) { int i; for (i = 0; i < c->peer_service_cnt; i++) { char * nm = c->peer_service_list[i]; - if (strcmp(nm, "ContextProxy") == 0) { - protocol_send_command(c, "ContextProxy", "clear", context_proxy_reply, NULL); + if (strcmp(nm, CONTEXT_PROXY) == 0) { + protocol_send_command(c, CONTEXT_PROXY, "clear", context_proxy_reply, NULL); json_write_string(&c->out, ctx->id); write_stream(&c->out, 0); write_stream(&c->out, MARKER_EOM); @@ -2819,12 +2826,38 @@ static void event_context_exited(Context * ctx, void * args) { } static void channel_closed(Channel * c) { + ChannelExtensionRC * ext_ch = EXT_CH(c); LINK * l; for (l = context_root.next; l != &context_root; l = l ->next) { Context * ctx = ctxl2ctxp(l); ContextExtensionRC * ext = EXT(ctx); if (ext->step_channel == c) cancel_step_mode(ctx); } + if (ext_ch->cache_lock) { + ext_ch->cache_lock = 0; + run_ctrl_unlock(); + } +} + +static void context_cache_lock(Channel * c) { + ChannelExtensionRC * ext = EXT_CH(c); + json_test_char(&c->inp, MARKER_EOM); + assert(ext->cache_lock == 0); + ext->cache_lock = 1; + run_ctrl_lock(); +} + +static void context_cache_unlock(Channel * c) { + ChannelExtensionRC * ext = EXT_CH(c); + json_test_char(&c->inp, MARKER_EOM); + assert(ext->cache_lock == 1); + ext->cache_lock = 0; + run_ctrl_unlock(); +} + +static void channel_opened(Channel * c) { + add_event_handler(c, CONTEXT_PROXY, "lock", context_cache_lock); + add_event_handler(c, CONTEXT_PROXY, "unlock", context_cache_unlock); } static void event_context_disposed(Context * ctx, void * args) { @@ -2870,7 +2903,9 @@ void ini_run_ctrl_service(Protocol * proto, TCFBroadcastGroup * bcg) { broadcast_group = bcg; add_context_event_listener(&listener, NULL); add_channel_close_listener(channel_closed); + add_channel_open_listener(channel_opened); context_extension_offset = context_extension(sizeof(ContextExtensionRC)); + channel_extension_offset = channel_extension(sizeof(ChannelExtensionRC)); add_command_handler(proto, RUN_CONTROL, "getContext", command_get_context); add_command_handler(proto, RUN_CONTROL, "getChildren", command_get_children); add_command_handler(proto, RUN_CONTROL, "getState", command_get_state); |