diff options
author | Adrian Hunter <adrian.hunter@intel.com> | 2015-07-17 12:33:39 -0400 |
---|---|---|
committer | Arnaldo Carvalho de Melo <acme@redhat.com> | 2015-08-17 10:11:36 -0400 |
commit | 53af92849d793662e943d61bb16f7d3eb2d7a072 (patch) | |
tree | 99f68bdac34a5468306eb44bc93a10a6131acb95 | |
parent | 237fae79f50d2d0c7bdeb039bc2c87fc6d52c7e7 (diff) |
perf tools: Add Intel PT log
Add a facility to log Intel Processor Trace decoding. The log is
intended for debugging purposes only.
The log file name is "intel_pt.log" and is opened in the current
directory. The log contains a record of all packets and instructions
decoded and can get very large (10 MB would be a small one).
Signed-off-by: Adrian Hunter <adrian.hunter@intel.com>
Cc: Jiri Olsa <jolsa@redhat.com>
Link: http://lkml.kernel.org/r/1437150840-31811-5-git-send-email-adrian.hunter@intel.com
Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
-rw-r--r-- | tools/perf/util/intel-pt-decoder/Build | 2 | ||||
-rw-r--r-- | tools/perf/util/intel-pt-decoder/intel-pt-log.c | 155 | ||||
-rw-r--r-- | tools/perf/util/intel-pt-decoder/intel-pt-log.h | 52 |
3 files changed, 208 insertions, 1 deletions
diff --git a/tools/perf/util/intel-pt-decoder/Build b/tools/perf/util/intel-pt-decoder/Build index 5a46ce13c1f8..3c717b420c89 100644 --- a/tools/perf/util/intel-pt-decoder/Build +++ b/tools/perf/util/intel-pt-decoder/Build | |||
@@ -1,4 +1,4 @@ | |||
1 | libperf-$(CONFIG_AUXTRACE) += intel-pt-pkt-decoder.o intel-pt-insn-decoder.o | 1 | libperf-$(CONFIG_AUXTRACE) += intel-pt-pkt-decoder.o intel-pt-insn-decoder.o intel-pt-log.o |
2 | 2 | ||
3 | inat_tables_script = util/intel-pt-decoder/gen-insn-attr-x86.awk | 3 | inat_tables_script = util/intel-pt-decoder/gen-insn-attr-x86.awk |
4 | inat_tables_maps = util/intel-pt-decoder/x86-opcode-map.txt | 4 | inat_tables_maps = util/intel-pt-decoder/x86-opcode-map.txt |
diff --git a/tools/perf/util/intel-pt-decoder/intel-pt-log.c b/tools/perf/util/intel-pt-decoder/intel-pt-log.c new file mode 100644 index 000000000000..d09c7d9f9050 --- /dev/null +++ b/tools/perf/util/intel-pt-decoder/intel-pt-log.c | |||
@@ -0,0 +1,155 @@ | |||
1 | /* | ||
2 | * intel_pt_log.c: Intel Processor Trace support | ||
3 | * Copyright (c) 2013-2014, Intel Corporation. | ||
4 | * | ||
5 | * This program is free software; you can redistribute it and/or modify it | ||
6 | * under the terms and conditions of the GNU General Public License, | ||
7 | * version 2, as published by the Free Software Foundation. | ||
8 | * | ||
9 | * This program is distributed in the hope it will be useful, but WITHOUT | ||
10 | * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or | ||
11 | * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for | ||
12 | * more details. | ||
13 | * | ||
14 | */ | ||
15 | |||
16 | #include <stdio.h> | ||
17 | #include <stdint.h> | ||
18 | #include <inttypes.h> | ||
19 | #include <stdarg.h> | ||
20 | #include <stdbool.h> | ||
21 | #include <string.h> | ||
22 | |||
23 | #include "intel-pt-log.h" | ||
24 | #include "intel-pt-insn-decoder.h" | ||
25 | |||
26 | #include "intel-pt-pkt-decoder.h" | ||
27 | |||
28 | #define MAX_LOG_NAME 256 | ||
29 | |||
30 | static FILE *f; | ||
31 | static char log_name[MAX_LOG_NAME]; | ||
32 | static bool enable_logging; | ||
33 | |||
34 | void intel_pt_log_enable(void) | ||
35 | { | ||
36 | enable_logging = true; | ||
37 | } | ||
38 | |||
39 | void intel_pt_log_disable(void) | ||
40 | { | ||
41 | if (f) | ||
42 | fflush(f); | ||
43 | enable_logging = false; | ||
44 | } | ||
45 | |||
46 | void intel_pt_log_set_name(const char *name) | ||
47 | { | ||
48 | strncpy(log_name, name, MAX_LOG_NAME - 5); | ||
49 | strcat(log_name, ".log"); | ||
50 | } | ||
51 | |||
52 | static void intel_pt_print_data(const unsigned char *buf, int len, uint64_t pos, | ||
53 | int indent) | ||
54 | { | ||
55 | int i; | ||
56 | |||
57 | for (i = 0; i < indent; i++) | ||
58 | fprintf(f, " "); | ||
59 | |||
60 | fprintf(f, " %08" PRIx64 ": ", pos); | ||
61 | for (i = 0; i < len; i++) | ||
62 | fprintf(f, " %02x", buf[i]); | ||
63 | for (; i < 16; i++) | ||
64 | fprintf(f, " "); | ||
65 | fprintf(f, " "); | ||
66 | } | ||
67 | |||
68 | static void intel_pt_print_no_data(uint64_t pos, int indent) | ||
69 | { | ||
70 | int i; | ||
71 | |||
72 | for (i = 0; i < indent; i++) | ||
73 | fprintf(f, " "); | ||
74 | |||
75 | fprintf(f, " %08" PRIx64 ": ", pos); | ||
76 | for (i = 0; i < 16; i++) | ||
77 | fprintf(f, " "); | ||
78 | fprintf(f, " "); | ||
79 | } | ||
80 | |||
81 | static int intel_pt_log_open(void) | ||
82 | { | ||
83 | if (!enable_logging) | ||
84 | return -1; | ||
85 | |||
86 | if (f) | ||
87 | return 0; | ||
88 | |||
89 | if (!log_name[0]) | ||
90 | return -1; | ||
91 | |||
92 | f = fopen(log_name, "w+"); | ||
93 | if (!f) { | ||
94 | enable_logging = false; | ||
95 | return -1; | ||
96 | } | ||
97 | |||
98 | return 0; | ||
99 | } | ||
100 | |||
101 | void intel_pt_log_packet(const struct intel_pt_pkt *packet, int pkt_len, | ||
102 | uint64_t pos, const unsigned char *buf) | ||
103 | { | ||
104 | char desc[INTEL_PT_PKT_DESC_MAX]; | ||
105 | |||
106 | if (intel_pt_log_open()) | ||
107 | return; | ||
108 | |||
109 | intel_pt_print_data(buf, pkt_len, pos, 0); | ||
110 | intel_pt_pkt_desc(packet, desc, INTEL_PT_PKT_DESC_MAX); | ||
111 | fprintf(f, "%s\n", desc); | ||
112 | } | ||
113 | |||
114 | void intel_pt_log_insn(struct intel_pt_insn *intel_pt_insn, uint64_t ip) | ||
115 | { | ||
116 | char desc[INTEL_PT_INSN_DESC_MAX]; | ||
117 | size_t len = intel_pt_insn->length; | ||
118 | |||
119 | if (intel_pt_log_open()) | ||
120 | return; | ||
121 | |||
122 | if (len > INTEL_PT_INSN_DBG_BUF_SZ) | ||
123 | len = INTEL_PT_INSN_DBG_BUF_SZ; | ||
124 | intel_pt_print_data(intel_pt_insn->buf, len, ip, 8); | ||
125 | if (intel_pt_insn_desc(intel_pt_insn, desc, INTEL_PT_INSN_DESC_MAX) > 0) | ||
126 | fprintf(f, "%s\n", desc); | ||
127 | else | ||
128 | fprintf(f, "Bad instruction!\n"); | ||
129 | } | ||
130 | |||
131 | void intel_pt_log_insn_no_data(struct intel_pt_insn *intel_pt_insn, uint64_t ip) | ||
132 | { | ||
133 | char desc[INTEL_PT_INSN_DESC_MAX]; | ||
134 | |||
135 | if (intel_pt_log_open()) | ||
136 | return; | ||
137 | |||
138 | intel_pt_print_no_data(ip, 8); | ||
139 | if (intel_pt_insn_desc(intel_pt_insn, desc, INTEL_PT_INSN_DESC_MAX) > 0) | ||
140 | fprintf(f, "%s\n", desc); | ||
141 | else | ||
142 | fprintf(f, "Bad instruction!\n"); | ||
143 | } | ||
144 | |||
145 | void intel_pt_log(const char *fmt, ...) | ||
146 | { | ||
147 | va_list args; | ||
148 | |||
149 | if (intel_pt_log_open()) | ||
150 | return; | ||
151 | |||
152 | va_start(args, fmt); | ||
153 | vfprintf(f, fmt, args); | ||
154 | va_end(args); | ||
155 | } | ||
diff --git a/tools/perf/util/intel-pt-decoder/intel-pt-log.h b/tools/perf/util/intel-pt-decoder/intel-pt-log.h new file mode 100644 index 000000000000..db3942f83677 --- /dev/null +++ b/tools/perf/util/intel-pt-decoder/intel-pt-log.h | |||
@@ -0,0 +1,52 @@ | |||
1 | /* | ||
2 | * intel_pt_log.h: Intel Processor Trace support | ||
3 | * Copyright (c) 2013-2014, Intel Corporation. | ||
4 | * | ||
5 | * This program is free software; you can redistribute it and/or modify it | ||
6 | * under the terms and conditions of the GNU General Public License, | ||
7 | * version 2, as published by the Free Software Foundation. | ||
8 | * | ||
9 | * This program is distributed in the hope it will be useful, but WITHOUT | ||
10 | * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or | ||
11 | * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for | ||
12 | * more details. | ||
13 | * | ||
14 | */ | ||
15 | |||
16 | #ifndef INCLUDE__INTEL_PT_LOG_H__ | ||
17 | #define INCLUDE__INTEL_PT_LOG_H__ | ||
18 | |||
19 | #include <stdint.h> | ||
20 | #include <inttypes.h> | ||
21 | |||
22 | struct intel_pt_pkt; | ||
23 | |||
24 | void intel_pt_log_enable(void); | ||
25 | void intel_pt_log_disable(void); | ||
26 | void intel_pt_log_set_name(const char *name); | ||
27 | |||
28 | void intel_pt_log_packet(const struct intel_pt_pkt *packet, int pkt_len, | ||
29 | uint64_t pos, const unsigned char *buf); | ||
30 | |||
31 | struct intel_pt_insn; | ||
32 | |||
33 | void intel_pt_log_insn(struct intel_pt_insn *intel_pt_insn, uint64_t ip); | ||
34 | void intel_pt_log_insn_no_data(struct intel_pt_insn *intel_pt_insn, | ||
35 | uint64_t ip); | ||
36 | |||
37 | __attribute__((format(printf, 1, 2))) | ||
38 | void intel_pt_log(const char *fmt, ...); | ||
39 | |||
40 | #define x64_fmt "0x%" PRIx64 | ||
41 | |||
42 | static inline void intel_pt_log_at(const char *msg, uint64_t u) | ||
43 | { | ||
44 | intel_pt_log("%s at " x64_fmt "\n", msg, u); | ||
45 | } | ||
46 | |||
47 | static inline void intel_pt_log_to(const char *msg, uint64_t u) | ||
48 | { | ||
49 | intel_pt_log("%s to " x64_fmt "\n", msg, u); | ||
50 | } | ||
51 | |||
52 | #endif | ||