diff options
author | Steven Rostedt (Red Hat) <rostedt@goodmis.org> | 2015-06-09 22:24:28 -0400 |
---|---|---|
committer | Steven Rostedt <rostedt@goodmis.org> | 2015-06-10 15:12:15 -0400 |
commit | a1f6bec35b6097cf6f3df43688a281da3c997a09 (patch) | |
tree | 8e6932a769459105621104b90b680fa557ad4230 | |
parent | 8cdbccd5ef422dc518e7246aa1c41922e834120b (diff) | |
download | trace-cmd-a1f6bec35b6097cf6f3df43688a281da3c997a09.tar.gz |
trace-cmd: Add more debugging to see various internal ring buffer entries
When trace-cmd report --debug is set, show the internal ring buffer entries
like time-extends and padding. This requires adding new kbuffer API to
retrieve these items.
Signed-off-by: Steven Rostedt <rostedt@goodmis.org>
-rw-r--r-- | kbuffer-parse.c | 49 | ||||
-rw-r--r-- | kbuffer.h | 13 | ||||
-rw-r--r-- | trace-cmd.h | 9 | ||||
-rw-r--r-- | trace-input.c | 28 | ||||
-rw-r--r-- | trace-read.c | 39 |
5 files changed, 137 insertions, 1 deletions
diff --git a/kbuffer-parse.c b/kbuffer-parse.c index fca326ca..cd13a921 100644 --- a/kbuffer-parse.c +++ b/kbuffer-parse.c @@ -767,3 +767,52 @@ int kbuffer_start_of_data(struct kbuffer *kbuf) { return kbuf->start; } + +/** + * kbuffer_raw_get - get raw buffer info + * @kbuf: The kbuffer + * @subbuf: Start of mapped subbuffer + * @info: Info descriptor to fill in + * + * For debugging. This can return internals of the ring buffer. + * Expects to have info->next set to what it will read. + * The type, length and timestamp delta will be filled in, and + * @info->next will be updated to the next element. + * The @subbuf is used to know if the info is passed the end of + * data and NULL will be returned if it is. + */ +struct kbuffer_raw_info * +kbuffer_raw_get(struct kbuffer *kbuf, void *subbuf, struct kbuffer_raw_info *info) +{ + unsigned long long flags; + unsigned long long delta; + unsigned int type_len; + unsigned int size; + int start; + int length; + void *ptr = info->next; + + if (!kbuf || !subbuf) + return NULL; + + if (kbuf->flags & KBUFFER_FL_LONG_8) + start = 16; + else + start = 12; + + flags = read_long(kbuf, subbuf + 8); + size = (unsigned int)flags & COMMIT_MASK; + + if (ptr < subbuf || ptr >= subbuf + start + size) + return NULL; + + type_len = translate_data(kbuf, ptr, &ptr, &delta, &length); + + info->next = ptr + length; + + info->type = type_len; + info->delta = delta; + info->length = length; + + return info; +} @@ -67,4 +67,17 @@ int kbuffer_subbuffer_size(struct kbuffer *kbuf); void kbuffer_set_old_format(struct kbuffer *kbuf); int kbuffer_start_of_data(struct kbuffer *kbuf); +/* Debugging */ + +struct kbuffer_raw_info { + int type; + int length; + unsigned long long delta; + void *next; +}; + +/* Read raw data */ +struct kbuffer_raw_info *kbuffer_raw_get(struct kbuffer *kbuf, void *subbuf, + struct kbuffer_raw_info *info); + #endif /* _K_BUFFER_H */ diff --git a/trace-cmd.h b/trace-cmd.h index a6983448..c9b9b955 100644 --- a/trace-cmd.h +++ b/trace-cmd.h @@ -320,4 +320,13 @@ void tracecmd_free_hooks(struct hook_list *hooks); /* --- Hack! --- */ int tracecmd_blk_hack(struct tracecmd_input *handle); + +/* --- Debugging --- */ +struct kbuffer *tracecmd_record_kbuf(struct tracecmd_input *handle, + struct pevent_record *record); +void *tracecmd_record_page(struct tracecmd_input *handle, + struct pevent_record *record); +void *tracecmd_record_offset(struct tracecmd_input *handle, + struct pevent_record *record); + #endif /* _TRACE_CMD_H */ diff --git a/trace-input.c b/trace-input.c index a7e0ff2a..76f03ee3 100644 --- a/trace-input.c +++ b/trace-input.c @@ -2847,6 +2847,34 @@ unsigned int tracecmd_record_ts_delta(struct tracecmd_input *handle, return kbuffer_ptr_delta(kbuf, page->map + offset); } +struct kbuffer *tracecmd_record_kbuf(struct tracecmd_input *handle, + struct pevent_record *record) +{ + return handle->cpu_data[record->cpu].kbuf; +} + +void *tracecmd_record_page(struct tracecmd_input *handle, + struct pevent_record *record) +{ + struct page *page = record->priv; + + return page ? page->map : NULL; +} + +void *tracecmd_record_offset(struct tracecmd_input *handle, + struct pevent_record *record) +{ + struct page *page = record->priv; + int offset; + + if (!page) + return NULL; + + offset = record->offset - page->offset; + + return page->map + offset; +} + int tracecmd_buffer_instances(struct tracecmd_input *handle) { return handle->nr_buffers; diff --git a/trace-read.c b/trace-read.c index e496ef0f..fe8f98b7 100644 --- a/trace-read.c +++ b/trace-read.c @@ -37,6 +37,7 @@ #include "trace-local.h" #include "trace-hash.h" +#include "kbuffer.h" #include "list.h" static struct filter_str { @@ -774,9 +775,45 @@ void trace_show_data(struct tracecmd_input *handle, struct pevent_record *record pevent_print_event(pevent, &s, record, use_trace_clock); if (s.len && *(s.buffer + s.len - 1) == '\n') s.len--; - if (debug) + if (debug) { + struct kbuffer *kbuf; + struct kbuffer_raw_info info; + void *page; + void *offset; + trace_seq_printf(&s, " [%d]", tracecmd_record_ts_delta(handle, record)); + kbuf = tracecmd_record_kbuf(handle, record); + page = tracecmd_record_page(handle, record); + offset = tracecmd_record_offset(handle, record); + + if (kbuf && page && offset) { + struct kbuffer_raw_info *pi = &info; + + /* We need to get the record raw data to get next */ + pi->next = offset; + pi = kbuffer_raw_get(kbuf, page, pi); + while ((pi = kbuffer_raw_get(kbuf, page, pi))) { + if (pi->type < KBUFFER_TYPE_PADDING) + break; + switch (pi->type) { + case KBUFFER_TYPE_PADDING: + trace_seq_printf(&s, "\n PADDING: "); + break; + case KBUFFER_TYPE_TIME_EXTEND: + trace_seq_printf(&s, "\n TIME EXTEND: "); + break; + case KBUFFER_TYPE_TIME_STAMP: + trace_seq_printf(&s, "\n TIME STAMP?: "); + break; + } + trace_seq_printf(&s, "delta:%lld length:%d", + pi->delta, + pi->length); + } + } + } + trace_seq_do_printf(&s); trace_seq_destroy(&s); |