Skip to main content
summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rwxr-xr-xagent/agent.vcproj8
-rwxr-xr-xagent/agent.vcxproj22
-rwxr-xr-xagent/agent.vcxproj.filters6
-rw-r--r--agent/system/Darwin/tcf/context-darwin.c17
-rw-r--r--agent/system/FreeBSD/tcf/context-freebsd.c19
-rw-r--r--agent/system/GNU/Linux/tcf/context-linux.c33
-rw-r--r--agent/system/Windows/tcf/context-win32.c8
-rw-r--r--agent/tcf/framework/context.c3
-rw-r--r--agent/tcf/framework/context.h7
-rw-r--r--agent/tcf/framework/signames.c25
-rw-r--r--agent/tcf/framework/signames.h3
-rw-r--r--agent/tcf/framework/sigsets.c130
-rw-r--r--agent/tcf/framework/sigsets.h52
-rw-r--r--agent/tcf/services/processes.c65
14 files changed, 337 insertions, 61 deletions
diff --git a/agent/agent.vcproj b/agent/agent.vcproj
index 9c9cb08b..4eb98f43 100755
--- a/agent/agent.vcproj
+++ b/agent/agent.vcproj
@@ -596,6 +596,14 @@
>
</File>
<File
+ RelativePath=".\tcf\framework\sigsets.c"
+ >
+ </File>
+ <File
+ RelativePath=".\tcf\framework\sigsets.h"
+ >
+ </File>
+ <File
RelativePath=".\tcf\framework\streams.c"
>
</File>
diff --git a/agent/agent.vcxproj b/agent/agent.vcxproj
index 54bc2a7d..94d5e775 100755
--- a/agent/agent.vcxproj
+++ b/agent/agent.vcxproj
@@ -89,13 +89,16 @@
<StringPooling>true</StringPooling>
<RuntimeLibrary>MultiThreaded</RuntimeLibrary>
<FunctionLevelLinking>true</FunctionLevelLinking>
- <PrecompiledHeaderOutputFile>$(OutDir)agent.pch</PrecompiledHeaderOutputFile>
+ <PrecompiledHeaderOutputFile>
+ </PrecompiledHeaderOutputFile>
<AssemblerListingLocation>$(OutDir)</AssemblerListingLocation>
<ObjectFileName>$(OutDir)</ObjectFileName>
<ProgramDataBaseFileName>$(OutDir)</ProgramDataBaseFileName>
<WarningLevel>Level3</WarningLevel>
<SuppressStartupBanner>true</SuppressStartupBanner>
<CompileAs>CompileAsC</CompileAs>
+ <PrecompiledHeaderFile>
+ </PrecompiledHeaderFile>
</ClCompile>
<ResourceCompile>
<PreprocessorDefinitions>NDEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>
@@ -132,13 +135,16 @@
<StringPooling>true</StringPooling>
<RuntimeLibrary>MultiThreaded</RuntimeLibrary>
<FunctionLevelLinking>true</FunctionLevelLinking>
- <PrecompiledHeaderOutputFile>$(OutDir)agent.pch</PrecompiledHeaderOutputFile>
+ <PrecompiledHeaderOutputFile>
+ </PrecompiledHeaderOutputFile>
<AssemblerListingLocation>$(OutDir)</AssemblerListingLocation>
<ObjectFileName>$(OutDir)</ObjectFileName>
<ProgramDataBaseFileName>$(OutDir)</ProgramDataBaseFileName>
<WarningLevel>Level3</WarningLevel>
<SuppressStartupBanner>true</SuppressStartupBanner>
<CompileAs>CompileAsC</CompileAs>
+ <PrecompiledHeaderFile>
+ </PrecompiledHeaderFile>
</ClCompile>
<ResourceCompile>
<PreprocessorDefinitions>NDEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>
@@ -171,7 +177,8 @@
<PreprocessorDefinitions>_DEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<MinimalRebuild>true</MinimalRebuild>
<RuntimeLibrary>MultiThreadedDebug</RuntimeLibrary>
- <PrecompiledHeaderOutputFile>$(OutDir)agent.pch</PrecompiledHeaderOutputFile>
+ <PrecompiledHeaderOutputFile>
+ </PrecompiledHeaderOutputFile>
<AssemblerListingLocation>$(OutDir)</AssemblerListingLocation>
<ObjectFileName>$(OutDir)</ObjectFileName>
<ProgramDataBaseFileName>$(OutDir)</ProgramDataBaseFileName>
@@ -179,6 +186,8 @@
<SuppressStartupBanner>true</SuppressStartupBanner>
<DebugInformationFormat>EditAndContinue</DebugInformationFormat>
<CompileAs>CompileAsC</CompileAs>
+ <PrecompiledHeaderFile>
+ </PrecompiledHeaderFile>
</ClCompile>
<ResourceCompile>
<PreprocessorDefinitions>_DEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>
@@ -213,7 +222,8 @@
<PreprocessorDefinitions>_DEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<MinimalRebuild>true</MinimalRebuild>
<RuntimeLibrary>MultiThreadedDebug</RuntimeLibrary>
- <PrecompiledHeaderOutputFile>$(OutDir)agent.pch</PrecompiledHeaderOutputFile>
+ <PrecompiledHeaderOutputFile>
+ </PrecompiledHeaderOutputFile>
<AssemblerListingLocation>$(OutDir)</AssemblerListingLocation>
<ObjectFileName>$(OutDir)</ObjectFileName>
<ProgramDataBaseFileName>$(OutDir)</ProgramDataBaseFileName>
@@ -221,6 +231,8 @@
<SuppressStartupBanner>true</SuppressStartupBanner>
<DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
<CompileAs>CompileAsC</CompileAs>
+ <PrecompiledHeaderFile>
+ </PrecompiledHeaderFile>
</ClCompile>
<ResourceCompile>
<PreprocessorDefinitions>_DEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>
@@ -266,6 +278,7 @@
<ClCompile Include="tcf\framework\proxy.c" />
<ClCompile Include="tcf\framework\shutdown.c" />
<ClCompile Include="tcf\framework\signames.c" />
+ <ClCompile Include="tcf\framework\sigsets.c" />
<ClCompile Include="tcf\framework\streams.c" />
<ClCompile Include="tcf\framework\trace.c" />
<ClCompile Include="tcf\framework\waitpid.c" />
@@ -415,6 +428,7 @@
<ClInclude Include="tcf\framework\proxy.h" />
<ClInclude Include="tcf\framework\shutdown.h" />
<ClInclude Include="tcf\framework\signames.h" />
+ <ClInclude Include="tcf\framework\sigsets.h" />
<ClInclude Include="tcf\framework\streams.h" />
<ClInclude Include="tcf\framework\tcf.h" />
<ClInclude Include="tcf\framework\trace.h" />
diff --git a/agent/agent.vcxproj.filters b/agent/agent.vcxproj.filters
index e2776791..f204cab9 100755
--- a/agent/agent.vcxproj.filters
+++ b/agent/agent.vcxproj.filters
@@ -312,6 +312,9 @@
<ClCompile Include="tcf\services\profiler.c">
<Filter>services</Filter>
</ClCompile>
+ <ClCompile Include="tcf\framework\sigsets.c">
+ <Filter>framework</Filter>
+ </ClCompile>
</ItemGroup>
<ItemGroup>
<ClInclude Include="tcf\framework\asyncreq.h">
@@ -579,5 +582,8 @@
<ClInclude Include="tcf\services\profiler.h">
<Filter>services</Filter>
</ClInclude>
+ <ClInclude Include="tcf\framework\sigsets.h">
+ <Filter>framework</Filter>
+ </ClInclude>
</ItemGroup>
</Project> \ No newline at end of file
diff --git a/agent/system/Darwin/tcf/context-darwin.c b/agent/system/Darwin/tcf/context-darwin.c
index b3b13cf0..55fcf739 100644
--- a/agent/system/Darwin/tcf/context-darwin.c
+++ b/agent/system/Darwin/tcf/context-darwin.c
@@ -168,13 +168,13 @@ int context_continue(Context * ctx) {
if (skip_breakpoint(ctx, 0)) return 0;
if (!EXT(ctx)->syscall_enter) {
- while (ctx->pending_signals != 0) {
- while ((ctx->pending_signals & (1 << signal)) == 0) signal++;
- if (ctx->sig_dont_pass & (1 << signal)) {
- ctx->pending_signals &= ~(1 << signal);
- signal = 0;
+ unsigned n = 0;
+ while (sigset_get_next(&ctx->pending_signals, &n)) {
+ if (sigset_get(&ctx->sig_dont_pass, n)) {
+ sigset_set(&ctx->pending_signals, n, 0);
}
else {
+ signal = n;
break;
}
}
@@ -272,7 +272,7 @@ int context_resume(Context * ctx, int mode, ContextAddress range_start, ContextA
case RM_STEP_INTO:
return context_single_step(ctx);
case RM_TERMINATE:
- ctx->pending_signals |= 1 << SIGKILL;
+ sigset_set(&ctx->pending_signals, SIGKILL, 1);
return context_continue(ctx);
}
errno = ERR_UNSUPPORTED;
@@ -598,9 +598,8 @@ static void event_pid_stopped(pid_t pid, int signal, int event, int syscall) {
assert(!EXT(ctx)->attach_callback);
if (signal != SIGSTOP && signal != SIGTRAP) {
- assert(signal < 32);
- ctx->pending_signals |= 1 << signal;
- if ((ctx->sig_dont_stop & (1 << signal)) == 0) {
+ sigset_set(&ctx->pending_signals, signal, 1);
+ if (sigset_get(&ctx->sig_dont_stop, signal) == 0) {
ctx->pending_intercept = 1;
stopped_by_exception = 1;
}
diff --git a/agent/system/FreeBSD/tcf/context-freebsd.c b/agent/system/FreeBSD/tcf/context-freebsd.c
index b778459d..69deef2e 100644
--- a/agent/system/FreeBSD/tcf/context-freebsd.c
+++ b/agent/system/FreeBSD/tcf/context-freebsd.c
@@ -173,13 +173,13 @@ int context_continue(Context * ctx) {
if (skip_breakpoint(ctx, 0)) return 0;
if (!EXT(ctx)->ptrace_event) {
- while (ctx->pending_signals != 0) {
- while ((ctx->pending_signals & (1 << signal)) == 0) signal++;
- if (ctx->sig_dont_pass & (1 << signal)) {
- ctx->pending_signals &= ~(1 << signal);
- signal = 0;
+ unsigned n = 0;
+ while (sigset_get_next(&ctx->pending_signals, &n)) {
+ if (sigset_get(&ctx->sig_dont_pass, n)) {
+ sigset_set(&ctx->pending_signals, n, 0);
}
else {
+ signal = n;
break;
}
}
@@ -214,7 +214,7 @@ int context_continue(Context * ctx) {
errno = err;
return -1;
}
- ctx->pending_signals &= ~(1 << signal);
+ sigset_set(&ctx->pending_signals, signal, 0);
send_context_started_event(ctx);
return 0;
}
@@ -269,7 +269,7 @@ int context_resume(Context * ctx, int mode, ContextAddress range_start, ContextA
case RM_STEP_INTO:
return context_single_step(ctx);
case RM_TERMINATE:
- ctx->pending_signals |= 1 << SIGKILL;
+ sigset_set(&ctx->pending_signals, SIGKILL, 1);
return context_continue(ctx);
}
errno = ERR_UNSUPPORTED;
@@ -590,9 +590,8 @@ static void event_pid_stopped(pid_t pid, int signal, int event, int syscall) {
assert(!EXT(ctx)->attach_callback);
if (signal != SIGSTOP && signal != SIGTRAP) {
- assert(signal < 32);
- ctx->pending_signals |= 1 << signal;
- if ((ctx->sig_dont_stop & (1 << signal)) == 0) {
+ sigset_set(&ctx->pending_signals, signal, 1);
+ if (sigset_get(&ctx->sig_dont_stop, signal) == 0) {
ctx->pending_intercept = 1;
stopped_by_exception = 1;
}
diff --git a/agent/system/GNU/Linux/tcf/context-linux.c b/agent/system/GNU/Linux/tcf/context-linux.c
index 1a4c66d0..926ed45c 100644
--- a/agent/system/GNU/Linux/tcf/context-linux.c
+++ b/agent/system/GNU/Linux/tcf/context-linux.c
@@ -494,13 +494,13 @@ int context_continue(Context * ctx) {
if (skip_breakpoint(ctx, 0)) return 0;
if (!ext->syscall_enter && !ext->ptrace_event) {
- while (ctx->pending_signals != 0) {
- while ((ctx->pending_signals & (1 << signal)) == 0) signal++;
- if (ctx->sig_dont_pass & (1 << signal)) {
- ctx->pending_signals &= ~(1 << signal);
- signal = 0;
+ unsigned n = 0;
+ while (sigset_get_next(&ctx->pending_signals, &n)) {
+ if (sigset_get(&ctx->sig_dont_pass, n)) {
+ sigset_set(&ctx->pending_signals, n, 0);
}
else {
+ signal = n;
break;
}
}
@@ -529,7 +529,7 @@ int context_continue(Context * ctx) {
errno = err;
return -1;
}
- ctx->pending_signals &= ~(1 << signal);
+ sigset_set(&ctx->pending_signals, signal, 0);
if (syscall_never_returns(ctx)) {
ext->syscall_enter = 0;
ext->syscall_exit = 0;
@@ -580,7 +580,7 @@ int context_resume(Context * ctx, int mode, ContextAddress range_start, ContextA
case RM_STEP_INTO:
return context_single_step(ctx);
case RM_TERMINATE:
- ctx->pending_signals |= 1 << SIGKILL;
+ sigset_set(&ctx->pending_signals, SIGKILL, 1);
return context_continue(ctx);
case RM_DETACH:
return context_detach(ctx);
@@ -1112,8 +1112,8 @@ static Context * add_thread(Context * parent, Context * creator, pid_t pid) {
ctx->big_endian = parent->big_endian;
ctx->creator = creator;
if (creator) {
- ctx->sig_dont_stop = creator->sig_dont_stop;
- ctx->sig_dont_pass = creator->sig_dont_pass;
+ sigset_copy(&ctx->sig_dont_stop, &creator->sig_dont_stop);
+ sigset_copy(&ctx->sig_dont_pass, &creator->sig_dont_pass);
creator->ref_count++;
}
(ctx->parent = parent)->ref_count++;
@@ -1260,8 +1260,8 @@ static void event_pid_stopped(pid_t pid, int signal, int event, int syscall) {
prs2->mem_access |= MEM_ACCESS_USER;
prs2->big_endian = ctx->parent->big_endian;
(prs2->creator = ctx)->ref_count++;
- prs2->sig_dont_stop = ctx->sig_dont_stop;
- prs2->sig_dont_pass = ctx->sig_dont_pass;
+ sigset_copy(&prs2->sig_dont_stop, &ctx->sig_dont_stop);
+ sigset_copy(&prs2->sig_dont_pass, &ctx->sig_dont_pass);
prs2->ref_count = 1;
clone_breakpoints_on_process_fork(ctx, prs2);
if ((ext->attach_mode & CONTEXT_ATTACH_CHILDREN) == 0) {
@@ -1296,8 +1296,8 @@ static void event_pid_stopped(pid_t pid, int signal, int event, int syscall) {
alloc_regs(ctx2);
ctx2->mem = prs;
ctx2->big_endian = prs->big_endian;
- ctx2->sig_dont_stop = ctx->sig_dont_stop;
- ctx2->sig_dont_pass = ctx->sig_dont_pass;
+ sigset_copy(&ctx2->sig_dont_stop, &ctx->sig_dont_stop);
+ sigset_copy(&ctx2->sig_dont_pass, &ctx->sig_dont_pass);
ctx2->exiting = 1;
(ctx2->creator = ctx)->ref_count++;
(ctx2->parent = prs)->ref_count++;
@@ -1318,8 +1318,7 @@ static void event_pid_stopped(pid_t pid, int signal, int event, int syscall) {
}
if (signal != SIGSTOP && signal != SIGTRAP) {
- assert(signal < 32);
- ctx->pending_signals |= 1 << signal;
+ sigset_set(&ctx->pending_signals, signal, 1);
#if defined(__arm__)
/* On ARM, Linux kernel appears to use SIGILL to lazily enable vector registers */
if (signal == SIGILL && !ext->crt0_done) {
@@ -1327,7 +1326,7 @@ static void event_pid_stopped(pid_t pid, int signal, int event, int syscall) {
}
else
#endif
- if ((ctx->sig_dont_stop & (1 << signal)) == 0) {
+ if (sigset_get(&ctx->sig_dont_stop, signal) == 0) {
if (!is_intercepted(ctx)) ctx->pending_intercept = 1;
stopped_by_exception = 1;
}
@@ -1414,7 +1413,7 @@ static void event_pid_stopped(pid_t pid, int signal, int event, int syscall) {
send_context_stopped_event(ctx);
}
- if (ext->detach_req && !ext->sigstop_posted && !ctx->pending_signals) {
+ if (ext->detach_req && !ext->sigstop_posted && sigset_is_empty(&ctx->pending_signals)) {
ext->waitpid_posted = 0;
detach_waitpid_process();
}
diff --git a/agent/system/Windows/tcf/context-win32.c b/agent/system/Windows/tcf/context-win32.c
index 98cfcddd..c9535704 100644
--- a/agent/system/Windows/tcf/context-win32.c
+++ b/agent/system/Windows/tcf/context-win32.c
@@ -255,7 +255,7 @@ static DWORD event_win32_context_stopped(Context * ctx) {
memset(ext->regs, 0, sizeof(REG_SET));
ctx->signal = get_signal_index(ctx);
- ctx->pending_signals = 0;
+ sigset_clear(&ctx->pending_signals);
ctx->stopped = 1;
ctx->stopped_by_bp = 0;
ctx->stopped_by_cb = NULL;
@@ -338,11 +338,11 @@ static DWORD event_win32_context_stopped(Context * ctx) {
int intercept = 1;
ctx->stopped_by_exception = 1;
if (ctx->signal) {
- ctx->pending_signals |= 1 << ctx->signal;
- if (ctx->sig_dont_pass & (1 << ctx->signal)) {
+ sigset_set(&ctx->pending_signals, ctx->signal, 1);
+ if (sigset_get(&ctx->sig_dont_pass, ctx->signal)) {
continue_status = DBG_CONTINUE;
}
- if (ctx->sig_dont_stop & (1 << ctx->signal)) {
+ if (sigset_get(&ctx->sig_dont_stop, ctx->signal)) {
intercept = 0;
}
}
diff --git a/agent/tcf/framework/context.c b/agent/tcf/framework/context.c
index e7a8fe2b..9684890c 100644
--- a/agent/tcf/framework/context.c
+++ b/agent/tcf/framework/context.c
@@ -206,6 +206,9 @@ void context_unlock(Context * ctx) {
}
ctx->event_notification = 0;
list_remove(&ctx->ctxl);
+ sigset_clear(&ctx->pending_signals);
+ sigset_clear(&ctx->sig_dont_stop);
+ sigset_clear(&ctx->sig_dont_pass);
loc_free(ctx->name);
loc_free(ctx);
}
diff --git a/agent/tcf/framework/context.h b/agent/tcf/framework/context.h
index c37d4e47..cd9e30ba 100644
--- a/agent/tcf/framework/context.h
+++ b/agent/tcf/framework/context.h
@@ -23,6 +23,7 @@
#include <tcf/config.h>
#include <tcf/framework/cpudefs.h>
#include <tcf/framework/errors.h>
+#include <tcf/framework/sigsets.h>
#include <tcf/framework/link.h>
extern LINK context_root;
@@ -65,9 +66,9 @@ struct Context {
int exited; /* context exited */
int event_notification; /* set to 1 when calling one of ContextEventListener call-backs for this context */
int pending_intercept; /* host is waiting for this context to be suspended */
- unsigned long pending_signals; /* bit set of signals that were received, but not handled yet */
- unsigned long sig_dont_stop; /* bit set of signals that should not be intercepted by the debugger */
- unsigned long sig_dont_pass; /* bit set of signals that should not be delivered to the context */
+ SigSet pending_signals; /* bit set of signals that were received, but not handled yet */
+ SigSet sig_dont_stop; /* bit set of signals that should not be intercepted by the debugger */
+ SigSet sig_dont_pass; /* bit set of signals that should not be delivered to the context */
int signal; /* signal that stopped this context */
};
diff --git a/agent/tcf/framework/signames.c b/agent/tcf/framework/signames.c
index d100960b..fc3f1c88 100644
--- a/agent/tcf/framework/signames.c
+++ b/agent/tcf/framework/signames.c
@@ -20,6 +20,8 @@
#include <tcf/config.h>
#include <signal.h>
+#include <tcf/framework/myalloc.h>
+#include <tcf/framework/sigsets.h>
#include <tcf/framework/signames.h>
#if defined(_WIN32)
@@ -64,6 +66,10 @@ static ExceptionName exception_names[] = {
#define EXCEPTION_NAMES_CNT ((int)(sizeof(exception_names) / sizeof(ExceptionName)))
+int signal_cnt(void) {
+ return EXCEPTION_NAMES_CNT;
+}
+
const char * signal_name(int signal) {
int n = signal - 1;
if (n >= 0 && n < EXCEPTION_NAMES_CNT) return exception_names[n].name;
@@ -154,20 +160,29 @@ static SignalInfo info[] = {
#define INFO_CNT ((int)(sizeof(info) / sizeof(SignalInfo)))
+static int index_len = 0;
+
static SignalInfo * get_info(int signal) {
- static SignalInfo * index[32];
- static int index_ok = 0;
- if (signal < 0 || signal > 31) return NULL;
- if (!index_ok) {
+ static SignalInfo ** index = NULL;
+ if (index_len == 0) {
int i;
for (i = 0; i < INFO_CNT; i++) {
+ if (info[i].signal >= index_len) index_len = info[i].signal + 1;
+ }
+ index = (SignalInfo **)loc_alloc_zero(sizeof(SignalInfo *) * index_len);
+ for (i = 0; i < INFO_CNT; i++) {
index[info[i].signal] = &info[i];
}
- index_ok = 1;
}
+ if (signal < 0 || signal >= index_len) return NULL;
return index[signal];
}
+int signal_cnt(void) {
+ get_info(0);
+ return index_len;
+}
+
const char * signal_name(int signal) {
SignalInfo * i = get_info(signal);
if (i != NULL) return i->name;
diff --git a/agent/tcf/framework/signames.h b/agent/tcf/framework/signames.h
index ad61e6d5..8b0d044c 100644
--- a/agent/tcf/framework/signames.h
+++ b/agent/tcf/framework/signames.h
@@ -20,6 +20,9 @@
#ifndef D_signames
#define D_signames
+/* Return the number of signals descriptions */
+extern int signal_cnt(void);
+
/* Return signal name */
extern const char * signal_name(int signal);
diff --git a/agent/tcf/framework/sigsets.c b/agent/tcf/framework/sigsets.c
new file mode 100644
index 00000000..557b149d
--- /dev/null
+++ b/agent/tcf/framework/sigsets.c
@@ -0,0 +1,130 @@
+/*******************************************************************************
+ * Copyright (c) 2013 Xilinx, 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.
+ * The Eclipse Public License is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ * and the Eclipse Distribution License is available at
+ * http://www.eclipse.org/org/documents/edl-v10.php.
+ * You may elect to redistribute this code under either of these licenses.
+ *
+ * Contributors:
+ * Xilinx - initial API and implementation
+ *******************************************************************************/
+
+
+#include <tcf/config.h>
+
+#include <assert.h>
+#include <tcf/framework/myalloc.h>
+#include <tcf/framework/sigsets.h>
+
+#if ENABLE_UnlimitedSignals
+
+static unsigned search(SigSet * set, unsigned bit) {
+ unsigned l = 0;
+ unsigned h = set->cnt;
+ while (l < h) {
+ unsigned k = (l + h) / 2;
+ if (set->buf[k] > bit) {
+ h = k;
+ }
+ else if (set->buf[k] < bit) {
+ l = k + 1;
+ }
+ else {
+ return k;
+ }
+ }
+ return l;
+}
+
+int sigset_is_empty(SigSet * set) {
+ return set->cnt == 0;
+}
+
+int sigset_get(SigSet * set, unsigned bit) {
+ unsigned n = search(set, bit);
+ return n < set->cnt && set->buf[n] == bit;
+}
+
+int sigset_get_next(SigSet * set, unsigned * bit) {
+ unsigned n = search(set, *bit + 1);
+ if (n >= set->cnt) return 0;
+ *bit = set->buf[n];
+ return 1;
+}
+
+void sigset_set(SigSet * set, unsigned bit, int value) {
+ unsigned n = search(set, bit);
+ assert(bit > 0 || (bit == 0 && value == 0));
+ assert(n <= set->cnt);
+ if (value) {
+ if (n < set->cnt && set->buf[n] == bit) return;
+ if (set->cnt >= set->max) {
+ set->max += 8;
+ set->buf = (unsigned *)loc_realloc(set->buf, sizeof(unsigned) * set->max);
+ }
+ memmove(set->buf + n + 1, set->buf + n, sizeof(unsigned) * (set->cnt - n));
+ set->buf[n] = bit;
+ set->cnt++;
+ }
+ else {
+ if (n >= set->cnt || set->buf[n] != bit) return;
+ memmove(set->buf + n, set->buf + n + 1, sizeof(unsigned) * (set->cnt - n - 1));
+ set->cnt--;
+ }
+}
+
+void sigset_copy(SigSet * dst, SigSet * src) {
+ dst->cnt = src->cnt;
+ dst->max = src->cnt;
+ dst->buf = (unsigned *)loc_alloc(sizeof(unsigned) * dst->max);
+ memcpy(dst->buf, src->buf, sizeof(unsigned) * dst->cnt);
+}
+
+void sigset_clear(SigSet * set) {
+ loc_free(set->buf);
+ memset(set, 0, sizeof(SigSet));
+}
+
+#else
+
+int sigset_is_empty(SigSet * set) {
+ return *set == 0;
+}
+
+int sigset_get(SigSet * set, unsigned bit) {
+ assert(bit < 32);
+ return (*set & (1ul << bit)) != 0;
+}
+
+int sigset_get_next(SigSet * set, unsigned * bit) {
+ (*bit)++;
+ while (*bit < 32) {
+ if (*bit > 0 && (*set & (1ul << *bit)) != 0) return 1;
+ (*bit)++;
+ }
+ return 0;
+}
+
+void sigset_set(SigSet * set, unsigned bit, int value) {
+ assert((bit > 0 && bit < 32) || (bit == 0 && value == 0));
+ if (value) {
+ *set |= 1ul << bit;
+ }
+ else {
+ *set &= ~(1ul << bit);
+ }
+}
+
+void sigset_copy(SigSet * dst, SigSet * src) {
+ *dst = *src;
+}
+
+void sigset_clear(SigSet * set) {
+ *set = 0;
+}
+
+#endif /* ENABLE_UnlimitedSignals */
diff --git a/agent/tcf/framework/sigsets.h b/agent/tcf/framework/sigsets.h
new file mode 100644
index 00000000..66454349
--- /dev/null
+++ b/agent/tcf/framework/sigsets.h
@@ -0,0 +1,52 @@
+/*******************************************************************************
+ * Copyright (c) 2013 Xilinx, 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.
+ * The Eclipse Public License is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ * and the Eclipse Distribution License is available at
+ * http://www.eclipse.org/org/documents/edl-v10.php.
+ * You may elect to redistribute this code under either of these licenses.
+ *
+ * Contributors:
+ * Xilinx - initial API and implementation
+ *******************************************************************************/
+
+/*
+ * SigSet type definition.
+ * The type used to provide support for more than 32 signals,
+ * e.g. POSIX real-time signals and Windows exceptions.
+ */
+
+#ifndef D_sigset
+#define D_sigset
+
+#if !defined(ENABLE_UnlimitedSignals)
+# define ENABLE_UnlimitedSignals 1
+#endif
+
+#if ENABLE_UnlimitedSignals
+
+typedef struct SigSet {
+ unsigned cnt;
+ unsigned max;
+ unsigned * buf;
+} SigSet;
+
+#else
+
+/* Backward compatible definition of signal set type,
+ * does not support signal numbers beyond 32 */
+typedef unsigned long SigSet;
+
+#endif
+
+extern int sigset_is_empty(SigSet * set);
+extern int sigset_get(SigSet * set, unsigned bit);
+extern int sigset_get_next(SigSet * set, unsigned * bit);
+extern void sigset_set(SigSet * set, unsigned bit, int value);
+extern void sigset_copy(SigSet * dst, SigSet * src);
+extern void sigset_clear(SigSet * set);
+
+#endif /* D_sigset */
diff --git a/agent/tcf/services/processes.c b/agent/tcf/services/processes.c
index a60ad13e..dafd1174 100644
--- a/agent/tcf/services/processes.c
+++ b/agent/tcf/services/processes.c
@@ -512,6 +512,28 @@ static void command_detach(char * token, Channel * c) {
write_stream(&c->out, MARKER_EOM);
}
+static void write_sigset(OutputStream * out, SigSet * set) {
+ unsigned bit = 0;
+ uint64_t bits = 0;
+ while (sigset_get_next(set, &bit)) {
+ if (bit >= sizeof(bits) * 8) {
+ /* Does not fit into int bitset */
+ unsigned cnt = 0;
+ bit = 0;
+ write_stream(out, '[');
+ while (sigset_get_next(set, &bit)) {
+ if (cnt > 0) write_stream(out, ',');
+ json_write_long(out, bit);
+ cnt++;
+ }
+ write_stream(out, ']');
+ return;
+ }
+ bits |= (uint64_t)1 << bit;
+ }
+ json_write_uint64(out, bits);
+}
+
static void command_get_signal_mask(char * token, Channel * c) {
int err = 0;
char id[256];
@@ -534,29 +556,51 @@ static void command_get_signal_mask(char * token, Channel * c) {
write_stringz(&c->out, "null");
}
else {
- json_write_long(&c->out, ctx->sig_dont_stop);
+ write_sigset(&c->out, &ctx->sig_dont_stop);
write_stream(&c->out, 0);
- json_write_long(&c->out, ctx->sig_dont_pass);
+ write_sigset(&c->out, &ctx->sig_dont_pass);
write_stream(&c->out, 0);
- json_write_long(&c->out, ctx->pending_signals);
+ write_sigset(&c->out, &ctx->pending_signals);
write_stream(&c->out, 0);
}
write_stream(&c->out, MARKER_EOM);
}
+static void read_sigset_bit(InputStream * inp, void * args) {
+ SigSet * set = (SigSet *)args;
+ unsigned bit = (unsigned)json_read_long(inp);
+ sigset_set(set, bit, 1);
+}
+
+static SigSet read_sigset(InputStream * inp) {
+ SigSet set;
+ memset(&set, 0, sizeof(set));
+ if (json_peek(inp) == '[') {
+ json_read_array(inp, read_sigset_bit, &set);
+ }
+ else {
+ unsigned bit;
+ uint64_t bits = json_read_uint64(inp);
+ for (bit = 0; bit < 64; bit++) {
+ sigset_set(&set, bit, (bits & ((uint64_t)1 << bit)) != 0);
+ }
+ }
+ return set;
+}
+
static void command_set_signal_mask(char * token, Channel * c) {
int err = 0;
char id[256];
Context * ctx = NULL;
- int dont_stop;
- int dont_pass;
+ SigSet dont_stop;
+ SigSet dont_pass;
json_read_string(&c->inp, id, sizeof(id));
json_test_char(&c->inp, MARKER_EOA);
- dont_stop = json_read_long(&c->inp);
+ dont_stop = read_sigset(&c->inp);
json_test_char(&c->inp, MARKER_EOA);
- dont_pass = json_read_long(&c->inp);
+ dont_pass = read_sigset(&c->inp);
json_test_char(&c->inp, MARKER_EOA);
json_test_char(&c->inp, MARKER_EOM);
@@ -565,6 +609,8 @@ static void command_set_signal_mask(char * token, Channel * c) {
err = ERR_INV_CONTEXT;
}
else {
+ sigset_clear(&ctx->sig_dont_stop);
+ sigset_clear(&ctx->sig_dont_pass);
ctx->sig_dont_stop = dont_stop;
ctx->sig_dont_pass = dont_pass;
}
@@ -700,8 +746,9 @@ static void command_get_signal_list(char * token, Channel * c) {
else {
int i = 0;
int n = 0;
+ int cnt = signal_cnt();
write_stream(&c->out, '[');
- for (i = 0; i < 32; i++) {
+ for (i = 0; i < cnt; i++) {
const char * name = signal_name(i);
const char * desc = signal_description(i);
if (name != NULL || desc != NULL) {
@@ -1468,7 +1515,7 @@ static void command_start(char * token, Channel * c, void * x) {
json_test_char(&c->inp, MARKER_EOA);
params.envp = json_read_alloc_string_array(&c->inp, &envp_len);
json_test_char(&c->inp, MARKER_EOA);
- if (version > 0 && (peek_stream(&c->inp) == '{' || peek_stream(&c->inp) == 'n')) {
+ if (version > 0 && (json_peek(&c->inp) == '{' || json_peek(&c->inp) == 'n')) {
json_read_struct(&c->inp, read_start_params, &params);
}
else {

Back to the top