diff options
-rw-r--r-- | agent/tcf/framework/trace.c | 79 | ||||
-rw-r--r-- | agent/tcf/framework/trace.h | 13 | ||||
-rw-r--r-- | agent/tcf/main/main.c | 42 | ||||
-rw-r--r-- | agent/tcf/main/main_client.c | 11 | ||||
-rw-r--r-- | agent/tcf/main/main_log.c | 5 | ||||
-rw-r--r-- | agent/tcf/main/main_lua.c | 5 | ||||
-rw-r--r-- | agent/tcf/main/main_reg.c | 5 | ||||
-rw-r--r-- | agent/tcf/main/main_va.c | 11 |
8 files changed, 149 insertions, 22 deletions
diff --git a/agent/tcf/framework/trace.c b/agent/tcf/framework/trace.c index b2c3b2cb..aca55bc4 100644 --- a/agent/tcf/framework/trace.c +++ b/agent/tcf/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,66 @@ 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/agent/tcf/framework/trace.h b/agent/tcf/framework/trace.h index 7a368bc3..3e787a19 100644 --- a/agent/tcf/framework/trace.h +++ b/agent/tcf/framework/trace.h @@ -23,6 +23,7 @@ #include <tcf/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/agent/tcf/main/main.c b/agent/tcf/main/main.c index 71799fde..c9ead5d8 100644 --- a/agent/tcf/main/main.c +++ b/agent/tcf/main/main.c @@ -125,21 +125,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", @@ -154,7 +141,19 @@ 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 @@ -166,6 +165,7 @@ int main(int argc, char ** argv) { int ind; int daemon = 0; const char * log_name = NULL; + const char * log_level = NULL; #endif int interactive = 0; int print_server_properties = 0; @@ -241,7 +241,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': @@ -285,6 +286,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/agent/tcf/main/main_client.c b/agent/tcf/main/main_client.c index 347bf5ac..3da3125e 100644 --- a/agent/tcf/main/main_client.c +++ b/agent/tcf/main/main_client.c @@ -54,6 +54,7 @@ int main(int argc, char ** argv) { int c; int ind; const char * log_name = "-"; + const char * log_level = NULL; #endif #if ENABLE_Cmdline int keep_alive = 0; @@ -111,7 +112,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': @@ -180,6 +182,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); + } + run_event_loop(); return 0; } diff --git a/agent/tcf/main/main_log.c b/agent/tcf/main/main_log.c index a71fd9d1..560dbd75 100644 --- a/agent/tcf/main/main_log.c +++ b/agent/tcf/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/agent/tcf/main/main_lua.c b/agent/tcf/main/main_lua.c index 0b300784..eca0a5d1 100644 --- a/agent/tcf/main/main_lua.c +++ b/agent/tcf/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/agent/tcf/main/main_reg.c b/agent/tcf/main/main_reg.c index de29d36a..f77588ff 100644 --- a/agent/tcf/main/main_reg.c +++ b/agent/tcf/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/agent/tcf/main/main_va.c b/agent/tcf/main/main_va.c index c575639d..fa82cf99 100644 --- a/agent/tcf/main/main_va.c +++ b/agent/tcf/main/main_va.c @@ -58,6 +58,7 @@ int tcf_va(void) { int main(int argc, char ** argv) { int c; int ind; + const char * log_level = NULL; const char * log_name = NULL; #endif const char * url = "TCP:"; @@ -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() |