]>
Commit | Line | Data |
---|---|---|
fabf5ed4 MH |
1 | /* -*- linux-c -*- |
2 | * Stack tracing functions | |
aaf2af3e | 3 | * Copyright (C) 2005-2008 Red Hat Inc. |
1c9db4fd AK |
4 | * Copyright (C) 2005 Intel Corporation. |
5 | * | |
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 | |
9 | * later version. | |
10 | */ | |
11 | ||
fabf5ed4 | 12 | #ifndef _STACK_C_ |
e32551b1 | 13 | #define _STACK_C_ |
3d4bc8be | 14 | |
e32551b1 MH |
15 | /** @file stack.c |
16 | * @brief Stack Tracing Functions | |
17 | */ | |
18 | ||
19 | /** @addtogroup stack Stack Tracing Functions | |
abedf3db | 20 | * |
e32551b1 MH |
21 | * @{ |
22 | */ | |
23 | ||
24 | #include "sym.c" | |
abedf3db | 25 | #include "regs.h" |
aaf2af3e | 26 | #include "unwind.c" |
a0ccc04f | 27 | |
7d678473 MH |
28 | #define MAXBACKTRACE 20 |
29 | ||
abedf3db | 30 | #if defined (__x86_64__) |
fabf5ed4 | 31 | #include "stack-x86_64.c" |
1c9db4fd | 32 | #elif defined (__ia64__) |
fabf5ed4 | 33 | #include "stack-ia64.c" |
abedf3db | 34 | #elif defined (__i386__) |
fabf5ed4 MH |
35 | #include "stack-i386.c" |
36 | #elif defined (__powerpc64__) | |
37 | #include "stack-ppc64.c" | |
79e80fed MH |
38 | #elif defined (__arm__) |
39 | #include "stack-arm.c" | |
24cb8c3b DW |
40 | #elif defined (__s390__) || defined (__s390x__) |
41 | #include "stack-s390.c" | |
e32551b1 | 42 | #else |
fabf5ed4 | 43 | #error "Unsupported architecture" |
e32551b1 | 44 | #endif |
e32551b1 | 45 | |
1b276fc2 | 46 | /** Prints the stack backtrace |
abedf3db | 47 | * @param regs A pointer to the struct pt_regs. |
3d4bc8be | 48 | */ |
1b276fc2 MH |
49 | |
50 | void _stp_stack_print(struct pt_regs *regs, int verbose, struct kretprobe_instance *pi) | |
e32551b1 | 51 | { |
9acc3200 | 52 | if (verbose) { |
fabf5ed4 MH |
53 | /* print the current address */ |
54 | if (pi) { | |
1b276fc2 MH |
55 | _stp_print("Returning from: "); |
56 | _stp_symbol_print((unsigned long)_stp_probe_addr_r(pi)); | |
57 | _stp_print("\nReturning to : "); | |
58 | _stp_symbol_print((unsigned long)_stp_ret_addr_r(pi)); | |
59 | } else { | |
60 | _stp_print_char(' '); | |
61 | _stp_symbol_print (REG_IP(regs)); | |
62 | } | |
63 | _stp_print_char('\n'); | |
9acc3200 | 64 | } else |
4f295b51 | 65 | _stp_printf ("%p ", (int64_t)REG_IP(regs)); |
1b276fc2 | 66 | __stp_stack_print (regs, verbose, 0); |
e32551b1 MH |
67 | } |
68 | ||
1b276fc2 MH |
69 | /** Writes stack backtrace to a string |
70 | * | |
71 | * @param str string | |
abedf3db | 72 | * @param regs A pointer to the struct pt_regs. |
1b276fc2 | 73 | * @returns void |
abedf3db | 74 | */ |
1b276fc2 | 75 | void _stp_stack_snprint (char *str, int size, struct pt_regs *regs, int verbose, struct kretprobe_instance *pi) |
abedf3db | 76 | { |
1b276fc2 MH |
77 | /* To get a string, we use a simple trick. First flush the print buffer, */ |
78 | /* then call _stp_stack_print, then copy the result into the output string */ | |
79 | /* and clear the print buffer. */ | |
80 | _stp_pbuf *pb = per_cpu_ptr(Stp_pbuf, smp_processor_id()); | |
81 | _stp_print_flush(); | |
82 | _stp_stack_print(regs, verbose, pi); | |
c3e51a48 | 83 | strlcpy(str, pb->buf, size < (int)pb->len ? size : (int)pb->len); |
1b276fc2 | 84 | pb->len = 0; |
abedf3db MH |
85 | } |
86 | ||
655ee282 | 87 | |
1b276fc2 MH |
88 | /** Prints the user stack backtrace |
89 | * @param str string | |
90 | * @returns Same string as was input with trace info appended, | |
abedf3db MH |
91 | * @note Currently limited to a depth of two. Works from jprobes and kprobes. |
92 | */ | |
1b276fc2 MH |
93 | #if 0 |
94 | void _stp_ustack_print (char *str) | |
e32551b1 | 95 | { |
abedf3db | 96 | struct pt_regs *nregs = ((struct pt_regs *) (THREAD_SIZE + (unsigned long) current->thread_info)) - 1; |
4f295b51 | 97 | _stp_printf ("%p : [user]\n", (int64_t)REG_IP(nregs)); |
abedf3db | 98 | if (REG_SP(nregs)) |
4f295b51 | 99 | _stp_printf ("%p : [user]\n", (int64_t)(*(unsigned long *)REG_SP(nregs))); |
e32551b1 | 100 | } |
1b276fc2 | 101 | #endif /* 0 */ |
abedf3db | 102 | |
e32551b1 MH |
103 | /** @} */ |
104 | #endif /* _STACK_C_ */ |