2 * Stack tracing functions
3 * Copyright (C) 2005-2009 Red Hat Inc.
4 * Copyright (C) 2005 Intel Corporation.
6 * This file is part of systemtap, and is free software. You can
7 * redistribute it and/or modify it under the terms of the GNU General
8 * Public License (GPL); either version 2, or (at your option) any
16 * @brief Stack Tracing Functions
19 /** @addtogroup stack Stack Tracing Functions
28 #define MAXBACKTRACE 20
30 #if defined(STAPCONF_KERNEL_STACKTRACE)
31 #include <linux/stacktrace.h>
32 #include <asm/stacktrace.h>
35 static void _stp_stack_print_fallback(unsigned long, int, int);
37 #if defined (__x86_64__)
38 #include "stack-x86_64.c"
39 #elif defined (__ia64__)
40 #include "stack-ia64.c"
41 #elif defined (__i386__)
42 #include "stack-i386.c"
43 #elif defined (__powerpc__)
44 #include "stack-ppc.c"
45 #elif defined (__arm__)
46 #include "stack-arm.c"
47 #elif defined (__s390__) || defined (__s390x__)
48 #include "stack-s390.c"
50 #error "Unsupported architecture"
53 #if defined(STAPCONF_KERNEL_STACKTRACE)
55 struct print_stack_data
62 static void print_stack_warning(void *data
, char *msg
)
67 print_stack_warning_symbol(void *data
, char *msg
, unsigned long symbol
)
71 static int print_stack_stack(void *data
, char *name
)
76 static void print_stack_address(void *data
, unsigned long addr
, int reliable
)
78 struct print_stack_data
*sdata
= data
;
79 if (sdata
->level
++ < sdata
->max_level
)
80 _stp_func_print(addr
, sdata
->verbose
, 0, NULL
);
83 static const struct stacktrace_ops print_stack_ops
= {
84 .warning
= print_stack_warning
,
85 .warning_symbol
= print_stack_warning_symbol
,
86 .stack
= print_stack_stack
,
87 .address
= print_stack_address
,
90 static void _stp_stack_print_fallback(unsigned long stack
, int verbose
, int levels
)
92 struct print_stack_data print_data
;
93 print_data
.verbose
= verbose
;
94 print_data
.max_level
= levels
;
96 dump_trace(current
, NULL
, (long *)stack
, 0, &print_stack_ops
,
101 // Without KPROBES very little works atm.
102 // But this file is unconditionally imported, while these two functions are only
103 // used through context-unwind.stp.
104 #if defined (CONFIG_KPROBES)
106 /** Prints the stack backtrace
107 * @param regs A pointer to the struct pt_regs.
110 static void _stp_stack_print(struct pt_regs
*regs
, int verbose
, struct kretprobe_instance
*pi
, int levels
, struct task_struct
*tsk
, struct uretprobe_instance
*ri
)
113 /* print the current address */
115 if (verbose
== SYM_VERBOSE_FULL
) {
116 _stp_print("Returning from: ");
117 _stp_symbol_print((unsigned long)_stp_probe_addr_r(pi
));
118 _stp_print("\nReturning to : ");
120 _stp_symbol_print((unsigned long)_stp_ret_addr_r(pi
));
122 if (verbose
== SYM_VERBOSE_FULL
) {
123 _stp_print("Returning from: ");
124 _stp_usymbol_print(ri
->rp
->u
.vaddr
, tsk
);
125 _stp_print("\nReturning to : ");
126 _stp_usymbol_print(ri
->ret_addr
, tsk
);
128 _stp_func_print(ri
->ret_addr
, verbose
, 0, tsk
);
130 _stp_print_char(' ');
132 _stp_usymbol_print(REG_IP(regs
), tsk
);
134 _stp_symbol_print(REG_IP(regs
));
136 if (verbose
!= SYM_VERBOSE_BRIEF
)
137 _stp_print_char('\n');
139 _stp_printf("%p %p ", (int64_t)(long)_stp_ret_addr_r(pi
), (int64_t) REG_IP(regs
));
141 _stp_printf("%p ", (int64_t) REG_IP(regs
));
143 __stp_stack_print(regs
, verbose
, levels
, tsk
, ri
);
146 /** Writes stack backtrace to a string
149 * @param regs A pointer to the struct pt_regs.
152 static void _stp_stack_snprint(char *str
, int size
, struct pt_regs
*regs
, int verbose
, struct kretprobe_instance
*pi
, int levels
, struct task_struct
*tsk
, struct uretprobe_instance
*ri
)
154 /* To get a string, we use a simple trick. First flush the print buffer, */
155 /* then call _stp_stack_print, then copy the result into the output string */
156 /* and clear the print buffer. */
157 _stp_pbuf
*pb
= per_cpu_ptr(Stp_pbuf
, smp_processor_id());
159 _stp_stack_print(regs
, verbose
, pi
, levels
, tsk
, ri
);
160 strlcpy(str
, pb
->buf
, size
< (int)pb
->len
? size
: (int)pb
->len
);
164 #endif /* CONFIG_KPROBES */
166 void _stp_stack_print_tsk(struct task_struct
*tsk
, int verbose
, int levels
)
168 #if defined(STAPCONF_KERNEL_STACKTRACE)
170 unsigned long backtrace
[MAXBACKTRACE
];
171 struct stack_trace trace
;
172 int maxLevels
= min(levels
, MAXBACKTRACE
);
173 memset(&trace
, 0, sizeof(trace
));
174 trace
.entries
= &backtrace
[0];
175 trace
.max_entries
= maxLevels
;
177 save_stack_trace_tsk(tsk
, &trace
);
178 for (i
= 0; i
< maxLevels
; ++i
) {
179 if (backtrace
[i
] == 0 || backtrace
[i
] == ULONG_MAX
)
181 _stp_printf("%lx ", backtrace
[i
]);
186 /** Writes a task stack backtrace to a string
189 * @param tsk A pointer to the task_struct
192 void _stp_stack_snprint_tsk(char *str
, int size
, struct task_struct
*tsk
, int verbose
, int levels
)
194 _stp_pbuf
*pb
= per_cpu_ptr(Stp_pbuf
, smp_processor_id());
196 _stp_stack_print_tsk(tsk
, verbose
, levels
);
197 strlcpy(str
, pb
->buf
, size
< (int)pb
->len
? size
: (int)pb
->len
);
200 #endif /* _STACK_C_ */