|
|
e96142 |
--- crash-trace-command-2.0/trace.c.orig
|
|
|
e96142 |
+++ crash-trace-command-2.0/trace.c
|
|
|
e96142 |
@@ -26,9 +26,21 @@ static int nr_cpu_ids;
|
|
|
e96142 |
*/
|
|
|
e96142 |
static int lockless_ring_buffer;
|
|
|
e96142 |
static int per_cpu_buffer_sizes;
|
|
|
e96142 |
+/*
|
|
|
e96142 |
+ * global and encapsulated current_trace are both supported
|
|
|
e96142 |
+ */
|
|
|
e96142 |
+static int encapsulated_current_trace;
|
|
|
e96142 |
+/*
|
|
|
e96142 |
+ * trace_buffer is supported
|
|
|
e96142 |
+ */
|
|
|
e96142 |
+static int trace_buffer_available;
|
|
|
e96142 |
|
|
|
e96142 |
#define koffset(struct, member) struct##_##member##_offset
|
|
|
e96142 |
|
|
|
e96142 |
+static int koffset(trace_array, current_trace);
|
|
|
e96142 |
+static int koffset(trace_array, trace_buffer);
|
|
|
e96142 |
+static int koffset(trace_array, max_buffer);
|
|
|
e96142 |
+static int koffset(trace_buffer, buffer);
|
|
|
e96142 |
static int koffset(trace_array, buffer);
|
|
|
e96142 |
static int koffset(tracer, name);
|
|
|
e96142 |
|
|
|
e96142 |
@@ -85,6 +97,8 @@ struct ring_buffer_per_cpu {
|
|
|
e96142 |
};
|
|
|
e96142 |
|
|
|
e96142 |
static ulong global_trace;
|
|
|
e96142 |
+static ulong global_trace_buffer;
|
|
|
e96142 |
+static ulong global_max_buffer;
|
|
|
e96142 |
static ulong global_ring_buffer;
|
|
|
e96142 |
static unsigned global_pages;
|
|
|
e96142 |
static struct ring_buffer_per_cpu *global_buffers;
|
|
|
e96142 |
@@ -144,8 +158,16 @@ static int init_offsets(void)
|
|
|
e96142 |
} \
|
|
|
e96142 |
} while (0)
|
|
|
e96142 |
|
|
|
e96142 |
+ if (encapsulated_current_trace)
|
|
|
e96142 |
+ init_offset(trace_array, current_trace);
|
|
|
e96142 |
|
|
|
e96142 |
- init_offset(trace_array, buffer);
|
|
|
e96142 |
+ if (trace_buffer_available) {
|
|
|
e96142 |
+ init_offset(trace_array, trace_buffer);
|
|
|
e96142 |
+ init_offset(trace_array, max_buffer);
|
|
|
e96142 |
+ init_offset(trace_buffer, buffer);
|
|
|
e96142 |
+ } else {
|
|
|
e96142 |
+ init_offset(trace_array, buffer);
|
|
|
e96142 |
+ }
|
|
|
e96142 |
init_offset(tracer, name);
|
|
|
e96142 |
|
|
|
e96142 |
if (MEMBER_EXISTS("ring_buffer_per_cpu", "nr_pages")) {
|
|
|
e96142 |
@@ -400,8 +422,13 @@ out_fail:
|
|
|
e96142 |
|
|
|
e96142 |
static int ftrace_int_global_trace(void)
|
|
|
e96142 |
{
|
|
|
e96142 |
- read_value(global_ring_buffer, global_trace, trace_array, buffer);
|
|
|
e96142 |
- read_value(global_pages, global_ring_buffer, ring_buffer, pages);
|
|
|
e96142 |
+ if (trace_buffer_available) {
|
|
|
e96142 |
+ global_trace_buffer = global_trace + koffset(trace_array, trace_buffer);
|
|
|
e96142 |
+ read_value(global_ring_buffer, global_trace_buffer, trace_buffer, buffer);
|
|
|
e96142 |
+ } else {
|
|
|
e96142 |
+ read_value(global_ring_buffer, global_trace, trace_array, buffer);
|
|
|
e96142 |
+ read_value(global_pages, global_ring_buffer, ring_buffer, pages);
|
|
|
e96142 |
+ }
|
|
|
e96142 |
|
|
|
e96142 |
global_buffers = calloc(sizeof(*global_buffers), nr_cpu_ids);
|
|
|
e96142 |
if (global_buffers == NULL)
|
|
|
e96142 |
@@ -420,12 +447,17 @@ out_fail:
|
|
|
e96142 |
|
|
|
e96142 |
static int ftrace_int_max_tr_trace(void)
|
|
|
e96142 |
{
|
|
|
e96142 |
- read_value(max_tr_ring_buffer, max_tr_trace, trace_array, buffer);
|
|
|
e96142 |
+ if (trace_buffer_available) {
|
|
|
e96142 |
+ global_max_buffer = global_trace + koffset(trace_array, max_buffer);
|
|
|
e96142 |
+ read_value(max_tr_ring_buffer, global_max_buffer, trace_buffer, buffer);
|
|
|
e96142 |
+ } else {
|
|
|
e96142 |
+ read_value(max_tr_ring_buffer, max_tr_trace, trace_array, buffer);
|
|
|
e96142 |
|
|
|
e96142 |
- if (!max_tr_ring_buffer)
|
|
|
e96142 |
- return 0;
|
|
|
e96142 |
+ if (!max_tr_ring_buffer)
|
|
|
e96142 |
+ return 0;
|
|
|
e96142 |
|
|
|
e96142 |
- read_value(max_tr_pages, max_tr_ring_buffer, ring_buffer, pages);
|
|
|
e96142 |
+ read_value(max_tr_pages, max_tr_ring_buffer, ring_buffer, pages);
|
|
|
e96142 |
+ }
|
|
|
e96142 |
|
|
|
e96142 |
max_tr_buffers = calloc(sizeof(*max_tr_buffers), nr_cpu_ids);
|
|
|
e96142 |
if (max_tr_buffers == NULL)
|
|
|
e96142 |
@@ -449,7 +481,12 @@ static int ftrace_init_current_tracer(vo
|
|
|
e96142 |
char tmp[128];
|
|
|
e96142 |
|
|
|
e96142 |
/* Get current tracer name */
|
|
|
e96142 |
- read_value(addr, current_trace, POINTER_SYM, POINTER);
|
|
|
e96142 |
+ if (encapsulated_current_trace) {
|
|
|
e96142 |
+ read_value(addr, global_trace, trace_array, current_trace);
|
|
|
e96142 |
+ } else {
|
|
|
e96142 |
+ read_value(addr, current_trace, POINTER_SYM, POINTER);
|
|
|
e96142 |
+ }
|
|
|
e96142 |
+
|
|
|
e96142 |
read_value(addr, addr, tracer, name);
|
|
|
e96142 |
read_string(addr, tmp, 128);
|
|
|
e96142 |
|
|
|
e96142 |
@@ -471,19 +508,33 @@ static int ftrace_init(void)
|
|
|
e96142 |
struct syment *sym_current_trace;
|
|
|
e96142 |
|
|
|
e96142 |
sym_global_trace = symbol_search("global_trace");
|
|
|
e96142 |
- sym_max_tr_trace = symbol_search("max_tr");
|
|
|
e96142 |
sym_ftrace_events = symbol_search("ftrace_events");
|
|
|
e96142 |
- sym_current_trace = symbol_search("current_trace");
|
|
|
e96142 |
|
|
|
e96142 |
- if (sym_global_trace == NULL || sym_max_tr_trace == NULL
|
|
|
e96142 |
- || sym_ftrace_events == NULL
|
|
|
e96142 |
- || sym_current_trace == NULL)
|
|
|
e96142 |
+ if (sym_global_trace == NULL || sym_ftrace_events == NULL)
|
|
|
e96142 |
return -1;
|
|
|
e96142 |
|
|
|
e96142 |
global_trace = sym_global_trace->value;
|
|
|
e96142 |
- max_tr_trace = sym_max_tr_trace->value;
|
|
|
e96142 |
ftrace_events = sym_ftrace_events->value;
|
|
|
e96142 |
- current_trace = sym_current_trace->value;
|
|
|
e96142 |
+
|
|
|
e96142 |
+ if (MEMBER_EXISTS("trace_array", "current_trace")) {
|
|
|
e96142 |
+ encapsulated_current_trace = 1;
|
|
|
e96142 |
+ } else {
|
|
|
e96142 |
+ sym_current_trace = symbol_search("current_trace");
|
|
|
e96142 |
+ if (sym_current_trace == NULL)
|
|
|
e96142 |
+ return -1;
|
|
|
e96142 |
+
|
|
|
e96142 |
+ current_trace = sym_current_trace->value;
|
|
|
e96142 |
+ }
|
|
|
e96142 |
+
|
|
|
e96142 |
+ if (MEMBER_EXISTS("trace_array", "trace_buffer")) {
|
|
|
e96142 |
+ trace_buffer_available = 1;
|
|
|
e96142 |
+ } else {
|
|
|
e96142 |
+ sym_max_tr_trace = symbol_search("max_tr");
|
|
|
e96142 |
+ if (sym_max_tr_trace == NULL)
|
|
|
e96142 |
+ return -1;
|
|
|
e96142 |
+
|
|
|
e96142 |
+ max_tr_trace = sym_max_tr_trace->value;
|
|
|
e96142 |
+ }
|
|
|
e96142 |
|
|
|
e96142 |
if (!try_get_symbol_data("nr_cpu_ids", sizeof(int), &nr_cpu_ids))
|
|
|
e96142 |
nr_cpu_ids = 1;
|
|
|
e96142 |
@@ -1453,6 +1504,7 @@ static void ftrace_show(int argc, char *
|
|
|
e96142 |
if ((file = popen(trace_cmd, "r"))) {
|
|
|
e96142 |
ret = fread(buf, 1, sizeof(buf), file);
|
|
|
e96142 |
buf[ret] = 0;
|
|
|
e96142 |
+ pclose(file);
|
|
|
e96142 |
}
|
|
|
e96142 |
if (!strstr(buf, "trace-cmd version")) {
|
|
|
e96142 |
if (env_trace_cmd)
|