Linux Kernel  3.7.1
 All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Macros Groups Pages
trace_kdb.c
Go to the documentation of this file.
1 /*
2  * kdb helper for dumping the ftrace buffer
3  *
4  * Copyright (C) 2010 Jason Wessel <[email protected]>
5  *
6  * ftrace_dump_buf based on ftrace_dump:
7  * Copyright (C) 2007-2008 Steven Rostedt <[email protected]>
8  * Copyright (C) 2008 Ingo Molnar <[email protected]>
9  *
10  */
11 #include <linux/init.h>
12 #include <linux/kgdb.h>
13 #include <linux/kdb.h>
14 #include <linux/ftrace.h>
15 
16 #include "trace.h"
17 #include "trace_output.h"
18 
19 static void ftrace_dump_buf(int skip_lines, long cpu_file)
20 {
21  /* use static because iter can be a bit big for the stack */
22  static struct trace_iterator iter;
23  unsigned int old_userobj;
24  int cnt = 0, cpu;
25 
27 
29  atomic_inc(&iter.tr->data[cpu]->disabled);
30  }
31 
32  old_userobj = trace_flags;
33 
34  /* don't look at user memory in panic mode */
36 
37  kdb_printf("Dumping ftrace buffer:\n");
38 
39  /* reset all but tr, trace, and overruns */
40  memset(&iter.seq, 0,
41  sizeof(struct trace_iterator) -
42  offsetof(struct trace_iterator, seq));
43  iter.iter_flags |= TRACE_FILE_LAT_FMT;
44  iter.pos = -1;
45 
46  if (cpu_file == TRACE_PIPE_ALL_CPU) {
48  iter.buffer_iter[cpu] =
49  ring_buffer_read_prepare(iter.tr->buffer, cpu);
50  ring_buffer_read_start(iter.buffer_iter[cpu]);
51  tracing_iter_reset(&iter, cpu);
52  }
53  } else {
54  iter.cpu_file = cpu_file;
55  iter.buffer_iter[cpu_file] =
56  ring_buffer_read_prepare(iter.tr->buffer, cpu_file);
57  ring_buffer_read_start(iter.buffer_iter[cpu_file]);
58  tracing_iter_reset(&iter, cpu_file);
59  }
60  if (!trace_empty(&iter))
62  while (!trace_empty(&iter)) {
63  if (!cnt)
64  kdb_printf("---------------------------------\n");
65  cnt++;
66 
67  if (trace_find_next_entry_inc(&iter) != NULL && !skip_lines)
68  print_trace_line(&iter);
69  if (!skip_lines)
70  trace_printk_seq(&iter.seq);
71  else
72  skip_lines--;
73  if (KDB_FLAG(CMD_INTERRUPT))
74  goto out;
75  }
76 
77  if (!cnt)
78  kdb_printf(" (ftrace buffer empty)\n");
79  else
80  kdb_printf("---------------------------------\n");
81 
82 out:
83  trace_flags = old_userobj;
84 
86  atomic_dec(&iter.tr->data[cpu]->disabled);
87  }
88 
90  if (iter.buffer_iter[cpu])
92 }
93 
94 /*
95  * kdb_ftdump - Dump the ftrace log buffer
96  */
97 static int kdb_ftdump(int argc, const char **argv)
98 {
99  int skip_lines = 0;
100  long cpu_file;
101  char *cp;
102 
103  if (argc > 2)
104  return KDB_ARGCOUNT;
105 
106  if (argc) {
107  skip_lines = simple_strtol(argv[1], &cp, 0);
108  if (*cp)
109  skip_lines = 0;
110  }
111 
112  if (argc == 2) {
113  cpu_file = simple_strtol(argv[2], &cp, 0);
114  if (*cp || cpu_file >= NR_CPUS || cpu_file < 0 ||
115  !cpu_online(cpu_file))
116  return KDB_BADINT;
117  } else {
118  cpu_file = TRACE_PIPE_ALL_CPU;
119  }
120 
121  kdb_trap_printk++;
122  ftrace_dump_buf(skip_lines, cpu_file);
123  kdb_trap_printk--;
124 
125  return 0;
126 }
127 
128 static __init int kdb_ftrace_register(void)
129 {
130  kdb_register_repeat("ftdump", kdb_ftdump, "[skip_#lines] [cpu]",
131  "Dump ftrace log", 0, KDB_REPEAT_NONE);
132  return 0;
133 }
134 
135 late_initcall(kdb_ftrace_register);