Skip to main content
summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--agent.dsp10
-rw-r--r--breakpoints.c340
-rw-r--r--context.c24
-rw-r--r--context.h1
-rw-r--r--dbghelp.dllbin0 -> 1061944 bytes
-rw-r--r--dwarfio.c38
-rw-r--r--dwarfio.h5
-rw-r--r--errors.c2
-rw-r--r--linenumbers.h5
-rw-r--r--linenumbers_elf.c110
-rw-r--r--linenumbers_win32.c78
-rw-r--r--peer.c8
-rw-r--r--protocol.c40
-rw-r--r--symbols_win32.c46
14 files changed, 512 insertions, 195 deletions
diff --git a/agent.dsp b/agent.dsp
index fdf3241f..80aca501 100644
--- a/agent.dsp
+++ b/agent.dsp
@@ -50,6 +50,10 @@ BSC32=bscmake.exe
LINK32=link.exe
# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /machine:I386
# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib WS2_32.lib Iphlpapi.lib dbghelp.lib /nologo /subsystem:console /machine:I386
+# Begin Special Build Tool
+SOURCE=$(InputPath)
+PostBuild_Cmds=copy dbghelp.dll Release
+# End Special Build Tool
!ELSEIF "$(CFG)" == "agent - Win32 Debug"
@@ -73,7 +77,11 @@ BSC32=bscmake.exe
# ADD BSC32 /nologo
LINK32=link.exe
# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /debug /machine:I386 /pdbtype:sept
-# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib WS2_32.lib Iphlpapi.lib dbghelp.lib /nologo /subsystem:console /debug /machine:I386 /pdbtype:sept
+# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib WS2_32.lib Iphlpapi.lib dbghelp.lib /nologo /subsystem:console /debug /machine:I386 /pdbtype:sept
+# Begin Special Build Tool
+SOURCE=$(InputPath)
+PostBuild_Cmds=copy dbghelp.dll Debug
+# End Special Build Tool
!ENDIF
diff --git a/breakpoints.c b/breakpoints.c
index 69d79a9e..f4f90cf1 100644
--- a/breakpoints.c
+++ b/breakpoints.c
@@ -40,6 +40,7 @@
#include "symbols.h"
#include "json.h"
#include "link.h"
+#include "linenumbers.h"
#if defined(_WRS_KERNEL)
# include <private/vxdbgLibP.h>
@@ -75,6 +76,13 @@ struct BreakpointInfo {
char * err_msg;
char * address;
char * condition;
+#if SERVICE_LineNumbers
+ char * file;
+ int line;
+ int column;
+#endif
+ int skip_count;
+ int hit_count;
BreakpointAttribute * unsupported;
};
@@ -100,8 +108,10 @@ struct BreakInstruction {
static const char * BREAKPOINTS = "Breakpoints";
+#define is_running(ctx) (!(ctx)->stopped && context_has_state(ctx))
+
#define ADDR2INSTR_HASH_SIZE 1023
-#define addr2instr_hash(addr) (((addr) + ((addr) >> 8)) % ADDR2INSTR_HASH_SIZE)
+#define addr2instr_hash(addr) ((unsigned)((addr) + ((addr) >> 8)) % ADDR2INSTR_HASH_SIZE)
#define link_all2bi(A) ((BreakInstruction *)((char *)(A) - (int)&((BreakInstruction *)0)->link_all))
#define link_adr2bi(A) ((BreakInstruction *)((char *)(A) - (int)&((BreakInstruction *)0)->link_adr))
@@ -132,7 +142,7 @@ static int condition_expression_identifier(char * name, Value * v);
static ExpressionContext bp_address_ctx = { address_expression_identifier, NULL };
static ExpressionContext bp_condition_ctx = { condition_expression_identifier, NULL };
-static int id2bp_hash(char * id) {
+static unsigned id2bp_hash(char * id) {
unsigned hash = 0;
while (*id) hash = (hash >> 16) + hash + (unsigned char)*id++;
return hash % ID2BP_HASH_SIZE;
@@ -189,7 +199,7 @@ static void remove_instruction(BreakInstruction * bi) {
}
}
#else
- if (!bi->ctx->exited && bi->ctx->stopped) {
+ if (!bi->ctx->exited && !is_running(bi->ctx)) {
if (context_write_mem(bi->ctx, bi->address, bi->saved_code, BREAK_SIZE) < 0) {
bi->error = errno;
}
@@ -229,12 +239,12 @@ static void delete_unused_instructions(void) {
list_remove(&bi->link_all);
list_remove(&bi->link_adr);
if (bi->planted) {
- if (bi->ctx->exited || !bi->ctx->stopped) {
+ if (bi->ctx->exited || is_running(bi->ctx)) {
LINK * qp = context_root.next;
while (qp != &context_root) {
Context * ctx = ctxl2ctxp(qp);
qp = qp->next;
- if (ctx->mem == bi->ctx->mem && !ctx->exited && ctx->stopped) {
+ if (ctx->mem == bi->ctx->mem && !ctx->exited && !is_running(ctx)) {
assert(bi->ctx != ctx);
context_unlock(bi->ctx);
context_lock(ctx);
@@ -267,7 +277,7 @@ static BreakInstruction * find_instruction(Context * ctx, unsigned long address)
BreakInstruction * bi = link_adr2bi(l);
l = l->next;
if (bi->ctx->mem == ctx->mem && bi->address == address) {
- if (bi->ctx->exited || !bi->ctx->stopped) {
+ if (bi->ctx->exited || is_running(bi->ctx)) {
assert(bi->ctx != ctx);
context_unlock(bi->ctx);
context_lock(ctx);
@@ -368,6 +378,42 @@ static void address_expression_error(BreakpointInfo * bp, char * msg) {
snprintf(bp->err_msg, size, "Invalid breakpoint address '%s': %s", bp->address, msg);
}
+static void plant_breakpoint_in_context(BreakpointInfo * bp, Context * ctx, unsigned long address) {
+ BreakInstruction * bi = NULL;
+ bi = find_instruction(ctx, address);
+ if (bi == NULL) {
+ bi = add_instruction(ctx, address);
+ }
+ else if (bp->planted) {
+ int i = 0;
+ while (i < bi->ref_cnt && bi->refs[i] != bp) i++;
+ if (i < bi->ref_cnt) return;
+ }
+ if (bi->ref_cnt >= bi->ref_size) {
+ bi->ref_size = bi->ref_size == 0 ? 8 : bi->ref_size * 2;
+ bi->refs = (BreakpointInfo **)loc_realloc(bi->refs, sizeof(BreakpointInfo *) * bi->ref_size);
+ }
+ bi->refs[bi->ref_cnt++] = bp;
+ if (bi->ctx != ctx) bi->ctx_cnt++;
+ if (bi->error) {
+ if (!bp->error) bp->error = bi->error;
+ }
+ else {
+ bp->planted = 1;
+ bp->hit_count = 0;
+ }
+}
+
+typedef struct PlantBreakpointArgs {
+ BreakpointInfo * bp;
+ Context * ctx;
+} PlantBreakpointArgs;
+
+static void plant_breakpoint_address_iterator(void * x, unsigned long address) {
+ PlantBreakpointArgs * args = (PlantBreakpointArgs *)x;
+ plant_breakpoint_in_context(args->bp, args->ctx, address);
+}
+
static void plant_breakpoint(BreakpointInfo * bp) {
LINK * qp;
char * p = NULL;
@@ -382,45 +428,40 @@ static void plant_breakpoint(BreakpointInfo * bp) {
bp->err_msg = NULL;
}
- if (bp->address == NULL) {
- bp->error = ERR_INV_EXPRESSION;
- trace(LOG_ALWAYS, "No breakpoint address");
- return;
- }
- expression_context = NULL;
- if (evaluate_expression(&bp_address_ctx, bp->address, &v) < 0) {
- if (errno != ERR_INV_CONTEXT) {
- address_expression_error(bp, NULL);
+ if (bp->address != NULL) {
+ expression_context = NULL;
+ if (evaluate_expression(&bp_address_ctx, bp->address, &v) < 0) {
+ if (errno != ERR_INV_CONTEXT) {
+ address_expression_error(bp, NULL);
+ trace(LOG_ALWAYS, "Error: %s", bp->err_msg);
+ return;
+ }
+ context_sensitive = 1;
+ }
+ if (!context_sensitive && v.type != VALUE_INT && v.type != VALUE_UNS) {
+ errno = ERR_INV_EXPRESSION;
+ address_expression_error(bp, "Must be integer number");
trace(LOG_ALWAYS, "Error: %s", bp->err_msg);
return;
}
+ }
+#if SERVICE_LineNumbers
+ else if (bp->file != NULL) {
context_sensitive = 1;
}
- if (!context_sensitive && v.type != VALUE_INT && v.type != VALUE_UNS) {
- errno = ERR_INV_EXPRESSION;
- address_expression_error(bp, "Must be integer number");
- trace(LOG_ALWAYS, "Error: %s", bp->err_msg);
+#endif
+ else {
+ bp->error = ERR_INV_EXPRESSION;
+ trace(LOG_ALWAYS, "No breakpoint address");
return;
}
for (qp = context_root.next; qp != &context_root; qp = qp->next) {
- BreakInstruction * bi = NULL;
Context * ctx = ctxl2ctxp(qp);
- if (ctx->exited || ctx->exiting || !ctx->stopped) continue;
- if (context_sensitive) {
- expression_context = ctx;
- if (evaluate_expression(&bp_address_ctx, bp->address, &v) < 0) {
- address_expression_error(bp, NULL);
- trace(LOG_ALWAYS, "Error: %s", bp->err_msg);
- continue;
- }
- if (v.type != VALUE_INT && v.type != VALUE_UNS) {
- errno = ERR_INV_EXPRESSION;
- address_expression_error(bp, "Must be integer number");
- continue;
- }
- }
+ if (ctx->exited || ctx->exiting) continue;
+ if (is_running(ctx)) continue;
+
if (bp->condition != NULL) {
/* Optimize away the breakpoint if condition is always false for given context */
Value c;
@@ -437,31 +478,71 @@ static void plant_breakpoint(BreakpointInfo * bp) {
}
}
}
- bi = find_instruction(ctx, v.value);
- if (bi == NULL) {
- bi = add_instruction(ctx, v.value);
- }
- else if (bp->planted) {
- int i = 0;
- while (i < bi->ref_cnt && bi->refs[i] != bp) i++;
- if (i < bi->ref_cnt) continue;
- }
- if (bi->ref_cnt >= bi->ref_size) {
- bi->ref_size = bi->ref_size == 0 ? 8 : bi->ref_size * 2;
- bi->refs = (BreakpointInfo **)loc_realloc(bi->refs, sizeof(BreakpointInfo *) * bi->ref_size);
- }
- bi->refs[bi->ref_cnt++] = bp;
- if (bi->ctx != ctx) bi->ctx_cnt++;
- if (bi->error) {
- if (!bp->error) bp->error = bi->error;
+ if (context_sensitive) {
+ if (bp->address != NULL) {
+ expression_context = ctx;
+ if (evaluate_expression(&bp_address_ctx, bp->address, &v) < 0) {
+ address_expression_error(bp, NULL);
+ trace(LOG_ALWAYS, "BP Error: %s", bp->err_msg);
+ continue;
+ }
+ if (v.type != VALUE_INT && v.type != VALUE_UNS) {
+ errno = ERR_INV_EXPRESSION;
+ address_expression_error(bp, "Must be integer number");
+ continue;
+ }
+ plant_breakpoint_in_context(bp, ctx, v.value);
+ }
+#if SERVICE_LineNumbers
+ else if (bp->file != NULL) {
+ PlantBreakpointArgs args;
+ if (ctx->parent != NULL && ctx->mem == ctx->parent->mem) continue;
+ args.ctx = ctx;
+ args.bp = bp;
+ if (line_to_address(ctx, bp->file, bp->line, bp->column,
+ plant_breakpoint_address_iterator, &args) < 0) {
+ assert(errno != 0);
+ if (bp->error == 0) {
+ bp->error = errno;
+ assert(bp->err_msg == NULL);
+ bp->err_msg = loc_strdup(errno_to_str(bp->error));
+ trace(LOG_ALWAYS, "BP Error: %s", bp->err_msg);
+ }
+ }
+ }
+#endif
+ else {
+ assert(0);
+ }
}
else {
- bp->planted = 1;
+ if (ctx->parent != NULL && ctx->mem == ctx->parent->mem) continue;
+ plant_breakpoint_in_context(bp, ctx, v.value);
}
}
if (bp->planted) bp->error = 0;
}
+static void free_bp(BreakpointInfo * bp) {
+ list_remove(&bp->link_all);
+ list_remove(&bp->link_id);
+ loc_free(bp->err_msg);
+ loc_free(bp->address);
+#if SERVICE_LineNumbers
+ loc_free(bp->file);
+#endif
+ loc_free(bp->condition);
+ while (bp->unsupported != NULL) {
+ BreakpointAttribute * u = bp->unsupported;
+ bp->unsupported = u->next;
+ loc_free(u->name);
+ loc_free(u->value);
+ loc_free(u);
+ }
+ assert(list_is_empty(&bp->refs));
+ loc_free(bp);
+}
+
static void event_replant_breakpoints(void *arg) {
LINK * l = breakpoints.next;
replanting = 0;
@@ -470,12 +551,7 @@ static void event_replant_breakpoints(void *arg) {
BreakpointInfo * bp = link_all2bp(l);
l = l->next;
if (bp->deleted) {
- list_remove(&bp->link_all);
- list_remove(&bp->link_id);
- loc_free(bp->err_msg);
- loc_free(bp->address);
- loc_free(bp->condition);
- loc_free(bp);
+ free_bp(bp);
continue;
}
bp->planted = 0;
@@ -528,10 +604,38 @@ static int copy_breakpoint_info(BreakpointInfo * dst, BreakpointInfo * src) {
}
src->condition = NULL;
+#if SERVICE_LineNumbers
+ if (!str_equ(dst->file, src->file)) {
+ loc_free(dst->file);
+ dst->file = src->file;
+ res = 1;
+ }
+ else {
+ loc_free(src->file);
+ }
+ src->file = NULL;
+
+ if (dst->line != src->line) {
+ dst->line = src->line;
+ res = 1;
+ }
+
+ if (dst->column != src->column) {
+ dst->column = src->column;
+ res = 1;
+ }
+#endif
+
+ if (dst->skip_count != src->skip_count) {
+ dst->skip_count = src->skip_count;
+ res = 1;
+ }
+
if (dst->enabled != src->enabled) {
dst->enabled = src->enabled;
res = 1;
}
+
if (dst->unsupported != src->unsupported) {
while (dst->unsupported != NULL) {
BreakpointAttribute * u = dst->unsupported;
@@ -593,6 +697,20 @@ static void read_breakpoint_properties(InputStream * inp, BreakpointInfo * bp) {
else if (strcmp(name, "Condition") == 0) {
bp->condition = json_read_alloc_string(inp);
}
+#if SERVICE_LineNumbers
+ else if (strcmp(name, "File") == 0) {
+ bp->file = json_read_alloc_string(inp);
+ }
+ else if (strcmp(name, "Line") == 0) {
+ bp->line = json_read_long(inp);
+ }
+ else if (strcmp(name, "Column") == 0) {
+ bp->column = json_read_long(inp);
+ }
+#endif
+ else if (strcmp(name, "SkipCount") == 0) {
+ bp->skip_count = json_read_long(inp);
+ }
else if (strcmp(name, "Enabled") == 0) {
bp->enabled = json_read_boolean(inp);
}
@@ -634,6 +752,36 @@ static void write_breakpoint_properties(OutputStream * out, BreakpointInfo * bp)
json_write_string(out, bp->condition);
}
+#if SERVICE_LineNumbers
+ if (bp->file != NULL) {
+ out->write(out, ',');
+ json_write_string(out, "File");
+ out->write(out, ':');
+ json_write_string(out, bp->file);
+ }
+
+ if (bp->line > 0) {
+ out->write(out, ',');
+ json_write_string(out, "Line");
+ out->write(out, ':');
+ json_write_long(out, bp->line);
+ }
+
+ if (bp->column > 0) {
+ out->write(out, ',');
+ json_write_string(out, "Column");
+ out->write(out, ':');
+ json_write_long(out, bp->column);
+ }
+#endif
+
+ if (bp->skip_count > 0) {
+ out->write(out, ',');
+ json_write_string(out, "SkipCount");
+ out->write(out, ':');
+ json_write_long(out, bp->skip_count);
+ }
+
if (bp->enabled) {
out->write(out, ',');
json_write_string(out, "Enabled");
@@ -645,7 +793,7 @@ static void write_breakpoint_properties(OutputStream * out, BreakpointInfo * bp)
out->write(out, ',');
json_write_string(out, u->name);
out->write(out, ':');
- json_write_string(out, u->value);
+ write_string(out, u->value);
u = u->next;
}
@@ -709,7 +857,7 @@ static void add_breakpoint(InputStream * inp, OutputStream * out, BreakpointInfo
}
r = find_breakpoint_ref(p, inp);
if (r == NULL) {
- int inp_hash = (int)inp / 16 % INP2BR_HASH_SIZE;
+ unsigned inp_hash = (unsigned)inp / 16 % INP2BR_HASH_SIZE;
r = (BreakpointRef *)loc_alloc_zero(sizeof(BreakpointRef));
list_add_last(&r->link_inp, inp2br + inp_hash);
list_add_last(&r->link_bp, &p->refs);
@@ -735,11 +883,7 @@ static void remove_breakpoint(OutputStream * out, BreakpointInfo * bp) {
replant_breakpoints();
}
else {
- list_remove(&bp->link_all);
- list_remove(&bp->link_id);
- loc_free(bp->address);
- loc_free(bp->condition);
- loc_free(bp);
+ free_bp(bp);
}
}
@@ -752,7 +896,7 @@ static void remove_ref(OutputStream * out, BreakpointRef * br) {
}
static void delete_breakpoint_refs(InputStream * inp, OutputStream * out) {
- int hash = (int)inp / 16 % INP2BR_HASH_SIZE;
+ unsigned hash = (unsigned)inp / 16 % INP2BR_HASH_SIZE;
LINK * l = inp2br[hash].next;
while (l != &inp2br[hash]) {
BreakpointRef * br = link_inp2br(l);
@@ -788,7 +932,7 @@ static void command_ini_bps(char * token, Channel * c) {
}
static void command_get_bp_ids(char * token, Channel * c) {
- int hash = (int)&c->inp / 16 % INP2BR_HASH_SIZE;
+ unsigned hash = (unsigned)&c->inp / 16 % INP2BR_HASH_SIZE;
LINK * l = inp2br[hash].next;
int cnt = 0;
@@ -846,10 +990,11 @@ static void command_get_status(char * token, Channel * c) {
static void command_bp_add(char * token, Channel * c) {
BreakpointInfo bp;
read_breakpoint_properties(&c->inp, &bp);
- add_breakpoint(&c->inp, &c->bcg->out, &bp);
if (c->inp.read(&c->inp) != 0) exception(ERR_JSON_SYNTAX);
if (c->inp.read(&c->inp) != MARKER_EOM) exception(ERR_JSON_SYNTAX);
+ add_breakpoint(&c->inp, &c->bcg->out, &bp);
+
write_stringz(&c->out, "R");
write_stringz(&c->out, token);
write_errno(&c->out, 0);
@@ -858,16 +1003,12 @@ static void command_bp_add(char * token, Channel * c) {
static void command_bp_change(char * token, Channel * c) {
BreakpointInfo bp;
- BreakpointInfo * p;
read_breakpoint_properties(&c->inp, &bp);
- p = find_breakpoint(bp.id);
- if (p != NULL && copy_breakpoint_info(p, &bp)) {
- if (p->planted || p->enabled && p->unsupported == NULL) replant_breakpoints();
- send_event_context_changed(&c->bcg->out, p);
- }
if (c->inp.read(&c->inp) != 0) exception(ERR_JSON_SYNTAX);
if (c->inp.read(&c->inp) != MARKER_EOM) exception(ERR_JSON_SYNTAX);
+ add_breakpoint(&c->inp, &c->bcg->out, &bp);
+
write_stringz(&c->out, "R");
write_stringz(&c->out, token);
write_errno(&c->out, 0);
@@ -986,6 +1127,24 @@ static void command_get_capabilities(char * token, Channel * c) {
json_write_string(&c->out, "Address");
c->out.write(&c->out, ':');
json_write_boolean(&c->out, 1);
+#if SERVICE_LineNumbers
+ c->out.write(&c->out, ',');
+ json_write_string(&c->out, "File");
+ c->out.write(&c->out, ':');
+ json_write_boolean(&c->out, 1);
+ c->out.write(&c->out, ',');
+ json_write_string(&c->out, "Line");
+ c->out.write(&c->out, ':');
+ json_write_boolean(&c->out, 1);
+ c->out.write(&c->out, ',');
+ json_write_string(&c->out, "Column");
+ c->out.write(&c->out, ':');
+ json_write_boolean(&c->out, 1);
+#endif
+ c->out.write(&c->out, ',');
+ json_write_string(&c->out, "SkipCount");
+ c->out.write(&c->out, ':');
+ json_write_boolean(&c->out, 1);
c->out.write(&c->out, ',');
json_write_string(&c->out, "Condition");
c->out.write(&c->out, ':');
@@ -1011,27 +1170,34 @@ int evaluate_breakpoint_condition(Context * ctx) {
if (bi == NULL) return 0;
expression_context = ctx;
for (i = 0; i < bi->ref_cnt; i++) {
- Value v;
BreakpointInfo * bp = bi->refs[i];
assert(bp->planted);
assert(bp->error == 0);
if (bp->deleted) continue;
if (bp->unsupported != NULL) continue;
if (!bp->enabled) continue;
- if (bp->condition == NULL) return 1;
- if (evaluate_expression(&bp_condition_ctx, bp->condition, &v) < 0) {
- trace(LOG_ALWAYS, "%s: %s", get_expression_error_msg(), bp->condition);
- return 1;
+ if (bp->condition != NULL) {
+ Value v;
+ if (evaluate_expression(&bp_condition_ctx, bp->condition, &v) < 0) {
+ trace(LOG_ALWAYS, "%s: %s", get_expression_error_msg(), bp->condition);
+ return 1;
+ }
+ switch (v.type) {
+ case VALUE_INT:
+ case VALUE_UNS:
+ if (v.value == 0) continue;
+ break;
+ case VALUE_STR:
+ if (v.str == NULL) continue;
+ break;
+ }
}
- switch (v.type) {
- case VALUE_INT:
- case VALUE_UNS:
- if (v.value) return 1;
- break;
- case VALUE_STR:
- if (v.str != NULL) return 1;
- break;
+ if (bp->skip_count > 0) {
+ bp->hit_count++;
+ if (bp->hit_count < bp->skip_count) continue;
+ bp->hit_count = 0;
}
+ return 1;
}
return 0;
}
diff --git a/context.c b/context.c
index e90c682a..31341168 100644
--- a/context.c
+++ b/context.c
@@ -26,7 +26,7 @@
#include "breakpoints.h"
#define CONTEXT_PID_ROOT_SIZE 1024
-#define CONTEXT_PID_HASH(PID) ((PID) % CONTEXT_PID_ROOT_SIZE)
+#define CONTEXT_PID_HASH(PID) ((unsigned)(PID) % CONTEXT_PID_ROOT_SIZE)
static LINK context_pid_root[CONTEXT_PID_ROOT_SIZE];
static ContextEventListener * event_listeners = NULL;
@@ -468,12 +468,14 @@ static void debug_event_handler(void * x) {
case EXCEPTION_DEBUG_EVENT:
if (ctx == NULL) break;
assert(ctx->pending_event.ExceptionRecord.ExceptionCode == 0);
- args->continue_status = DBG_EXCEPTION_NOT_HANDLED;
switch (args->event.u.Exception.ExceptionRecord.ExceptionCode) {
case EXCEPTION_SINGLE_STEP:
case EXCEPTION_BREAKPOINT:
args->continue_status = DBG_CONTINUE;
break;
+ default:
+ args->continue_status = DBG_EXCEPTION_NOT_HANDLED;
+ break;
}
memcpy(&ctx->pending_event, &args->event.u.Exception, sizeof(EXCEPTION_DEBUG_INFO));
if (!ctx->stopped) event_win32_context_stopped(ctx);
@@ -522,7 +524,6 @@ static DWORD WINAPI debugger_thread_func(LPVOID x) {
DebugEvent create_process;
DebugEvent fantom_process;
int state = 0;
- int abort = 0;
if (event_semaphore == NULL) {
args->error = GetLastError();
@@ -543,7 +544,7 @@ static DWORD WINAPI debugger_thread_func(LPVOID x) {
memset(&create_process, 0, sizeof(create_process));
memset(&fantom_process, 0, sizeof(fantom_process));
- while (!abort) {
+ while (1) {
DebugEvent * buf = NULL;
DEBUG_EVENT * debug_event = &event_buffer.event;
@@ -585,6 +586,8 @@ static DWORD WINAPI debugger_thread_func(LPVOID x) {
case LOAD_DLL_DEBUG_EVENT:
CloseHandle(debug_event->u.LoadDll.hFile);
break;
+ case UNLOAD_DLL_DEBUG_EVENT:
+ break;
default:
if (fantom_process.event.dwThreadId == debug_event->dwThreadId) {
if (debug_event->dwDebugEventCode == EXIT_THREAD_DEBUG_EVENT) {
@@ -602,6 +605,11 @@ static DWORD WINAPI debugger_thread_func(LPVOID x) {
/* ResumeThread(fantom_process.event.u.CreateProcessInfo.hThread); */
fantom_process.event.u.CreateProcessInfo.hThread = NULL;
}
+ if (state == 0) {
+ if (debug_event->dwDebugEventCode == EXCEPTION_DEBUG_EVENT) {
+ event_buffer.continue_status = DBG_EXCEPTION_NOT_HANDLED;
+ }
+ }
if (state == 1) {
create_process.event_semaphore = event_semaphore;
post_event(debug_event_handler, &create_process);
@@ -623,12 +631,8 @@ static DWORD WINAPI debugger_thread_func(LPVOID x) {
break;
}
- switch (debug_event->dwDebugEventCode) {
- case EXIT_PROCESS_DEBUG_EVENT:
- case RIP_EVENT:
- abort = 1;
- break;
- }
+ if (debug_event->dwDebugEventCode == EXIT_PROCESS_DEBUG_EVENT) break;
+ if (debug_event->dwDebugEventCode == RIP_EVENT) break;
}
if (state < 2) ReleaseSemaphore(args->debug_thread_semaphore, 1, 0);
diff --git a/context.h b/context.h
index fd2c6f50..593f13d7 100644
--- a/context.h
+++ b/context.h
@@ -65,6 +65,7 @@ struct Context {
LPVOID base_address;
EXCEPTION_DEBUG_INFO pending_event;
EXCEPTION_DEBUG_INFO suspend_reason;
+ int sym_handler_loaded;
#endif
};
diff --git a/dbghelp.dll b/dbghelp.dll
new file mode 100644
index 00000000..4abd2b09
--- /dev/null
+++ b/dbghelp.dll
Binary files differ
diff --git a/dwarfio.c b/dwarfio.c
index b056c6cf..4a6584c5 100644
--- a/dwarfio.c
+++ b/dwarfio.c
@@ -211,7 +211,7 @@ U8_T dio_ReadU8(void) {
return sBigEndian ? (x0 << 32) | x1 : x0 | (x1 << 32);
}
-U4_T dio_ReadLEB128(void) {
+U4_T dio_ReadULEB128(void) {
U4_T res = 0;
int i = 0;
for (;; i += 7) {
@@ -222,6 +222,20 @@ U4_T dio_ReadLEB128(void) {
return res;
}
+I4_T dio_ReadSLEB128(void) {
+ U4_T res = 0;
+ int i = 0;
+ for (;; i += 7) {
+ U1_T n = dio_ReadU1();
+ res |= (n & 0x7Fu) << i;
+ if ((n & 0x80) == 0) {
+ res |= -(n & 0x40) << i;
+ break;
+ }
+ }
+ return (I4_T)res;
+}
+
U8_T dio_ReadU8LEB128(void) {
U8_T res = 0;
int i = 0;
@@ -233,7 +247,7 @@ U8_T dio_ReadU8LEB128(void) {
return res;
}
-I8_T dio_ReadI8LEB128(void) {
+I8_T dio_ReadS8LEB128(void) {
U8_T res = 0;
int i = 0;
for (;; i += 7) {
@@ -421,12 +435,12 @@ static void dio_ReadAttribute(U2_T Attr, U2_T Form) {
case FORM_BLOCK1 : dio_ReadFormBlock(Attr, dio_ReadU1()); break;
case FORM_BLOCK2 : dio_ReadFormBlock(Attr, dio_ReadU2()); break;
case FORM_BLOCK4 : dio_ReadFormBlock(Attr, dio_ReadU4()); break;
- case FORM_BLOCK : dio_ReadFormBlock(Attr, dio_ReadLEB128()); break;
+ case FORM_BLOCK : dio_ReadFormBlock(Attr, dio_ReadULEB128()); break;
case FORM_DATA1 : dio_ReadFormData(Attr, 1, dio_ReadU1()); break;
case FORM_DATA2 : dio_ReadFormData(Attr, 2, dio_ReadU2()); break;
case FORM_DATA4 : dio_ReadFormData(Attr, 4, dio_ReadU4()); break;
case FORM_DATA8 : dio_ReadFormData(Attr, 8, dio_ReadU8()); break;
- case FORM_SDATA : dio_ReadFormData(Attr, 8, dio_ReadI8LEB128()); break;
+ case FORM_SDATA : dio_ReadFormData(Attr, 8, dio_ReadS8LEB128()); break;
case FORM_UDATA : dio_ReadFormData(Attr, 8, dio_ReadU8LEB128()); break;
case FORM_FLAG : dio_ReadFormFlag(); break;
case FORM_STRING : dio_ReadFormString(); break;
@@ -436,7 +450,7 @@ static void dio_ReadAttribute(U2_T Attr, U2_T Form) {
case FORM_REF2 : dio_ReadFormRelRef(dio_ReadU2()); break;
case FORM_REF4 : dio_ReadFormRelRef(dio_ReadU4()); break;
case FORM_REF8 : dio_ReadFormRelRef(dio_ReadU8()); break;
- case FORM_REF_UDATA : dio_ReadFormRelRef(dio_ReadLEB128()); break;
+ case FORM_REF_UDATA : dio_ReadFormRelRef(dio_ReadULEB128()); break;
default: str_exception(ERR_DWARF, "invalid FORM");
}
}
@@ -449,7 +463,7 @@ static void dio_ReadEntry(DIO_EntryCallBack CallBack) {
int Init = 1;
dio_gEntryPos = dio_GetPos();
if (dio_gVersion >= 2) {
- U4_T AbbrCode = dio_ReadLEB128();
+ U4_T AbbrCode = dio_ReadULEB128();
if (AbbrCode == 0) return;
if (AbbrCode >= sAbbrevTableSize || sAbbrevTable[AbbrCode] == NULL) {
str_exception(ERR_DWARF, "invalid abbreviation table");
@@ -479,7 +493,7 @@ static void dio_ReadEntry(DIO_EntryCallBack CallBack) {
if (AttrPos < Abbr->mAttrLen) {
Attr = Abbr->mAttrs[AttrPos++];
Form = Abbr->mAttrs[AttrPos++];
- if (Form == FORM_INDIRECT) Form = (U2_T)dio_ReadLEB128();
+ if (Form == FORM_INDIRECT) Form = (U2_T)dio_ReadULEB128();
}
}
else {
@@ -537,7 +551,7 @@ void dio_ReadUnit(DIO_EntryCallBack CallBack) {
}
}
-#define dio_AbbrevTableHash(File, Offset) (((int)(File) + (int)(Offset)) / 4 % ABBREV_TABLE_SIZE)
+#define dio_AbbrevTableHash(File, Offset) (((unsigned)(File) + (unsigned)(Offset)) / 16 % ABBREV_TABLE_SIZE)
static int dio_IsAbbrevSectionLoaded(ELF_File * File) {
DIO_Cache * Cache = dio_GetCache(File);
@@ -580,7 +594,7 @@ void dio_LoadAbbrevTable(ELF_File * File) {
U4_T AttrPos = 0;
U2_T Tag = 0;
U1_T Children = 0;
- U4_T ID = dio_ReadLEB128();
+ U4_T ID = dio_ReadULEB128();
if (ID == 0) {
/* End of compilation unit */
U4_T Hash = dio_AbbrevTableHash(File, TableOffset);
@@ -607,11 +621,11 @@ void dio_LoadAbbrevTable(ELF_File * File) {
AbbrevTable = (DIO_Abbreviation **)loc_realloc(AbbrevTable, sizeof(DIO_Abbreviation *) * AbbrevTableSize);
memset(AbbrevTable + Size, 0, sizeof(DIO_Abbreviation *) * (AbbrevTableSize - Size));
}
- Tag = (U2_T)dio_ReadLEB128();
+ Tag = (U2_T)dio_ReadULEB128();
Children = (U2_T)dio_ReadU1() != 0;
for (;;) {
- U4_T Attr = dio_ReadLEB128();
- U4_T Form = dio_ReadLEB128();
+ U4_T Attr = dio_ReadULEB128();
+ U4_T Form = dio_ReadULEB128();
if (Attr >= 0x10000 || Form >= 0x10000) str_exception(ERR_DWARF, "invalid abbreviation table");
if (Attr == 0 && Form == 0) {
DIO_Abbreviation * Abbr = AbbrevTable[ID];
diff --git a/dwarfio.h b/dwarfio.h
index f45edb1c..46af8756 100644
--- a/dwarfio.h
+++ b/dwarfio.h
@@ -44,9 +44,10 @@ extern U2_T dio_ReadU2(void);
extern U4_T dio_ReadU4(void);
extern U8_T dio_ReadU8(void);
-extern U4_T dio_ReadLEB128(void);
+extern U4_T dio_ReadULEB128(void);
+extern I4_T dio_ReadSLEB128(void);
extern U8_T dio_ReadU8LEB128(void);
-extern I8_T dio_ReadI8LEB128(void);
+extern I8_T dio_ReadS8LEB128(void);
extern U8_T dio_ReadUX(int Size);
extern U8_T dio_ReadAddress(void);
diff --git a/errors.c b/errors.c
index 2a62ab18..61f89b7e 100644
--- a/errors.c
+++ b/errors.c
@@ -46,7 +46,7 @@ static char * system_strerror(void) {
}
else {
int l;
- strncpy(msg, (char *)msg_buf, sizeof(msg));
+ snprintf(msg, sizeof(msg), "0x%08x: %s", errno_win32, msg_buf, sizeof(msg));
LocalFree(msg_buf);
l = strlen(msg);
while (l > 0 && (msg[l - 1] == '\n' || msg[l - 1] == '\r')) l--;
diff --git a/linenumbers.h b/linenumbers.h
index 04dc32c6..0d6c0172 100644
--- a/linenumbers.h
+++ b/linenumbers.h
@@ -19,6 +19,11 @@
#define D_linenumbers
#include "protocol.h"
+#include "context.h"
+
+typedef void (*line_to_address_callback)(void *, unsigned long);
+
+extern int line_to_address(Context * ctx, char * file, int line, int column, line_to_address_callback, void * args);
/*
* Initialize Line Numbers service.
diff --git a/linenumbers_elf.c b/linenumbers_elf.c
index 8ca8dc65..64fe1ce6 100644
--- a/linenumbers_elf.c
+++ b/linenumbers_elf.c
@@ -316,10 +316,10 @@ static void load_line_numbers(LineNumbersCache * cache, CompUnit * unit) {
memset(&file, 0, sizeof(file));
file.name = dio_ReadString();
if (file.name == NULL) break;
- dir = dio_ReadLEB128();
+ dir = dio_ReadULEB128();
if (dir > 0 && dir <= unit->dirs_cnt) file.dir = unit->dirs[dir - 1];
- file.mtime = dio_ReadLEB128();
- file.size = dio_ReadLEB128();
+ file.mtime = dio_ReadULEB128();
+ file.size = dio_ReadULEB128();
add_file(unit, &file);
}
@@ -341,7 +341,7 @@ static void load_line_numbers(LineNumbersCache * cache, CompUnit * unit) {
state.epilogue_begin = 0;
}
else if (opcode == 0) {
- U4_T op_size = dio_ReadLEB128();
+ U4_T op_size = dio_ReadULEB128();
U8_T op_pos = dio_GetPos();
switch (dio_ReadU1()) {
case DW_LNE_define_file: {
@@ -349,10 +349,10 @@ static void load_line_numbers(LineNumbersCache * cache, CompUnit * unit) {
FileInfo file;
memset(&file, 0, sizeof(file));
file.name = dio_ReadString();
- dir = dio_ReadLEB128();
+ dir = dio_ReadULEB128();
if (dir > 0 && dir <= unit->dirs_cnt) file.dir = unit->dirs[dir - 1];
- file.mtime = dio_ReadLEB128();
- file.size = dio_ReadLEB128();
+ file.mtime = dio_ReadULEB128();
+ file.size = dio_ReadULEB128();
add_file(unit, &file);
break;
}
@@ -385,13 +385,13 @@ static void load_line_numbers(LineNumbersCache * cache, CompUnit * unit) {
state.address += (ADDR_T)(dio_ReadU8LEB128() * min_instruction_length);
break;
case DW_LNS_advance_line:
- state.line += dio_ReadLEB128();
+ state.line += dio_ReadSLEB128();
break;
case DW_LNS_set_file:
- state.file = dio_ReadLEB128();
+ state.file = dio_ReadULEB128();
break;
case DW_LNS_set_column:
- state.column = dio_ReadLEB128();
+ state.column = dio_ReadULEB128();
break;
case DW_LNS_negate_stmt:
state.is_stmt = !state.is_stmt;
@@ -412,7 +412,7 @@ static void load_line_numbers(LineNumbersCache * cache, CompUnit * unit) {
state.epilogue_begin = 1;
break;
case DW_LNS_set_isa:
- state.isa = (U1_T)dio_ReadLEB128();
+ state.isa = (U1_T)dio_ReadULEB128();
break;
default:
str_exception(ERR_DWARF, "Invalid line info op code");
@@ -488,6 +488,86 @@ static void load_line_numbers_in_range(LineNumbersCache * cache, ADDR_T addr0, A
}
}
+static int cmp_file(char * file, char * dir, char * name) {
+ int i;
+ if (file == NULL) return 0;
+ if (name == NULL) return 0;
+ if (strcmp(file, name) == 0) return 1;
+ i = strlen(name);
+ while (i > 0 && name[i - 1] != '/' && name[i - 1] != '\\') i--;
+ if (strcmp(file, name + i) == 0) return 1;
+ if (dir == NULL) return 0;
+ i = strlen(dir);
+ if (strncmp(dir, file, i) == 0 && (file[i] == '/' || file[i] == '\\') &&
+ strcmp(file + i + 1, name) == 0) return 1;
+ return 0;
+}
+
+int line_to_address(Context * ctx, char * file, int line, int column, line_to_address_callback callback, void * user_args) {
+ int err = 0;
+ Trap trap;
+ LineNumbersCache * cache = NULL;
+
+ if (ctx == NULL) err = ERR_INV_CONTEXT;
+ else if (ctx->exited) err = ERR_ALREADY_EXITED;
+
+ if (err == 0) {
+ if (set_trap(&trap)) {
+ int i;
+ cache = get_line_numbers_cache(ctx);
+ for (i = 0; i < cache->units_cnt; i++) {
+ CompUnit * unit = cache->units + i;
+ int equ = 0;
+ if (unit->dir != NULL && unit->name != NULL) {
+ equ = cmp_file(file, unit->dir, unit->name);
+ }
+ if (!equ) {
+ int j;
+ for (j = 0; j < unit->files_cnt; j++) {
+ FileInfo * f = unit->files + j;
+ if (f->dir != NULL && f->name != NULL) {
+ equ = cmp_file(file, f->dir, f->name);
+ if (equ) break;
+ }
+ }
+ }
+ if (equ) {
+ int j;
+ load_line_numbers(cache, unit);
+ for (j = 0; j < unit->states_cnt - 1; j++) {
+ LineNumbersState * state = unit->states + j;
+ LineNumbersState * next = unit->states + j + 1;
+ char * state_dir = unit->dir;
+ char * state_name = unit->name;
+ if (state->end_sequence) continue;
+ if (line < state->line) continue;
+ if (line >= next->line) continue;
+ if (state->file >= 1 && state->file <= unit->files_cnt) {
+ FileInfo * f = unit->files + (state->file - 1);
+ state_dir = f->dir;
+ state_name = f->name;
+ }
+ if (!cmp_file(file, state_dir, state_name)) continue;
+ callback(user_args, state->address);
+ }
+ }
+ }
+ clear_trap(&trap);
+ }
+ else {
+ err = trap.error;
+ }
+ }
+
+ if (cache != NULL) elf_close(cache->file);
+
+ if (err != 0) {
+ errno = err;
+ return -1;
+ }
+ return 0;
+}
+
static void command_map_to_source(char * token, Channel * c) {
int err = 0;
char * err_msg = NULL;
@@ -548,22 +628,22 @@ static void command_map_to_source(char * token, Channel * c) {
c->out.write(&c->out, '{');
json_write_string(&c->out, "SLine");
c->out.write(&c->out, ':');
- json_write_ulong(&c->out, state->line - 1);
+ json_write_ulong(&c->out, state->line);
if (state->column > 0) {
c->out.write(&c->out, ',');
json_write_string(&c->out, "SCol");
c->out.write(&c->out, ':');
- json_write_ulong(&c->out, state->column - 1);
+ json_write_ulong(&c->out, state->column);
}
c->out.write(&c->out, ',');
json_write_string(&c->out, "ELine");
c->out.write(&c->out, ':');
- json_write_ulong(&c->out, next->line - 1);
+ json_write_ulong(&c->out, next->line);
if (next->column > 0) {
c->out.write(&c->out, ',');
json_write_string(&c->out, "ECol");
c->out.write(&c->out, ':');
- json_write_ulong(&c->out, next->column - 1);
+ json_write_ulong(&c->out, next->column);
}
state_file = NULL;
if (state->file >= 1 && state->file <= unit->files_cnt) {
diff --git a/linenumbers_win32.c b/linenumbers_win32.c
index 82454b77..ebbbec45 100644
--- a/linenumbers_win32.c
+++ b/linenumbers_win32.c
@@ -34,9 +34,69 @@
static const char * LINENUMBERS = "LineNumbers";
+typedef struct LineToAddressArgs {
+ Context * ctx;
+ char * file;
+ int line;
+ line_to_address_callback callback;
+ void * user_args;
+ int error;
+} LineToAddressArgs;
+
+static BOOL CALLBACK line_to_address_iterator(PSTR module_name, DWORD base_address, PVOID x) {
+ DWORD offset = 0;
+ IMAGEHLP_LINE line;
+ LineToAddressArgs * args = (LineToAddressArgs *)x;
+
+ memset(&line, 0, sizeof(line));
+ line.SizeOfStruct = sizeof(IMAGEHLP_LINE);
+
+ if (args->error == 0 && !SymGetLineFromName(args->ctx->handle, module_name, args->file, args->line, &offset, &line)) {
+ set_win32_errno(GetLastError());
+ args->error = errno;
+ }
+ if (args->error == 0) {
+ args->callback(args->user_args, line.Address);
+ }
+ return args->error == 0;
+}
+
+int line_to_address(Context * ctx, char * file, int line, int column, line_to_address_callback callback, void * user_args) {
+ int err = 0;
+
+ if (ctx == NULL) err = ERR_INV_CONTEXT;
+ else if (ctx->exited) err = ERR_ALREADY_EXITED;
+
+ if (err == 0 && ctx->parent != NULL) ctx = ctx->parent;
+ if (err == 0 && set_symbol_context(ctx) != 0) err = errno;
+
+ if (err == 0) {
+ LineToAddressArgs args;
+ args.ctx = ctx;
+ args.file = file;
+ args.line = line;
+ args.callback = callback;
+ args.user_args = user_args;
+ args.error = 0;
+ if (!SymEnumerateModules(ctx->handle, line_to_address_iterator, &args)) {
+ set_win32_errno(GetLastError());
+ err = errno;
+ }
+ else {
+ err = args.error;
+ }
+ }
+
+ if (err != 0) {
+ errno = err;
+ return -1;
+ }
+ return 0;
+}
+
static void command_map_to_source(char * token, Channel * c) {
int err = 0;
- char * err_msg = NULL;
+ int not_found = 0;
char id[256];
unsigned long addr0;
unsigned long addr1;
@@ -64,19 +124,25 @@ static void command_map_to_source(char * token, Channel * c) {
line.SizeOfStruct = sizeof(IMAGEHLP_LINE);
if (err == 0 && !SymGetLineFromAddr(ctx->handle, addr0, &offset, &line)) {
- set_win32_errno(GetLastError());
- err = errno;
+ DWORD w = GetLastError();
+ if (w == ERROR_MOD_NOT_FOUND) {
+ not_found = 1;
+ }
+ else {
+ set_win32_errno(w);
+ err = errno;
+ }
}
memcpy(&next, &line, sizeof(next));
- if (err == 0 && !SymGetLineNext(ctx->handle, &next)) {
+ if (err == 0 && !not_found && !SymGetLineNext(ctx->handle, &next)) {
set_win32_errno(GetLastError());
err = errno;
}
write_stringz(&c->out, "R");
write_stringz(&c->out, token);
- write_err_msg(&c->out, err, err_msg);
- if (err != 0) {
+ write_errno(&c->out, err);
+ if (err != 0 || not_found) {
write_stringz(&c->out, "null");
}
else {
diff --git a/peer.c b/peer.c
index 398a7cfa..d7ab3669 100644
--- a/peer.c
+++ b/peer.c
@@ -197,15 +197,13 @@ PeerServer * peer_server_add(PeerServer * n, unsigned int stale_delta) {
}
/* Find peer server based on ID */
-PeerServer * peer_server_find(const char *id) {
- PeerServerList *pi = &peer_server_list;
+PeerServer * peer_server_find(const char * id) {
+ PeerServerList * pi = &peer_server_list;
PeerServer * s;
assert(is_dispatch_thread());
for (s = pi->root; s != NULL; s = s->next) {
- if (strcmp(s->id, id) == 0) {
- return s;
- }
+ if (strcmp(s->id, id) == 0) return s;
}
return NULL;
}
diff --git a/protocol.c b/protocol.c
index 24f80491..a1cab5b5 100644
--- a/protocol.c
+++ b/protocol.c
@@ -124,16 +124,16 @@ static void free_services(void * owner) {
}
}
-static int message_hash(Protocol *p, const char * service, const char * name) {
+static unsigned message_hash(Protocol * p, const char * service, const char * name) {
int i;
- int h = (unsigned long)p;
+ unsigned h = (unsigned)p;
for (i = 0; service[i]; i++) h += service[i];
for (i = 0; name[i]; i++) h += name[i];
h = h + h / MESSAGE_HASH_SIZE;
return h % MESSAGE_HASH_SIZE;
}
-static MessageHandlerInfo * find_message_handler(Protocol *p, char * service, char * name) {
+static MessageHandlerInfo * find_message_handler(Protocol * p, char * service, char * name) {
MessageHandlerInfo * mh = message_handlers[message_hash(p, service, name)];
while (mh != NULL) {
if (mh->p == p && !strcmp(mh->service->name, service) && !strcmp(mh->name, name)) return mh;
@@ -142,16 +142,16 @@ static MessageHandlerInfo * find_message_handler(Protocol *p, char * service, ch
return NULL;
}
-static int event_hash(Channel *c, const char * service, const char * name) {
+static unsigned event_hash(Channel * c, const char * service, const char * name) {
int i;
- int h = (unsigned long)c;
+ unsigned h = (unsigned)c;
for (i = 0; service[i]; i++) h += service[i];
for (i = 0; name[i]; i++) h += name[i];
h = h + h / EVENT_HASH_SIZE;
return h % EVENT_HASH_SIZE;
}
-static EventHandlerInfo * find_event_handler(Channel *c, char * service, char * name) {
+static EventHandlerInfo * find_event_handler(Channel * c, char * service, char * name) {
EventHandlerInfo * mh = event_handlers[event_hash(c, service, name)];
while (mh != NULL) {
if (mh->c == c && !strcmp(mh->service->name, service) && !strcmp(mh->name, name)) return mh;
@@ -160,11 +160,11 @@ static EventHandlerInfo * find_event_handler(Channel *c, char * service, char *
return NULL;
}
-#define reply_hash(c, tokenid) ((((unsigned long)c)+(tokenid)) % REPLY_HASH_SIZE)
+#define reply_hash(c, tokenid) (((unsigned)(c)+(unsigned)(tokenid)) % REPLY_HASH_SIZE)
-static ReplyHandlerInfo * find_reply_handler(Channel *c, unsigned long tokenid, int take) {
- ReplyHandlerInfo **rhp = &reply_handlers[reply_hash(c, tokenid)];
- ReplyHandlerInfo *rh;
+static ReplyHandlerInfo * find_reply_handler(Channel * c, unsigned long tokenid, int take) {
+ ReplyHandlerInfo ** rhp = &reply_handlers[reply_hash(c, tokenid)];
+ ReplyHandlerInfo * rh;
while ((rh = *rhp) != NULL) {
if (rh->c == c && rh->tokenid == tokenid) {
if (take) {
@@ -314,8 +314,8 @@ void set_default_message_handler(Protocol *p, ProtocolMessageHandler handler) {
p->default_handler = handler;
}
-void add_command_handler(Protocol *p, const char * service, const char * name, ProtocolCommandHandler handler) {
- int h = message_hash(p, service, name);
+void add_command_handler(Protocol * p, const char * service, const char * name, ProtocolCommandHandler handler) {
+ unsigned h = message_hash(p, service, name);
MessageHandlerInfo * mh = (MessageHandlerInfo *)loc_alloc(sizeof(MessageHandlerInfo));
mh->p = p;
mh->service = protocol_get_service(p, service);
@@ -325,8 +325,8 @@ void add_command_handler(Protocol *p, const char * service, const char * name, P
message_handlers[h] = mh;
}
-void add_event_handler(Channel *c, const char * service, const char * name, ProtocolEventHandler handler) {
- int h = event_hash(c, service, name);
+void add_event_handler(Channel * c, const char * service, const char * name, ProtocolEventHandler handler) {
+ unsigned h = event_hash(c, service, name);
EventHandlerInfo * eh = (EventHandlerInfo *)loc_alloc(sizeof(EventHandlerInfo));
eh->c = c;
eh->service = protocol_get_service(c, service);
@@ -336,7 +336,7 @@ void add_event_handler(Channel *c, const char * service, const char * name, Prot
event_handlers[h] = eh;
}
-ReplyHandlerInfo *protocol_send_command(Protocol *p, Channel *c, const char *service, const char *name, ReplyHandlerCB handler, void *client_data) {
+ReplyHandlerInfo * protocol_send_command(Protocol * p, Channel * c, const char *service, const char *name, ReplyHandlerCB handler, void *client_data) {
ReplyHandlerInfo *rh;
int h;
unsigned long tokenid;
@@ -360,7 +360,7 @@ ReplyHandlerInfo *protocol_send_command(Protocol *p, Channel *c, const char *ser
return rh;
}
-void send_hello_message(Protocol *p, Channel *c) {
+void send_hello_message(Protocol * p, Channel * c) {
ServiceInfo * s = services;
int cnt = 0;
@@ -381,7 +381,7 @@ void send_hello_message(Protocol *p, Channel *c) {
c->out.write(&c->out, MARKER_EOM);
}
-static void command_sync(char * token, Channel *c) {
+static void command_sync(char * token, Channel * c) {
if (c->inp.read(&c->inp) != MARKER_EOM) exception(ERR_JSON_SYNTAX);
write_stringz(&c->out, "R");
write_stringz(&c->out, token);
@@ -389,7 +389,7 @@ static void command_sync(char * token, Channel *c) {
c->out.write(&c->out, MARKER_EOM);
}
-static void command_redirect(char * token, Channel *c) {
+static void command_redirect(char * token, Channel * c) {
char id[256];
json_read_string(&c->inp, id, sizeof(id));
@@ -435,7 +435,7 @@ static PeerServer * read_peer_properties(InputStream * inp) {
return ps;
}
-static void command_publish_peer(char * token, Channel *c) {
+static void command_publish_peer(char * token, Channel * c) {
PeerServer * ps = read_peer_properties(&c->inp);
if (c->inp.read(&c->inp) != 0) exception(ERR_JSON_SYNTAX);
if (c->inp.read(&c->inp) != MARKER_EOM) exception(ERR_JSON_SYNTAX);
@@ -621,7 +621,7 @@ void protocol_release(Protocol * p) {
free_services(p);
}
-void ini_locator_service(Protocol *p) {
+void ini_locator_service(Protocol * p) {
add_command_handler(p, LOCATOR, "sync", command_sync);
add_command_handler(p, LOCATOR, "redirect", command_redirect);
add_command_handler(p, LOCATOR, "publishPeer", command_publish_peer);
diff --git a/symbols_win32.c b/symbols_win32.c
index 7d776b96..64ac4222 100644
--- a/symbols_win32.c
+++ b/symbols_win32.c
@@ -32,40 +32,10 @@
# define MAX_SYM_NAME 2000
#endif
-static HANDLE current_process = NULL;
-static ULONG current_base = 0;
-
-/*
-static BOOL CALLBACK EnumSymProc1(
- LPSTR SymbolName,
- ULONG SymbolAddress,
- ULONG SymbolSize,
- PVOID UserContext)
-{
- printf("%08X %4u %s\n", (long)SymbolAddress, SymbolSize, SymbolName);
- return TRUE;
-}
-
-static void print_symbols(void) {
- printf("process 0x%08x, base address 0x%08x\n", current_process, current_base);
- if (!SymEnumerateSymbols(current_process, current_base, EnumSymProc1, NULL)) {
- printf("SymEnumerateSymbols failed: %d\n", GetLastError());
- }
-}
-*/
-
int set_symbol_context(Context * ctx) {
if (ctx->parent != NULL) ctx = ctx->parent;
assert(ctx->pid == ctx->mem);
- if (ctx->handle != current_process) {
- if (current_process != NULL) {
- if (!SymCleanup(current_process)) {
- set_win32_errno(GetLastError());
- trace(LOG_ALWAYS, "SymCleanup() error: %d: %s",
- errno, errno_to_str(errno));
- }
- current_process = NULL;
- }
+ if (!ctx->sym_handler_loaded) {
if (!SymInitialize(ctx->handle, NULL, FALSE)) {
set_win32_errno(GetLastError());
return -1;
@@ -74,8 +44,7 @@ int set_symbol_context(Context * ctx) {
set_win32_errno(GetLastError());
return -1;
}
- current_process = ctx->handle;
- current_base = (ULONG)ctx->base_address;
+ ctx->sym_handler_loaded = 1;
}
return 0;
}
@@ -147,13 +116,18 @@ int find_symbol(Context * ctx, char * name, Symbol * sym) {
static void event_context_exited(Context * ctx, void * client_data) {
assert(ctx->handle != NULL);
- if (ctx->handle == current_process) {
- if (!SymCleanup(current_process)) {
+ if (ctx->sym_handler_loaded) {
+ if (!SymUnloadModule(ctx->handle, (DWORD)ctx->base_address)) {
+ set_win32_errno(GetLastError());
+ trace(LOG_ALWAYS, "SymUnloadModule() error: %d: %s",
+ errno, errno_to_str(errno));
+ }
+ if (!SymCleanup(ctx->handle)) {
set_win32_errno(GetLastError());
trace(LOG_ALWAYS, "SymCleanup() error: %d: %s",
errno, errno_to_str(errno));
}
- current_process = NULL;
+ ctx->sym_handler_loaded = 0;
}
}

Back to the top