aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorSteven Rostedt <srostedt@redhat.com>2009-12-18 10:30:25 -0500
committerSteven Rostedt <rostedt@goodmis.org>2009-12-18 10:30:25 -0500
commit40a8521b53435a97e855c7d65486da41b30f9131 (patch)
tree01a8e3ce933cacfcdc446cce971d350ce1d5f5cc
parentfc4871218e73f925b5bd6c7db33a035a5bdd472b (diff)
trace-graph: Handle function-graph hack
In order for the function graph tracer to know if the current entry is a nested function or a leaf function, it must read ahead to examine the next entry. But if the next entry happens to be on another page, doing this will unmap the current record's data. We have debug printing to the screen as we mouse over the events. The debug prints out the record's info, and this can call the function graph tracer's routine that will move the record. But then we reference the record a second time to display the same info in the drawing. This second one is using a unmapped page. For now, we hack a work around by freeing the record and rereading it after we display the debug info. Signed-off-by: Steven Rostedt <rostedt@goodmis.org>
-rw-r--r--trace-graph.c30
1 files changed, 23 insertions, 7 deletions
diff --git a/trace-graph.c b/trace-graph.c
index 13fd7c9..4303a0a 100644
--- a/trace-graph.c
+++ b/trace-graph.c
@@ -136,6 +136,10 @@ static void print_rec_info(struct record *record, struct pevent *pevent, int cpu
136 136
137 type = pevent_data_type(pevent, record); 137 type = pevent_data_type(pevent, record);
138 event = pevent_data_event_from_type(pevent, type); 138 event = pevent_data_event_from_type(pevent, type);
139 if (!event) {
140 printf("No event found for id %d!\n", type);
141 return;
142 }
139 trace_seq_puts(&s, event->name); 143 trace_seq_puts(&s, event->name);
140 trace_seq_putc(&s, ':'); 144 trace_seq_putc(&s, ':');
141 pevent_event_info(&s, event, cpu, record->data, record->size, 145 pevent_event_info(&s, event, cpu, record->data, record->size,
@@ -263,19 +267,31 @@ static void draw_cpu_info(struct graph_info *ginfo, gint cpu, gint x, gint y)
263 record->ts, time, time-(gint)(1/ginfo->resolution)); 267 record->ts, time, time-(gint)(1/ginfo->resolution));
264 print_rec_info(record, pevent, cpu); 268 print_rec_info(record, pevent, cpu);
265 269
270 /*
271 * The function graph trace reads the next record, which may
272 * unmap the record data. We need to reread the record to
273 * make sure it still exists.
274 */
275 offset = record->offset;
276 free_record(record);
277 record = tracecmd_read_at(ginfo->handle, offset, NULL);
278
266 if (record->ts > time - 2/ginfo->resolution && 279 if (record->ts > time - 2/ginfo->resolution &&
267 record->ts < time + 2/ginfo->resolution) { 280 record->ts < time + 2/ginfo->resolution) {
268 convert_nano(record->ts, &sec, &usec); 281 convert_nano(record->ts, &sec, &usec);
269 282
270 type = pevent_data_type(pevent, record); 283 type = pevent_data_type(pevent, record);
271 event = pevent_data_event_from_type(pevent, type); 284 event = pevent_data_event_from_type(pevent, type);
272 trace_seq_puts(&s, event->name); 285 if (event) {
273 trace_seq_putc(&s, '\n'); 286 trace_seq_puts(&s, event->name);
274 pevent_data_lat_fmt(pevent, &s, record->data, record->size); 287 trace_seq_putc(&s, '\n');
275 trace_seq_putc(&s, '\n'); 288 pevent_data_lat_fmt(pevent, &s, record->data, record->size);
276 pevent_event_info(&s, event, cpu, record->data, record->size, 289 trace_seq_putc(&s, '\n');
277 record->ts); 290 pevent_event_info(&s, event, cpu, record->data, record->size,
278 trace_seq_putc(&s, '\n'); 291 record->ts);
292 trace_seq_putc(&s, '\n');
293 } else
294 trace_seq_printf(&s, "UNKNOW EVENT %d\n", type);
279 } 295 }
280 296
281 trace_seq_printf(&s, "%lu.%06lu", sec, usec); 297 trace_seq_printf(&s, "%lu.%06lu", sec, usec);