Create a LttvEvent object
[lttv.git] / lttv / lttv / print.c
CommitLineData
8e680509 1/* This file is part of the Linux Trace Toolkit viewer
2 * Copyright (C) 2003-2004 Michel Dagenais
3 * 2005 Mathieu Desnoyers
4 *
5 * This program is free software; you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License Version 2 as
7 * published by the Free Software Foundation;
8 *
9 * This program is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU General Public License for more details.
13 *
14 * You should have received a copy of the GNU General Public License
15 * along with this program; if not, write to the Free Software
16 * Foundation, Inc., 59 Temple Place - Suite 330, Boston,
17 * MA 02111-1307, USA.
18 */
19
20/* print.c
21 *
5290ec02 22 * Event printing routines.
23 */
8e680509 24
25#ifdef HAVE_CONFIG_H
26#include <config.h>
27#endif
28
29#include <lttv/lttv.h>
30#include <lttv/option.h>
31#include <lttv/module.h>
32#include <lttv/hook.h>
33#include <lttv/attribute.h>
34#include <lttv/iattribute.h>
35#include <lttv/stats.h>
36#include <lttv/filter.h>
37#include <lttv/print.h>
38#include <ltt/ltt.h>
39#include <ltt/event.h>
8e680509 40#include <ltt/trace.h>
8e680509 41#include <stdio.h>
73e6c609 42#include <ctype.h>
95868736 43#include <ltt/ltt-private.h>
73ccabb3 44#include <babeltrace/ctf/events.h>
e8548639 45#include <string.h>
43ed82b5 46#include <inttypes.h>
556b540a 47#include <lttv/event.h>
e8548639 48
cf453ac7 49static inline void print_enum_events(LttEvent *e, struct marker_field *f,
90e19f82 50 guint64 value, GString *s, LttvTracefileState *tfs)
cf453ac7 51{
90e19f82
AM
52 LttTracefile *tf = tfs->parent.tf;
53 struct marker_info *info = marker_get_info_from_id(tf->mdata, e->event_id);
54 LttvTraceState *ts = (LttvTraceState*)(tfs->parent.t_context);
55 LttvNameTables *nt = ts->name_tables;
56
57 if (tf->name == LTT_CHANNEL_KERNEL) {
58 if (info->name == LTT_EVENT_SYSCALL_ENTRY
59 && f->name == LTT_FIELD_SYSCALL_ID) {
60 g_string_append_printf(s, " [%s]",
61 g_quark_to_string(nt->syscall_names[value]));
62 } else if ((info->name == LTT_EVENT_SOFT_IRQ_ENTRY
63 || info->name == LTT_EVENT_SOFT_IRQ_EXIT
64 || info->name == LTT_EVENT_SOFT_IRQ_RAISE)
65 && f->name == LTT_FIELD_SOFT_IRQ_ID) {
66 g_string_append_printf(s, " [%s]",
67 g_quark_to_string(nt->soft_irq_names[value]));
68 } else if (info->name == LTT_EVENT_KPROBE
69 && f->name == LTT_FIELD_IP) {
e9a5b514 70#if (__WORDSIZE == 32)
90e19f82
AM
71 GQuark symbol = (GQuark)g_hash_table_lookup(nt->kprobe_hash,
72 (gconstpointer)&value);
9ee1ff6a 73#else
90e19f82
AM
74 GQuark symbol = (GQuark)(unsigned long)g_hash_table_lookup(nt->kprobe_hash,
75 (gconstpointer)value);
9ee1ff6a 76#endif
90e19f82
AM
77 if (symbol)
78 g_string_append_printf(s, " [%s]", g_quark_to_string(symbol));
79 }
80 }
cf453ac7 81}
8e680509 82
95868736 83void lttv_print_field(LttEvent *e, struct marker_field *f, GString *s,
90e19f82 84 gboolean field_names, LttvTracefileState *tfs)
95868736 85{
90e19f82
AM
86 GQuark name;
87 guint64 value;
88
89 //int nb, i;
8e680509 90
90e19f82
AM
91 switch(f->type) {
92 case LTT_TYPE_SIGNED_INT:
93 if(field_names) {
94 name = f->name;
95 if(name)
96 g_string_append_printf(s, "%s = ", g_quark_to_string(name));
97 }
98 value = ltt_event_get_long_int(e,f);
99 //g_string_append_printf(s, "%lld", value);
100 g_string_append_printf(s, f->fmt->str, value);
101 //g_string_append_printf(s, type->fmt, ltt_event_get_long_int(e,f));
102 print_enum_events(e, f, value, s, tfs);
103 break;
8e680509 104
90e19f82
AM
105 case LTT_TYPE_UNSIGNED_INT:
106 if(field_names) {
107 name = f->name;
108 if(name)
109 g_string_append_printf(s, "%s = ", g_quark_to_string(name));
110 }
111 value = ltt_event_get_long_unsigned(e,f);
112 //g_string_append_printf(s, "%llu", value);
113 g_string_append_printf(s, f->fmt->str, value);
114 print_enum_events(e, f, value, s, tfs);
115 //g_string_append_printf(s, type->fmt, ltt_event_get_long_unsigned(e,f));
116 break;
8e680509 117
95868736 118#if 0
90e19f82
AM
119 case LTT_CHAR:
120 case LTT_UCHAR:
121 {
122 unsigned car = ltt_event_get_unsigned(e,f);
123 if(field_names) {
124 name = ltt_field_name(f);
125 if(name)
126 g_string_append_printf(s, "%s = ", g_quark_to_string(name));
127 }
128 if(isprint(car)) {
129 if(field_names) {
130 name = ltt_field_name(f);
131 if(name)
132 g_string_append_printf(s, "%s = ", g_quark_to_string(name));
133 }
134 //g_string_append_printf(s, "%c", car);
135 g_string_append_printf(s, type->fmt, car);
136 } else {
137 g_string_append_printf(s, "\\%x", car);
138 }
139 }
140 break;
141 case LTT_FLOAT:
142 if(field_names) {
143 name = ltt_field_name(f);
144 if(name)
145 g_string_append_printf(s, "%s = ", g_quark_to_string(name));
146 }
147 //g_string_append_printf(s, "%g", ltt_event_get_double(e,f));
148 g_string_append_printf(s, type->fmt, ltt_event_get_double(e,f));
149 break;
91346f59 150#endif
8e680509 151
90e19f82
AM
152 case LTT_TYPE_POINTER:
153 if(field_names) {
154 name = f->name;
155 if(name)
156 g_string_append_printf(s, "%s = ", g_quark_to_string(name));
157 }
158 g_string_append_printf(s, "0x%" PRIx64, ltt_event_get_long_unsigned(e,f));
159 //g_string_append_printf(s, type->fmt, ltt_event_get_long_unsigned(e,f));
160 break;
8e680509 161
90e19f82
AM
162 case LTT_TYPE_STRING:
163 if(field_names) {
164 name = f->name;
165 if(name)
166 g_string_append_printf(s, "%s = ", g_quark_to_string(name));
167 }
168 g_string_append_printf(s, "\"%s\"", ltt_event_get_string(e,f));
169 break;
8e680509 170
95868736 171#if 0
90e19f82
AM
172 case LTT_ENUM:
173 {
174 GQuark value = ltt_enum_string_get(type, ltt_event_get_unsigned(e,f));
175 if(field_names) {
176 name = ltt_field_name(f);
177 if(name)
178 g_string_append_printf(s, "%s = ", g_quark_to_string(name));
179 }
180 if(value)
181 g_string_append_printf(s, "%s", g_quark_to_string(value));
182 else
183 g_string_append_printf(s, "%lld", ltt_event_get_long_int(e,f));
184 }
185 break;
8e680509 186
90e19f82
AM
187 case LTT_ARRAY:
188 case LTT_SEQUENCE:
189 if(field_names) {
190 name = ltt_field_name(f);
191 if(name)
192 g_string_append_printf(s, "%s = ", g_quark_to_string(name));
193 }
194 // g_string_append_printf(s, "{ ");
195 //Insert header
196 g_string_append_printf(s, type->header);//tested, works fine.
e8548639 197
198
90e19f82
AM
199 nb = ltt_event_field_element_number(e,f);
200 for(i = 0 ; i < nb ; i++) {
201 LttField *child = ltt_event_field_element_select(e,f,i);
202 lttv_print_field(e, child, s, field_names, i);
e8548639 203 if(i<nb-1)
90e19f82
AM
204 g_string_append_printf(s,type->separator);
205 }
206 //g_string_append_printf(s, " }");
207 //Insert footer
208 g_string_append_printf(s, type->footer);//tested, works fine.
209 break;
8e680509 210
90e19f82
AM
211 case LTT_STRUCT:
212 if(field_names) {
213 name = ltt_field_name(f);
214 if(name)
215 g_string_append_printf(s, "%s = ", g_quark_to_string(name));
216 }
217 // g_string_append_printf(s, "{ ");
218 //Insert header
219 g_string_append_printf(s, type->header);
e8548639 220
90e19f82
AM
221 nb = ltt_type_member_number(type);
222 for(i = 0 ; i < nb ; i++) {
223 LttField *element;
224 element = ltt_field_member(f,i);
225 lttv_print_field(e, element, s, field_names, i);
e8548639 226 if(i < nb-1)
90e19f82
AM
227 g_string_append_printf(s,type->separator);
228 }
229 //g_string_append_printf(s, " }");
230 //Insert footer
231 g_string_append_printf(s, type->footer);
232 break;
8e680509 233
90e19f82
AM
234 case LTT_UNION:
235 if(field_names) {
236 name = ltt_field_name(f);
237 if(name)
238 g_string_append_printf(s, "%s = ", g_quark_to_string(name));
239 }
240 // g_string_append_printf(s, "{ ");
241 g_string_append_printf(s, type->header);
e8548639 242
90e19f82
AM
243 nb = ltt_type_member_number(type);
244 for(i = 0 ; i < nb ; i++) {
245 LttField *element;
246 element = ltt_field_member(f,i);
247 lttv_print_field(e, element, s, field_names, i);
e8548639 248 if(i<nb-1)
90e19f82
AM
249 g_string_append_printf(s, type->separator);
250 }
251 // g_string_append_printf(s, " }");
252 g_string_append_printf(s, type->footer);
253 break;
95868736 254#endif
90e19f82
AM
255 case LTT_TYPE_COMPACT:
256 g_error("compact type printing not implemented");
257 break;
258 case LTT_TYPE_NONE:
259 break;
260 }
8e680509 261}
262
73ccabb3
HM
263int getProcessInfosFromEvent(struct bt_ctf_event *ctf_event, GString* processInfos)
264{
265 int pid, tid, ppid;
266 char *procname;
267 struct definition *scope;
268 unsigned long timestamp;
269
270 int ret = 0;
271
272 gboolean noError = TRUE;
273
274 timestamp = bt_ctf_get_timestamp(ctf_event);
275 if (timestamp == -1ULL) {
276 noError = FALSE;
277 }
278 if (noError) {
279 scope = bt_ctf_get_top_level_scope(ctf_event, BT_STREAM_EVENT_CONTEXT);
280 if (bt_ctf_field_get_error()) {
281 noError = FALSE;
282 }
283 }
284 if (noError) {
285 pid = bt_ctf_get_int64(bt_ctf_get_field(ctf_event, scope, "_pid"));
286 if (bt_ctf_field_get_error()) {
287 noError = FALSE;
288 }
289 }
290 if (noError) {
291 tid = bt_ctf_get_int64(bt_ctf_get_field(ctf_event, scope, "_tid"));
292 if (bt_ctf_field_get_error()) {
293 noError = FALSE;
294 }
295 }
296 if (noError) {
297 ppid = bt_ctf_get_int64(bt_ctf_get_field(ctf_event, scope, "_ppid"));
298 if (bt_ctf_field_get_error()) {
299 noError = FALSE;
300 }
301 }
302 if (noError) {
303 procname = bt_ctf_get_char_array(bt_ctf_get_field(ctf_event, scope, "_procname"));
304 if (bt_ctf_field_get_error()) {
305 noError = FALSE;
306 }
307 }
308
309 if (noError) {
310 g_string_append_printf(processInfos, "%u, %u, %s, %u", pid, tid, procname, ppid);
311 }
312 else {
313 ret = -1;
314 }
315
316 return ret;
317}
318
319
320int getCPUIdFromEvent(struct bt_ctf_event *ctf_event, GString* cpuId_str)
321{
322 struct definition *scope;
323 unsigned long timestamp;
324 unsigned int cpu_id;
325 int ret = 0;
326
327 gboolean noError = TRUE;
328
329 timestamp = bt_ctf_get_timestamp(ctf_event);
330 if (timestamp == -1ULL) {
331 noError = FALSE;
332 }
333 if (noError) {
334 scope = bt_ctf_get_top_level_scope(ctf_event, BT_STREAM_PACKET_CONTEXT);
335 if (bt_ctf_field_get_error()) {
336 noError = FALSE;
337 }
338 }
339 if (noError) {
340 cpu_id = bt_ctf_get_uint64(bt_ctf_get_field(ctf_event, scope, "cpu_id"));
341 if (bt_ctf_field_get_error()) {
342 noError = FALSE;
343 }
344 else {
345 g_string_append_printf(cpuId_str, "%u", cpu_id);
346 }
347 }
348
349 if (!noError) {
350 ret = -1;
351 }
352
353 return ret;
354}
355
356int getFields(struct bt_ctf_event *ctf_event, struct definition const *fields, GString* fieldsStr)
357{
358 enum ctf_type_id fieldType = bt_ctf_field_type(fields);
359 int ret = 0, isSigned = -1, len = 0, i = 0;
360 struct definition *index_def;
361 switch (fieldType) {
362 case CTF_TYPE_INTEGER:
363 isSigned = bt_ctf_get_int_signedness(fields);
364 if (isSigned == 1) {
365 g_string_append_printf(fieldsStr, "%lu", bt_ctf_get_int64(fields));
366 }
367 else if (isSigned == 0) {
368 g_string_append_printf(fieldsStr, "%llu", bt_ctf_get_uint64(fields));
369 }
370 break;
371 case CTF_TYPE_STRING:
372 g_string_append_printf(fieldsStr, "%s", bt_ctf_get_string(fields));
373 break;
374
375 case CTF_TYPE_ARRAY:
376 g_string_append_printf(fieldsStr, "[ ");
377 len = bt_ctf_get_array_len(fields);
378 if (index_def = bt_ctf_get_index(ctf_event, fields, i)) {
379 for (i = 0; i < len; i++) {
380 if (i > 0) {
381 g_string_append_printf(fieldsStr, ", ");
382 }
383 bt_ctf_field_type(bt_ctf_get_index(ctf_event, fields, i));
384 g_string_append_printf(fieldsStr, " ");
385 g_string_append_printf(fieldsStr, "[%d] = ");
386 getFields(ctf_event, bt_ctf_get_index(ctf_event, fields, i), fieldsStr);
387 }
388 }
389 else {
390 g_string_append_printf(fieldsStr, "%s", bt_ctf_get_char_array(fields));
391 }
392 g_string_append_printf(fieldsStr, " ]");
393
394 break;
395 case CTF_TYPE_UNKNOWN:
396 default:
397 break;
398 }
399 return ret;
400}
401
402int getFieldsFromEvent(struct bt_ctf_event *ctf_event, GString* fields, gboolean field_names)
403{
404 struct definition const * const *list = NULL;
405 unsigned int count;
406 int i = 0, j = 0, ret = 0;
407 gboolean noError = TRUE;
408 struct definition *scope;
409 scope = bt_ctf_get_top_level_scope(ctf_event, BT_EVENT_FIELDS);
410
411 if (!scope) {
412 noError = FALSE;
413 }
414 if (noError) {
415 ret = bt_ctf_get_field_list(ctf_event, scope, &list, &count);
416 if (ret < 0) {
417 noError = TRUE;
418 }
419 else {
420 for (i = 0; i < count; i++) {
421 if (i > 0) {
422 g_string_append_printf(fields, ", ");
423 }
424 const char *name = bt_ctf_field_name(list[i]);
425 if (field_names) {
426 g_string_append_printf(fields, "%s = ", name);
427 }
428 getFields(ctf_event, list[i] ,fields);
429 if (bt_ctf_field_get_error()) {
430 continue;
431 }
432 }
433 }
434 }
435 if (!noError) {
436 ret = -1;
437 }
438 return ret;
439}
440
556b540a 441void lttv_event_to_string(LttvEvent *event, GString *a_string, gboolean field_names)
73ccabb3
HM
442{
443 GString* processInfos = g_string_new("");
444 GString* fields = g_string_new("");
445 GString* cpuId_str = g_string_new("");
446
556b540a
YB
447 getProcessInfosFromEvent(event->bt_event, processInfos);
448 getFieldsFromEvent(event->bt_event, fields, field_names);
449 getCPUIdFromEvent(event->bt_event, cpuId_str);
73ccabb3
HM
450
451 g_string_set_size(a_string,0);
452
556b540a 453 g_string_append_printf(a_string, "%llu %s: { %s }", bt_ctf_get_timestamp(event->bt_event), bt_ctf_event_name(event->bt_event), cpuId_str->str);
73ccabb3
HM
454 if (strcmp("", processInfos->str) < 0) {
455 g_string_append_printf(a_string, ", { %s }", processInfos->str);
456 }
457 if (strcmp("", fields->str) < 0) {
458 g_string_append_printf(a_string, ", { %s }", fields->str);
459 }
460
461 g_string_free(fields, TRUE);
462 g_string_free(processInfos, TRUE);
463 g_string_free(cpuId_str, TRUE);
464}
465
466#ifdef BABEL_CLEANUP
90e19f82
AM
467void lttv_event_to_string(LttEvent *e, GString *s, gboolean mandatory_fields,
468 gboolean field_names, LttvTracefileState *tfs)
8e680509 469{
90e19f82
AM
470 struct marker_field *field;
471 struct marker_info *info;
472
473 LttTime time;
8e680509 474
90e19f82
AM
475 guint cpu = tfs->cpu;
476 LttvTraceState *ts = (LttvTraceState*)tfs->parent.t_context;
477 LttvProcessState *process = ts->running_process[cpu];
8e680509 478
90e19f82 479 s = g_string_set_size(s,0);
76373d36 480
90e19f82 481 info = marker_get_info_from_id(tfs->parent.tf->mdata, e->event_id);
8e680509 482
90e19f82
AM
483 if(mandatory_fields) {
484 time = ltt_event_time(e);
485 g_string_append_printf(s,"%s.%s: %ld.%09ld (%s/%s_%u)",
486 g_quark_to_string(ltt_tracefile_name(tfs->parent.tf)),
487 g_quark_to_string(info->name), (long)time.tv_sec, time.tv_nsec,
488 g_quark_to_string(
489 ltt_trace_name(ltt_tracefile_get_trace(tfs->parent.tf))),
490 g_quark_to_string(ltt_tracefile_name(tfs->parent.tf)), cpu);
491 /* Print the process id and the state/interrupt type of the process */
492 g_string_append_printf(s,", %u, %u, %s, %s, %u, 0x%" PRIx64", %s",
493 process->pid,
494 process->tgid,
495 g_quark_to_string(process->name),
496 g_quark_to_string(process->brand),
497 process->ppid,
498 process->current_function,
499 g_quark_to_string(process->state->t));
500 }
8e680509 501
90e19f82
AM
502 if(marker_get_num_fields(info) == 0) return;
503 g_string_append_printf(s, " ");
504 g_string_append_printf(s, "{ ");
505 for (field = marker_get_field(info, 0);
506 field != marker_get_field(info, marker_get_num_fields(info));
507 field++) {
508 if(field != marker_get_field(info, 0))
509 g_string_append_printf(s, ", ");
510 lttv_print_field(e, field, s, field_names, tfs);
511 }
512 g_string_append_printf(s, " }");
8e680509 513}
73ccabb3 514#endif /* BABEL_CLEANUP */
8e680509 515
516static void init()
517{
518}
519
520static void destroy()
521{
522}
523
524LTTV_MODULE("print", "Print events", \
90e19f82
AM
525 "Produce a detailed text printout of events", \
526 init, destroy)
8e680509 527
This page took 0.078344 seconds and 4 git commands to generate.