diff --git a/man/dfuzzer.xml b/man/dfuzzer.xml index 3e667df..0c0a5a3 100644 --- a/man/dfuzzer.xml +++ b/man/dfuzzer.xml @@ -200,10 +200,13 @@ - + - Enable debug logging. Implies . This option should - not be normally used during testing. + Enable debug logging. Implies . Takes an optional + argument specifying a log handle, where HANDLE is one of + all, general, or command. + + This option should not be normally used during testing. diff --git a/src/dfuzzer.c b/src/dfuzzer.c index 92b7212..b42a94a 100644 --- a/src/dfuzzer.c +++ b/src/dfuzzer.c @@ -573,7 +573,9 @@ static void df_print_help(const char *name) " -h --help Show this help text.\n" " -l --list List all available services on both buses.\n" " -v --verbose Be more verbose.\n" - " -d --debug Enable debug logging; implies -v.\n" + " -d --debug[=HANDLE] Enable debug logging; implies -v.\n" + " Takes an optional argument specifying a log handle,\n" + " where handle is one of 'all', 'general', or 'command'.\n" " -L --log-dir=DIRNAME Write full, parseable log into DIRNAME/BUS_NAME.\n" " The directory must already exist.\n" " -s --no-suppressions Don't load suppression file(s).\n" @@ -626,7 +628,7 @@ static void df_parse_parameters(int argc, char **argv) static const struct option options[] = { { "buffer-limit", required_argument, NULL, 'b' }, - { "debug", no_argument, NULL, 'd' }, + { "debug", optional_argument, NULL, 'd' }, { "command", required_argument, NULL, 'e' }, { "string-file", required_argument, NULL, 'f' }, { "help", no_argument, NULL, 'h' }, @@ -649,7 +651,7 @@ static void df_parse_parameters(int argc, char **argv) {} }; - while ((c = getopt_long(argc, argv, "n:o:i:m:b:t:e:L:x:y:f:I:p:sdvlhV", options, NULL)) >= 0) { + while ((c = getopt_long(argc, argv, "n:o:i:m:b:t:e:L:x:y:f:I:p:d::svlhV", options, NULL)) >= 0) { switch (c) { case 'n': if (strlen(optarg) >= MAX_OBJECT_PATH_LENGTH) { @@ -712,7 +714,20 @@ static void df_parse_parameters(int argc, char **argv) df_supflg = 1; break; case 'd': - df_set_log_level(DF_LOG_HANDLE_GENERAL, DF_LOG_LEVEL_DEBUG); + if (optarg) { + if (g_ascii_strcasecmp(optarg, "all") == 0) + df_set_log_level(DF_LOG_HANDLE_ALL, DF_LOG_LEVEL_DEBUG); + else if (g_ascii_strcasecmp(optarg, "general") == 0) + df_set_log_level(DF_LOG_HANDLE_GENERAL, DF_LOG_LEVEL_DEBUG); + else if (g_ascii_strcasecmp(optarg, "command") == 0) + df_set_log_level(DF_LOG_HANDLE_COMMAND, DF_LOG_LEVEL_DEBUG); + else { + df_fail("Invalid log handle '%s'\n", optarg); + exit(1); + } + } else + df_set_log_level(DF_LOG_HANDLE_GENERAL, DF_LOG_LEVEL_DEBUG); + break; case 'v': df_set_log_level(DF_LOG_HANDLE_GENERAL, DF_LOG_LEVEL_VERBOSE); diff --git a/src/log.c b/src/log.c index 61e6d15..95484b8 100644 --- a/src/log.c +++ b/src/log.c @@ -7,11 +7,11 @@ static FILE *log_file; void df_set_log_level(guint8 log_handle, guint8 log_level) { - g_assert(log_handle < _DF_LOG_HANDLE_MAX); + g_assert(log_handle <= DF_LOG_HANDLE_ALL); g_assert(log_level < _DF_LOG_LEVEL_MAX); if (log_handle == DF_LOG_HANDLE_ALL) - for (guint8 i = 0; i < _DF_LOG_LEVEL_MAX; i++) + for (guint8 i = 0; i < _DF_LOG_HANDLE_MAX; i++) log_level_max[i] = log_level; else log_level_max[log_handle] = log_level; diff --git a/src/util.c b/src/util.c index 30ef35a..be26801 100644 --- a/src/util.c +++ b/src/util.c @@ -104,6 +104,10 @@ int df_execute_external_command(const char *command) return df_fail_ret(-1, "Failed to open /dev/null: %m\n"); for (guint8 i = 0; i < 3; i++) { + /* Don't redirect stdout/stderr to /dev/null if the command log level + * is set to debug */ + if (i > 0 && df_get_log_level(DF_LOG_HANDLE_COMMAND) >= DF_LOG_LEVEL_DEBUG) + break; if (dup2(null_fd, i) < 0) return df_fail_ret(-1, "Failed to replace fd %d with /dev/null: %m\n", i); }