aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--Makefile2
-rw-r--r--trace-cmd.h5
-rw-r--r--trace-input.c293
-rw-r--r--trace-read.c259
4 files changed, 306 insertions, 253 deletions
diff --git a/Makefile b/Makefile
index 8d93d08..38407ec 100644
--- a/Makefile
+++ b/Makefile
@@ -35,7 +35,7 @@ libparsevent.so: $(PEVENT_LIB_OBJS)
35libparsevent.a: $(PEVENT_LIB_OBJS) 35libparsevent.a: $(PEVENT_LIB_OBJS)
36 $(RM) $@; $(AR) rcs $@ $^ 36 $(RM) $@; $(AR) rcs $@ $^
37 37
38TCMD_LIB_OBJS = $(PEVENT_LIB_OBJS) trace-util.o 38TCMD_LIB_OBJS = $(PEVENT_LIB_OBJS) trace-util.o trace-input.o
39 39
40libtracecmd.a: $(TCMD_LIB_OBJS) 40libtracecmd.a: $(TCMD_LIB_OBJS)
41 $(RM) $@; $(AR) rcs $@ $^ 41 $(RM) $@; $(AR) rcs $@ $^
diff --git a/trace-cmd.h b/trace-cmd.h
index 667ab3e..4e1d900 100644
--- a/trace-cmd.h
+++ b/trace-cmd.h
@@ -33,4 +33,9 @@ enum {
33#define TS_SHIFT 27 33#define TS_SHIFT 27
34#endif 34#endif
35 35
36struct tracecmd_handle;
37
38struct tracecmd_handle *tracecmd_open(int fd);
39int tracecmd_read_headers(struct tracecmd_handle *handle);
40
36#endif /* _TRACE_CMD_H */ 41#endif /* _TRACE_CMD_H */
diff --git a/trace-input.c b/trace-input.c
new file mode 100644
index 0000000..e2c089b
--- /dev/null
+++ b/trace-input.c
@@ -0,0 +1,293 @@
1#define _LARGEFILE64_SOURCE
2#define _GNU_SOURCE
3#include <dirent.h>
4#include <stdio.h>
5#include <stdlib.h>
6#include <string.h>
7#include <getopt.h>
8#include <stdarg.h>
9#include <sys/types.h>
10#include <sys/stat.h>
11#include <sys/wait.h>
12#include <sys/mman.h>
13#include <pthread.h>
14#include <fcntl.h>
15#include <unistd.h>
16#include <ctype.h>
17#include <errno.h>
18
19#include "trace-cmd.h"
20
21extern int show_events;
22
23struct tracecmd_handle {
24 int fd;
25};
26
27int file_bigendian;
28int host_bigendian;
29int long_size;
30
31int read_or_die(void *data, int size)
32{
33 int r;
34
35 r = read(input_fd, data, size);
36 if (r != size)
37 die("reading input file (size expected=%d received=%d)",
38 size, r);
39 return r;
40}
41
42static char *read_string(void)
43{
44 char buf[BUFSIZ];
45 char *str = NULL;
46 int size = 0;
47 int i;
48 int r;
49
50 for (;;) {
51 r = read(input_fd, buf, BUFSIZ);
52 if (r < 0)
53 die("reading input file");
54
55 if (!r)
56 die("no data");
57
58 for (i = 0; i < r; i++) {
59 if (!buf[i])
60 break;
61 }
62 if (i < r)
63 break;
64
65 if (str) {
66 size += BUFSIZ;
67 str = realloc(str, size);
68 if (!str)
69 die("malloc of size %d", size);
70 memcpy(str + (size - BUFSIZ), buf, BUFSIZ);
71 } else {
72 size = BUFSIZ;
73 str = malloc_or_die(size);
74 memcpy(str, buf, size);
75 }
76 }
77
78 /* move the file descriptor to the end of the string */
79 r = lseek(input_fd, -(r - (i+1)), SEEK_CUR);
80 if (r < 0)
81 die("lseek");
82
83 if (str) {
84 size += i + 1;
85 str = realloc(str, size);
86 if (!str)
87 die("malloc of size %d", size);
88 memcpy(str + (size - i), buf, i);
89 str[size] = 0;
90 } else {
91 size = i + 1;
92 str = malloc_or_die(i);
93 memcpy(str, buf, i);
94 str[i] = 0;
95 }
96
97 return str;
98}
99
100unsigned int read4(void)
101{
102 unsigned int data;
103
104 read_or_die(&data, 4);
105 return __data2host4(data);
106}
107
108unsigned long long read8(void)
109{
110 unsigned long long data;
111
112 read_or_die(&data, 8);
113 return __data2host8(data);
114}
115
116static void read_header_files(void)
117{
118 unsigned long long size;
119 char *header_page;
120 char *header_event;
121 char buf[BUFSIZ];
122
123 read_or_die(buf, 12);
124 if (memcmp(buf, "header_page", 12) != 0)
125 die("did not read header page");
126
127 size = read8();
128 header_page = malloc_or_die(size);
129 read_or_die(header_page, size);
130 pevent_parse_header_page(header_page, size);
131 free(header_page);
132
133 /*
134 * The size field in the page is of type long,
135 * use that instead, since it represents the kernel.
136 */
137 long_size = header_page_size_size;
138
139 read_or_die(buf, 13);
140 if (memcmp(buf, "header_event", 13) != 0)
141 die("did not read header event");
142
143 size = read8();
144 header_event = malloc_or_die(size);
145 read_or_die(header_event, size);
146 free(header_event);
147}
148
149static void read_ftrace_file(unsigned long long size)
150{
151 char *buf;
152
153 buf = malloc_or_die(size);
154 read_or_die(buf, size);
155 pevent_parse_event(buf, size, "ftrace");
156 free(buf);
157}
158
159static void read_event_file(char *system, unsigned long long size)
160{
161 char *buf;
162
163 buf = malloc_or_die(size+1);
164 read_or_die(buf, size);
165 buf[size] = 0;
166 if (show_events)
167 printf("%s\n", buf);
168 pevent_parse_event(buf, size, system);
169 free(buf);
170}
171
172static void read_ftrace_files(void)
173{
174 unsigned long long size;
175 int count;
176 int i;
177
178 count = read4();
179
180 for (i = 0; i < count; i++) {
181 size = read8();
182 read_ftrace_file(size);
183 }
184}
185
186static void read_event_files(void)
187{
188 unsigned long long size;
189 char *system;
190 int systems;
191 int count;
192 int i,x;
193
194 systems = read4();
195
196 for (i = 0; i < systems; i++) {
197 system = read_string();
198
199 count = read4();
200 for (x=0; x < count; x++) {
201 size = read8();
202 read_event_file(system, size);
203 }
204 }
205}
206
207static void read_proc_kallsyms(void)
208{
209 unsigned int size;
210 char *buf;
211
212 size = read4();
213 if (!size)
214 return;
215
216 buf = malloc_or_die(size);
217 read_or_die(buf, size);
218
219 parse_proc_kallsyms(buf, size);
220
221 free(buf);
222}
223
224static void read_ftrace_printk(void)
225{
226 unsigned int size;
227 char *buf;
228
229 size = read4();
230 if (!size)
231 return;
232
233 buf = malloc_or_die(size);
234 read_or_die(buf, size);
235
236 parse_ftrace_printk(buf, size);
237
238 free(buf);
239}
240
241int read_trace_files(void)
242{
243 read_header_files();
244 read_ftrace_files();
245 read_event_files();
246 read_proc_kallsyms();
247 read_ftrace_printk();
248
249 trace_load_plugins();
250
251 return 0;
252}
253
254struct tracecmd_handle *tracecmd_open(int fd)
255{
256 struct tracecmd_handle *handle;
257 char test[] = { 23, 8, 68 };
258 char *version;
259 char buf[BUFSIZ];
260
261 handle = malloc(sizeof(*handle));
262 if (!handle)
263 return NULL;
264
265 handle->fd = fd;
266
267 input_fd = open(input_file, O_RDONLY);
268 if (input_fd < 0)
269 die("opening '%s'\n", input_file);
270
271 read_or_die(buf, 3);
272 if (memcmp(buf, test, 3) != 0)
273 die("not an trace data file");
274
275 read_or_die(buf, 7);
276 if (memcmp(buf, "tracing", 7) != 0)
277 die("not a trace file (missing tracing)");
278
279 version = read_string();
280 printf("version = %s\n", version);
281 free(version);
282
283 read_or_die(buf, 1);
284 file_bigendian = buf[0];
285 host_bigendian = bigendian();
286
287 read_or_die(buf, 1);
288 long_size = buf[0];
289
290 page_size = read4();
291
292 return 0;
293}
diff --git a/trace-read.c b/trace-read.c
index cb358b0..395eeef 100644
--- a/trace-read.c
+++ b/trace-read.c
@@ -43,224 +43,10 @@ const char *input_file = "trace.dat";
43 43
44static int read_page; 44static int read_page;
45 45
46int file_bigendian; 46int show_events = 0;
47int host_bigendian;
48static int long_size;
49
50static int show_events = 0;
51 47
52static int filter_cpu = -1; 48static int filter_cpu = -1;
53 49
54static int read_or_die(void *data, int size)
55{
56 int r;
57
58 r = read(input_fd, data, size);
59 if (r != size)
60 die("reading input file (size expected=%d received=%d)",
61 size, r);
62 return r;
63}
64
65static unsigned int read4(void)
66{
67 unsigned int data;
68
69 read_or_die(&data, 4);
70 return __data2host4(data);
71}
72
73static unsigned long long read8(void)
74{
75 unsigned long long data;
76
77 read_or_die(&data, 8);
78 return __data2host8(data);
79}
80
81static char *read_string(void)
82{
83 char buf[BUFSIZ];
84 char *str = NULL;
85 int size = 0;
86 int i;
87 int r;
88
89 for (;;) {
90 r = read(input_fd, buf, BUFSIZ);
91 if (r < 0)
92 die("reading input file");
93
94 if (!r)
95 die("no data");
96
97 for (i = 0; i < r; i++) {
98 if (!buf[i])
99 break;
100 }
101 if (i < r)
102 break;
103
104 if (str) {
105 size += BUFSIZ;
106 str = realloc(str, size);
107 if (!str)
108 die("malloc of size %d", size);
109 memcpy(str + (size - BUFSIZ), buf, BUFSIZ);
110 } else {
111 size = BUFSIZ;
112 str = malloc_or_die(size);
113 memcpy(str, buf, size);
114 }
115 }
116
117 /* move the file descriptor to the end of the string */
118 r = lseek(input_fd, -(r - (i+1)), SEEK_CUR);
119 if (r < 0)
120 die("lseek");
121
122 if (str) {
123 size += i + 1;
124 str = realloc(str, size);
125 if (!str)
126 die("malloc of size %d", size);
127 memcpy(str + (size - i), buf, i);
128 str[size] = 0;
129 } else {
130 size = i + 1;
131 str = malloc_or_die(i);
132 memcpy(str, buf, i);
133 str[i] = 0;
134 }
135
136 return str;
137}
138
139static void read_proc_kallsyms(void)
140{
141 unsigned int size;
142 char *buf;
143
144 size = read4();
145 if (!size)
146 return;
147
148 buf = malloc_or_die(size);
149 read_or_die(buf, size);
150
151 parse_proc_kallsyms(buf, size);
152
153 free(buf);
154}
155
156static void read_ftrace_printk(void)
157{
158 unsigned int size;
159 char *buf;
160
161 size = read4();
162 if (!size)
163 return;
164
165 buf = malloc_or_die(size);
166 read_or_die(buf, size);
167
168 parse_ftrace_printk(buf, size);
169
170 free(buf);
171}
172
173static void read_header_files(void)
174{
175 unsigned long long size;
176 char *header_page;
177 char *header_event;
178 char buf[BUFSIZ];
179
180 read_or_die(buf, 12);
181 if (memcmp(buf, "header_page", 12) != 0)
182 die("did not read header page");
183
184 size = read8();
185 header_page = malloc_or_die(size);
186 read_or_die(header_page, size);
187 pevent_parse_header_page(header_page, size);
188 free(header_page);
189
190 /*
191 * The size field in the page is of type long,
192 * use that instead, since it represents the kernel.
193 */
194 long_size = header_page_size_size;
195
196 read_or_die(buf, 13);
197 if (memcmp(buf, "header_event", 13) != 0)
198 die("did not read header event");
199
200 size = read8();
201 header_event = malloc_or_die(size);
202 read_or_die(header_event, size);
203 free(header_event);
204}
205
206static void read_ftrace_file(unsigned long long size)
207{
208 char *buf;
209
210 buf = malloc_or_die(size);
211 read_or_die(buf, size);
212 pevent_parse_event(buf, size, "ftrace");
213 free(buf);
214}
215
216static void read_event_file(char *system, unsigned long long size)
217{
218 char *buf;
219
220 buf = malloc_or_die(size+1);
221 read_or_die(buf, size);
222 buf[size] = 0;
223 if (show_events)
224 printf("%s\n", buf);
225 pevent_parse_event(buf, size, system);
226 free(buf);
227}
228
229static void read_ftrace_files(void)
230{
231 unsigned long long size;
232 int count;
233 int i;
234
235 count = read4();
236
237 for (i = 0; i < count; i++) {
238 size = read8();
239 read_ftrace_file(size);
240 }
241}
242
243static void read_event_files(void)
244{
245 unsigned long long size;
246 char *system;
247 int systems;
248 int count;
249 int i,x;
250
251 systems = read4();
252
253 for (i = 0; i < systems; i++) {
254 system = read_string();
255
256 count = read4();
257 for (x=0; x < count; x++) {
258 size = read8();
259 read_event_file(system, size);
260 }
261 }
262}
263
264struct cpu_data { 50struct cpu_data {
265 unsigned long long offset; 51 unsigned long long offset;
266 unsigned long long size; 52 unsigned long long size;
@@ -629,6 +415,11 @@ static void read_rest(void)
629 } while (r > 0); 415 } while (r > 0);
630} 416}
631 417
418unsigned int read4(void);
419unsigned long long read8(void);
420int read_or_die(void *data, int size);
421extern int long_size;
422
632static void read_data_info(void) 423static void read_data_info(void)
633{ 424{
634 unsigned long long ts; 425 unsigned long long ts;
@@ -695,47 +486,11 @@ static void read_data_info(void)
695 486
696int read_trace_header(void) 487int read_trace_header(void)
697{ 488{
698 char test[] = { 23, 8, 68 };
699 char *version;
700 char buf[BUFSIZ];
701
702 input_fd = open(input_file, O_RDONLY); 489 input_fd = open(input_file, O_RDONLY);
703 if (input_fd < 0) 490 if (input_fd < 0)
704 die("opening '%s'\n", input_file); 491 die("opening '%s'\n", input_file);
705 492
706 read_or_die(buf, 3); 493 tracecmd_open(input_fd);
707 if (memcmp(buf, test, 3) != 0)
708 die("not an trace data file");
709
710 read_or_die(buf, 7);
711 if (memcmp(buf, "tracing", 7) != 0)
712 die("not a trace file (missing tracing)");
713
714 version = read_string();
715 printf("version = %s\n", version);
716 free(version);
717
718 read_or_die(buf, 1);
719 file_bigendian = buf[0];
720 host_bigendian = bigendian();
721
722 read_or_die(buf, 1);
723 long_size = buf[0];
724
725 page_size = read4();
726
727 return 0;
728}
729
730int read_trace_files(void)
731{
732 read_header_files();
733 read_ftrace_files();
734 read_event_files();
735 read_proc_kallsyms();
736 read_ftrace_printk();
737
738 trace_load_plugins();
739 494
740 return 0; 495 return 0;
741} 496}