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);
}