When in TUI mode, it is impossible to show all the debug messages to
console. This make it hard to debug perf issues using debug messages.
This patch adds support for logging debug messages to file to resolve
this problem.

The usage is:
perf -debug verbose=2 --debug file=1 COMMAND

And the path of log file is '~/perf.log'.

Signed-off-by: Changbin Du <[email protected]>
---
 tools/perf/Documentation/perf.txt |  4 +++-
 tools/perf/util/debug.c           | 20 ++++++++++++++++++++
 2 files changed, 23 insertions(+), 1 deletion(-)

diff --git a/tools/perf/Documentation/perf.txt 
b/tools/perf/Documentation/perf.txt
index 401f0ed67439..45db7b22d1a5 100644
--- a/tools/perf/Documentation/perf.txt
+++ b/tools/perf/Documentation/perf.txt
@@ -16,7 +16,8 @@ OPTIONS
        Setup debug variable (see list below) in value
        range (0, 10). Use like:
          --debug verbose   # sets verbose = 1
-         --debug verbose=2 # sets verbose = 2
+         --debug verbose=2 --debug file=1
+                           # sets verbose = 2 and save log to file
 
        List of debug variables allowed to set:
          verbose          - general debug messages
@@ -24,6 +25,7 @@ OPTIONS
          data-convert     - data convert command debug messages
          stderr           - write debug output (option -v) to stderr
                             in browser mode
+         file             - write debug output to log file ~/perf.log
 
 --buildid-dir::
        Setup buildid cache directory. It has higher priority than
diff --git a/tools/perf/util/debug.c b/tools/perf/util/debug.c
index 3780fe42453b..f0b4346a0efa 100644
--- a/tools/perf/util/debug.c
+++ b/tools/perf/util/debug.c
@@ -8,6 +8,7 @@
 #include <stdarg.h>
 #include <stdio.h>
 #include <stdlib.h>
+#include <errno.h>
 #include <sys/wait.h>
 #include <api/debug.h>
 #include <linux/time64.h>
@@ -28,6 +29,8 @@ int verbose;
 bool dump_trace = false, quiet = false;
 int debug_ordered_events;
 static int redirect_to_stderr;
+static int log_to_file;
+static FILE *log_file;
 int debug_data_convert;
 
 int veprintf(int level, int var, const char *fmt, va_list args)
@@ -39,6 +42,9 @@ int veprintf(int level, int var, const char *fmt, va_list 
args)
                        ui_helpline__vshow(fmt, args);
                else
                        ret = vfprintf(stderr, fmt, args);
+
+               if (log_file)
+                       vfprintf(log_file, fmt, args);
        }
 
        return ret;
@@ -180,6 +186,7 @@ static struct debug_variable {
        { .name = "verbose",            .ptr = &verbose },
        { .name = "ordered-events",     .ptr = &debug_ordered_events},
        { .name = "stderr",             .ptr = &redirect_to_stderr},
+       { .name = "file",               .ptr = &log_to_file},
        { .name = "data-convert",       .ptr = &debug_data_convert },
        { .name = NULL, }
 };
@@ -219,6 +226,19 @@ int perf_debug_option(const char *str)
                v = -1;
 
        *var->ptr = v;
+
+       if (log_to_file) {
+               char log_path[PATH_MAX];
+
+               strcat(strcpy(log_path, getenv("HOME")), "/perf.log");
+               log_file = fopen(log_path, "a");
+               if (!log_file) {
+                       pr_err("Can not create log file: %s\n", 
strerror(errno));
+                       free(s);
+                       return -1;
+               }
+       }
+
        free(s);
        return 0;
 }
-- 
2.20.1

Reply via email to