Skip to main content
summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorFelix Burton2012-01-05 21:00:23 +0000
committerFelix Burton2012-01-07 00:48:59 +0000
commit2945831fad854a71050892f634f2cae6fd8ff33f (patch)
tree5d6f4d163c1a522b098639fa9d317c7b5b8987b0
parent3c5fa3ba770441a4a120e5828df25e61f7ecebfd (diff)
downloadorg.eclipse.tcf.agent-2945831fad854a71050892f634f2cae6fd8ff33f.tar.gz
org.eclipse.tcf.agent-2945831fad854a71050892f634f2cae6fd8ff33f.tar.xz
org.eclipse.tcf.agent-2945831fad854a71050892f634f2cae6fd8ff33f.zip
TCF Agent: extend trace API to allow dynamic registration of named log levels
-rw-r--r--framework/trace.c86
-rw-r--r--framework/trace.h13
-rw-r--r--main/main.c41
-rw-r--r--main/main_client.c11
-rw-r--r--main/main_log.c5
-rw-r--r--main/main_lua.c5
-rw-r--r--main/main_reg.c5
-rw-r--r--main/main_va.c11
8 files changed, 155 insertions, 22 deletions
diff --git a/framework/trace.c b/framework/trace.c
index 33bc6e7b..5a02b9b7 100644
--- a/framework/trace.c
+++ b/framework/trace.c
@@ -36,6 +36,25 @@ int log_mode = LOG_EVENTS | LOG_CHILD | LOG_WAITPID | LOG_CONTEXT | LOG_PROTOCOL
FILE * log_file = NULL;
+#define MAX_TRACE_MODES 40
+
+struct trace_mode trace_mode_table[MAX_TRACE_MODES + 1] = {
+ { LOG_ALLOC, "alloc", "memory allocation and deallocation" },
+ { LOG_EVENTCORE, "eventcore", "main event queue" },
+ { LOG_WAITPID, "waitpid", "waitpid() events" },
+ { LOG_EVENTS, "events", "low-level debugger events" },
+ { LOG_PROTOCOL, "protocol", "communication protocol" },
+ { LOG_CONTEXT, "context", "debugger actions" },
+ { LOG_DISCOVERY, "discovery", "discovery" },
+ { LOG_ASYNCREQ, "asyncreq", "async I/O" },
+ { LOG_PROXY, "proxy", "proxy state" },
+ { LOG_TCFLOG, "tcflog", "proxy traffic" },
+ { LOG_ELF, "elf", "ELF reader" },
+ { LOG_LUA, "lua", "LUA interpreter" },
+ { LOG_STACK, "stack", "stack trace service" },
+ { LOG_PLUGIN, "plugin", "plugins" }
+};
+
static pthread_mutex_t mutex;
int print_trace(int mode, const char * fmt, ...) {
@@ -85,6 +104,73 @@ int print_trace(int mode, const char * fmt, ...) {
#endif /* ENABLE_Trace */
+int parse_trace_mode(const char * mode, int * result)
+{
+#if ENABLE_Trace
+ int rval = 0;
+
+ *result = 0;
+ if (*mode == '\0')
+ return 0;
+ for(;;) {
+ if (*mode >= '0' && *mode <= '9') {
+ char * endptr;
+ *result |= strtoul(mode, &endptr, 0);
+ mode = endptr;
+ } else {
+ struct trace_mode *entry;
+ const char * endptr = mode;
+ while (*endptr != '\0' && *endptr != ',')
+ endptr++;
+ for (entry = trace_mode_table; entry->mode; entry++) {
+ if (strncmp(mode, entry->name, endptr - mode) == 0 &&
+ entry->name[endptr - mode] == '\0')
+ break;
+ }
+ if (entry->mode == 0)
+ rval = 1;
+ *result |= entry->mode;
+ mode = endptr;
+ }
+ if (*mode != ',')
+ break;
+ mode++;
+ }
+ if (*mode != '\0')
+ return 1;
+ return rval;
+#else
+ *result = 0;
+ return 0;
+#endif /* ENABLE_Trace */
+}
+
+int add_trace_mode(int mode, const char * name, const char * description)
+{
+#if ENABLE_Trace
+ int i;
+ int busy = 0;
+
+ for (i = 0; i < MAX_TRACE_MODES; i++) {
+ if (trace_mode_table[i].mode == 0) {
+ if (mode == 0) {
+ /* Set mode to first unused bit. */
+ mode = ~busy;
+ if (mode == 0)
+ break;
+ mode &= ~(mode - 1);
+ }
+ trace_mode_table[i].mode = mode;
+ trace_mode_table[i].name = name;
+ trace_mode_table[i].description = description;
+ return 0;
+ }
+ busy |= trace_mode_table[i].mode;
+ }
+#endif /* ENABLE_Trace */
+ return 0;
+}
+
void open_log_file(const char * log_name) {
#if ENABLE_Trace
if (log_name == NULL) {
diff --git a/framework/trace.h b/framework/trace.h
index c3599d68..5cbde26e 100644
--- a/framework/trace.h
+++ b/framework/trace.h
@@ -23,6 +23,7 @@
#include <config.h>
#include <stdio.h>
+/* Always update trace.c when adding or removing predefined log levels */
#define LOG_ALWAYS 0x0
#define LOG_ALLOC 0x1
#define LOG_EVENTCORE 0x2
@@ -64,6 +65,18 @@ extern FILE * log_file;
#endif /* ENABLE_Trace */
+struct trace_mode {
+ int mode;
+ const char * name;
+ const char * description;
+};
+
+extern struct trace_mode trace_mode_table[];
+
+extern int parse_trace_mode(const char * mode, int * result);
+
+extern int add_trace_mode(int mode, const char * name, const char * description);
+
extern void ini_trace(void);
extern void open_log_file(const char * name);
diff --git a/main/main.c b/main/main.c
index fc1dca46..fbe8a821 100644
--- a/main/main.c
+++ b/main/main.c
@@ -101,21 +101,8 @@ static const char * help_text[] = {
" -t run in diagnostic mode",
#endif
" -L<file> enable logging, use -L- to send log to stderr",
- " -l<number> set log level, the value is bitwise OR of:",
- " 0x0001 memory allocation and deallocation",
- " 0x0002 main event queue",
- " 0x0004 waitpid() events",
- " 0x0008 low-level debugger events",
- " 0x0020 communication protocol",
- " 0x0040 debugger actions",
- " 0x0080 discovery",
- " 0x0100 async I/O",
- " 0x0200 proxy state",
- " 0x0400 proxy traffic",
- " 0x0800 ELF reader",
- " 0x1000 LUA interpreter",
- " 0x2000 stack trace service",
- " 0x4000 plugins",
+ " -l<level> set log level, the level is comma separated list of:",
+ "@",
" -s<url> set agent listening port and protocol, default is TCP::1534",
" -S print server properties in Json format to stdout",
" -I<idle-seconds> exit if are no connections for the specified time",
@@ -130,7 +117,18 @@ static const char * help_text[] = {
static void show_help(void) {
const char ** p = help_text;
- while (*p != NULL) fprintf(stderr, "%s\n", *p++);
+ while (*p != NULL) {
+ if (**p == '@') {
+ struct trace_mode * tm = trace_mode_table;
+ while (tm->mode != 0) {
+ fprintf(stderr, " %-12s %s (%#x)\n", tm->name, tm->description, tm->mode);
+ tm++;
+ }
+ p++;
+ } else {
+ fprintf(stderr, "%s\n", *p++);
+ }
+ }
}
#endif
@@ -144,6 +142,7 @@ int main(int argc, char ** argv) {
int daemon = 0;
int interactive = 0;
int print_server_properties = 0;
+ const char * log_level = NULL;
const char * log_name = NULL;
const char * url = "TCP:";
Protocol * proto = NULL;
@@ -217,7 +216,8 @@ int main(int argc, char ** argv) {
break;
case 'l':
- log_mode = strtol(s, 0, 0);
+ log_level = s;
+ parse_trace_mode(log_level, &log_mode);
break;
case 'L':
@@ -261,6 +261,13 @@ int main(int argc, char ** argv) {
#endif
ini_services(proto, bcg);
+
+ /* Reparse log level in case initialization cause additional
+ * levels to be registered */
+ if (parse_trace_mode(log_level, &log_mode) != 0) {
+ fprintf(stderr, "Cannot parse log level: %s\n", log_level);
+ exit(1);
+ }
if (ini_server(url, proto, bcg) < 0) {
fprintf(stderr, "Cannot create TCF server: %s\n", errno_to_str(errno));
exit(1);
diff --git a/main/main_client.c b/main/main_client.c
index 6668779e..97d03d94 100644
--- a/main/main_client.c
+++ b/main/main_client.c
@@ -58,6 +58,7 @@ int main(int argc, char ** argv) {
int mode = 1; /* interactive */
const char * host_name = "localhost";
const char * command = NULL;
+ const char * log_level = NULL;
const char * log_name = "-";
const char * script_name = NULL;
@@ -107,7 +108,8 @@ int main(int argc, char ** argv) {
}
switch (c) {
case 'l':
- log_mode = strtol(s, 0, 0);
+ log_level = s;
+ parse_trace_mode(log_level, &log_mode);
break;
case 'L':
@@ -174,6 +176,13 @@ int main(int argc, char ** argv) {
plugins_load(proto, NULL);
#endif
+ /* Reparse log level in case initialization cause additional
+ * levels to be registered */
+ if (parse_trace_mode(log_level, &log_mode) != 0) {
+ fprintf(stderr, "Cannot parse log level: %s\n", log_level);
+ exit(1);
+ }
+
/* Process events - must run on the initial thread since ptrace()
* returns ECHILD otherwise, thinking we are not the owner. */
run_event_loop();
diff --git a/main/main_log.c b/main/main_log.c
index 99959e39..d95758f3 100644
--- a/main/main_log.c
+++ b/main/main_log.c
@@ -166,7 +166,10 @@ int main(int argc, char ** argv) {
}
switch (c) {
case 'l':
- log_mode = strtol(s, 0, 0);
+ if (parse_trace_mode(s, &log_mode) != 0) {
+ fprintf(stderr, "Cannot parse log level: %s\n", s);
+ exit(1);
+ }
break;
case 'L':
diff --git a/main/main_lua.c b/main/main_lua.c
index 758232dc..a911156f 100644
--- a/main/main_lua.c
+++ b/main/main_lua.c
@@ -1493,7 +1493,10 @@ int main(int argc, char ** argv) {
}
switch (c) {
case 'l':
- log_mode = strtol(s, 0, 0);
+ if (parse_trace_mode(s, &log_mode) != 0) {
+ fprintf(stderr, "Cannot parse log level: %s\n", s);
+ exit(1);
+ }
break;
case 'L':
diff --git a/main/main_reg.c b/main/main_reg.c
index 78672977..524a7f1d 100644
--- a/main/main_reg.c
+++ b/main/main_reg.c
@@ -79,7 +79,10 @@ int main(int argc, char **argv) {
}
switch (c) {
case 'l':
- log_mode = strtol(s, 0, 0);
+ if (parse_trace_mode(s, &log_mode) != 0) {
+ fprintf(stderr, "Cannot parse log level: %s\n", s);
+ exit(1);
+ }
break;
case 'L':
diff --git a/main/main_va.c b/main/main_va.c
index 84387234..7a59bc64 100644
--- a/main/main_va.c
+++ b/main/main_va.c
@@ -59,6 +59,7 @@ int main(int argc, char ** argv) {
#endif
int c;
int ind;
+ const char * log_level = NULL;
const char * log_name = NULL;
const char * url = "TCP:";
PeerServer * ps;
@@ -102,7 +103,8 @@ int main(int argc, char ** argv) {
}
switch (c) {
case 'l':
- log_mode = strtol(s, 0, 0);
+ log_level = s;
+ parse_trace_mode(log_level, &log_mode);
break;
case 'L':
@@ -163,6 +165,13 @@ int main(int argc, char ** argv) {
plugins_load(proto, NULL);
#endif
+ /* Reparse log level in case initialization cause additional
+ * levels to be registered */
+ if (parse_trace_mode(log_level, &log_mode) != 0) {
+ fprintf(stderr, "Cannot parse log level: %s\n", log_level);
+ exit(1);
+ }
+
discovery_start();
/* Process events - must run on the initial thread since ptrace()

Back to the top