Mercurial > dovecot > original-hg > dovecot-1.2
annotate src/lib/backtrace-string.c @ 6429:65c69a53a7be HEAD
Replaced my Copyright notices. The year range always ends with 2007 now.
My name was replaced with "Dovecot authors". In many cases I didn't really
even own the copyright, so this is more correct.
author | Timo Sirainen <tss@iki.fi> |
---|---|
date | Sun, 16 Sep 2007 14:34:22 +0300 |
parents | 6a64e64fa3a3 |
children | 59490181469e |
rev | line source |
---|---|
6429
65c69a53a7be
Replaced my Copyright notices. The year range always ends with 2007 now.
Timo Sirainen <tss@iki.fi>
parents:
6411
diff
changeset
|
1 /* Copyright (c) 2006-2007 Dovecot authors, see the included COPYING file */ |
4840
a0a38a306c17
Since getting core dumps can be sometimes difficult, if we now do abort()
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
2 |
a0a38a306c17
Since getting core dumps can be sometimes difficult, if we now do abort()
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
3 #include "lib.h" |
a0a38a306c17
Since getting core dumps can be sometimes difficult, if we now do abort()
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
4 #include "str.h" |
a0a38a306c17
Since getting core dumps can be sometimes difficult, if we now do abort()
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
5 #include "backtrace-string.h" |
a0a38a306c17
Since getting core dumps can be sometimes difficult, if we now do abort()
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
6 |
a0a38a306c17
Since getting core dumps can be sometimes difficult, if we now do abort()
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
7 #define MAX_STACK_SIZE 30 |
a0a38a306c17
Since getting core dumps can be sometimes difficult, if we now do abort()
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
8 #define STACK_SKIP_COUNT 2 |
a0a38a306c17
Since getting core dumps can be sometimes difficult, if we now do abort()
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
9 |
a0a38a306c17
Since getting core dumps can be sometimes difficult, if we now do abort()
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
10 #if defined(HAVE_BACKTRACE_SYMBOLS) && defined(HAVE_EXECINFO_H) |
a0a38a306c17
Since getting core dumps can be sometimes difficult, if we now do abort()
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
11 /* Linux */ |
a0a38a306c17
Since getting core dumps can be sometimes difficult, if we now do abort()
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
12 #include <execinfo.h> |
a0a38a306c17
Since getting core dumps can be sometimes difficult, if we now do abort()
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
13 #include <stdlib.h> |
a0a38a306c17
Since getting core dumps can be sometimes difficult, if we now do abort()
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
14 |
a0a38a306c17
Since getting core dumps can be sometimes difficult, if we now do abort()
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
15 int backtrace_append(string_t *str) |
a0a38a306c17
Since getting core dumps can be sometimes difficult, if we now do abort()
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
16 { |
a0a38a306c17
Since getting core dumps can be sometimes difficult, if we now do abort()
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
17 void *stack[MAX_STACK_SIZE]; |
a0a38a306c17
Since getting core dumps can be sometimes difficult, if we now do abort()
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
18 char **strings; |
a0a38a306c17
Since getting core dumps can be sometimes difficult, if we now do abort()
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
19 int ret, i; |
a0a38a306c17
Since getting core dumps can be sometimes difficult, if we now do abort()
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
20 |
a0a38a306c17
Since getting core dumps can be sometimes difficult, if we now do abort()
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
21 ret = backtrace(stack, sizeof(stack)/sizeof(stack[0])); |
a0a38a306c17
Since getting core dumps can be sometimes difficult, if we now do abort()
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
22 if (ret <= STACK_SKIP_COUNT) |
a0a38a306c17
Since getting core dumps can be sometimes difficult, if we now do abort()
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
23 return -1; |
a0a38a306c17
Since getting core dumps can be sometimes difficult, if we now do abort()
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
24 |
a0a38a306c17
Since getting core dumps can be sometimes difficult, if we now do abort()
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
25 strings = backtrace_symbols(stack, ret); |
a0a38a306c17
Since getting core dumps can be sometimes difficult, if we now do abort()
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
26 for (i = STACK_SKIP_COUNT; i < ret; i++) { |
a0a38a306c17
Since getting core dumps can be sometimes difficult, if we now do abort()
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
27 if (i > STACK_SKIP_COUNT) |
a0a38a306c17
Since getting core dumps can be sometimes difficult, if we now do abort()
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
28 str_append(str, " -> "); |
4841
c04ecbc7bdc8
Handle backtrace_symbols() returning NULL without errors (out of memory).
Timo Sirainen <tss@iki.fi>
parents:
4840
diff
changeset
|
29 |
c04ecbc7bdc8
Handle backtrace_symbols() returning NULL without errors (out of memory).
Timo Sirainen <tss@iki.fi>
parents:
4840
diff
changeset
|
30 if (strings != NULL) |
c04ecbc7bdc8
Handle backtrace_symbols() returning NULL without errors (out of memory).
Timo Sirainen <tss@iki.fi>
parents:
4840
diff
changeset
|
31 str_append(str, strings[i]); |
c04ecbc7bdc8
Handle backtrace_symbols() returning NULL without errors (out of memory).
Timo Sirainen <tss@iki.fi>
parents:
4840
diff
changeset
|
32 else { |
c04ecbc7bdc8
Handle backtrace_symbols() returning NULL without errors (out of memory).
Timo Sirainen <tss@iki.fi>
parents:
4840
diff
changeset
|
33 /* out of memory case */ |
c04ecbc7bdc8
Handle backtrace_symbols() returning NULL without errors (out of memory).
Timo Sirainen <tss@iki.fi>
parents:
4840
diff
changeset
|
34 str_printfa(str, "0x%p", stack[i]); |
c04ecbc7bdc8
Handle backtrace_symbols() returning NULL without errors (out of memory).
Timo Sirainen <tss@iki.fi>
parents:
4840
diff
changeset
|
35 } |
4840
a0a38a306c17
Since getting core dumps can be sometimes difficult, if we now do abort()
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
36 } |
a0a38a306c17
Since getting core dumps can be sometimes difficult, if we now do abort()
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
37 free(strings); |
a0a38a306c17
Since getting core dumps can be sometimes difficult, if we now do abort()
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
38 return 0; |
a0a38a306c17
Since getting core dumps can be sometimes difficult, if we now do abort()
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
39 } |
a0a38a306c17
Since getting core dumps can be sometimes difficult, if we now do abort()
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
40 #elif defined(HAVE_WALKCONTEXT) && defined(HAVE_UCONTEXT_H) |
a0a38a306c17
Since getting core dumps can be sometimes difficult, if we now do abort()
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
41 /* Solaris */ |
a0a38a306c17
Since getting core dumps can be sometimes difficult, if we now do abort()
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
42 #include <ucontext.h> |
a0a38a306c17
Since getting core dumps can be sometimes difficult, if we now do abort()
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
43 |
a0a38a306c17
Since getting core dumps can be sometimes difficult, if we now do abort()
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
44 struct walk_context { |
a0a38a306c17
Since getting core dumps can be sometimes difficult, if we now do abort()
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
45 string_t *str; |
a0a38a306c17
Since getting core dumps can be sometimes difficult, if we now do abort()
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
46 unsigned int pos; |
a0a38a306c17
Since getting core dumps can be sometimes difficult, if we now do abort()
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
47 }; |
a0a38a306c17
Since getting core dumps can be sometimes difficult, if we now do abort()
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
48 |
6411
6a64e64fa3a3
Renamed __attr_*__ to ATTR_*. Renamed __attrs_used__ to ATTRS_DEFINED.
Timo Sirainen <tss@iki.fi>
parents:
4841
diff
changeset
|
49 static int walk_callback(uintptr_t ptr, int signo ATTR_UNUSED, |
4840
a0a38a306c17
Since getting core dumps can be sometimes difficult, if we now do abort()
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
50 void *context) |
a0a38a306c17
Since getting core dumps can be sometimes difficult, if we now do abort()
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
51 { |
a0a38a306c17
Since getting core dumps can be sometimes difficult, if we now do abort()
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
52 struct walk_context *ctx = context; |
a0a38a306c17
Since getting core dumps can be sometimes difficult, if we now do abort()
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
53 |
a0a38a306c17
Since getting core dumps can be sometimes difficult, if we now do abort()
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
54 if (ctx->pos >= STACK_SKIP_COUNT) { |
a0a38a306c17
Since getting core dumps can be sometimes difficult, if we now do abort()
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
55 if (ctx->pos > STACK_SKIP_COUNT) |
a0a38a306c17
Since getting core dumps can be sometimes difficult, if we now do abort()
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
56 str_append(ctx->str, " -> "); |
a0a38a306c17
Since getting core dumps can be sometimes difficult, if we now do abort()
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
57 str_printfa(ctx->str, "0x%p", (void *)ptr); |
a0a38a306c17
Since getting core dumps can be sometimes difficult, if we now do abort()
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
58 } |
a0a38a306c17
Since getting core dumps can be sometimes difficult, if we now do abort()
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
59 ctx->pos++; |
a0a38a306c17
Since getting core dumps can be sometimes difficult, if we now do abort()
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
60 return 0; |
a0a38a306c17
Since getting core dumps can be sometimes difficult, if we now do abort()
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
61 } |
a0a38a306c17
Since getting core dumps can be sometimes difficult, if we now do abort()
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
62 |
a0a38a306c17
Since getting core dumps can be sometimes difficult, if we now do abort()
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
63 int backtrace_append(string_t *str) |
a0a38a306c17
Since getting core dumps can be sometimes difficult, if we now do abort()
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
64 { |
a0a38a306c17
Since getting core dumps can be sometimes difficult, if we now do abort()
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
65 ucontext_t uc; |
a0a38a306c17
Since getting core dumps can be sometimes difficult, if we now do abort()
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
66 struct walk_context ctx; |
a0a38a306c17
Since getting core dumps can be sometimes difficult, if we now do abort()
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
67 |
a0a38a306c17
Since getting core dumps can be sometimes difficult, if we now do abort()
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
68 if (getcontext(&uc) < 0) |
a0a38a306c17
Since getting core dumps can be sometimes difficult, if we now do abort()
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
69 return -1; |
a0a38a306c17
Since getting core dumps can be sometimes difficult, if we now do abort()
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
70 |
a0a38a306c17
Since getting core dumps can be sometimes difficult, if we now do abort()
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
71 ctx.str = str; |
a0a38a306c17
Since getting core dumps can be sometimes difficult, if we now do abort()
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
72 ctx.pos = 0; |
a0a38a306c17
Since getting core dumps can be sometimes difficult, if we now do abort()
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
73 walkcontext(&uc, walk_callback, &ctx); |
a0a38a306c17
Since getting core dumps can be sometimes difficult, if we now do abort()
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
74 return 0; |
a0a38a306c17
Since getting core dumps can be sometimes difficult, if we now do abort()
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
75 } |
a0a38a306c17
Since getting core dumps can be sometimes difficult, if we now do abort()
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
76 #else |
6411
6a64e64fa3a3
Renamed __attr_*__ to ATTR_*. Renamed __attrs_used__ to ATTRS_DEFINED.
Timo Sirainen <tss@iki.fi>
parents:
4841
diff
changeset
|
77 int backtrace_append(string_t *str ATTR_UNUSED) |
4840
a0a38a306c17
Since getting core dumps can be sometimes difficult, if we now do abort()
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
78 { |
a0a38a306c17
Since getting core dumps can be sometimes difficult, if we now do abort()
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
79 return -1; |
a0a38a306c17
Since getting core dumps can be sometimes difficult, if we now do abort()
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
80 } |
a0a38a306c17
Since getting core dumps can be sometimes difficult, if we now do abort()
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
81 #endif |
a0a38a306c17
Since getting core dumps can be sometimes difficult, if we now do abort()
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
82 |
a0a38a306c17
Since getting core dumps can be sometimes difficult, if we now do abort()
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
83 int backtrace_get(const char **backtrace_r) |
a0a38a306c17
Since getting core dumps can be sometimes difficult, if we now do abort()
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
84 { |
a0a38a306c17
Since getting core dumps can be sometimes difficult, if we now do abort()
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
85 string_t *str; |
a0a38a306c17
Since getting core dumps can be sometimes difficult, if we now do abort()
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
86 |
a0a38a306c17
Since getting core dumps can be sometimes difficult, if we now do abort()
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
87 str = t_str_new(512); |
a0a38a306c17
Since getting core dumps can be sometimes difficult, if we now do abort()
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
88 if (backtrace_append(str) < 0) |
a0a38a306c17
Since getting core dumps can be sometimes difficult, if we now do abort()
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
89 return -1; |
a0a38a306c17
Since getting core dumps can be sometimes difficult, if we now do abort()
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
90 |
a0a38a306c17
Since getting core dumps can be sometimes difficult, if we now do abort()
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
91 *backtrace_r = str_c(str); |
a0a38a306c17
Since getting core dumps can be sometimes difficult, if we now do abort()
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
92 return 0; |
a0a38a306c17
Since getting core dumps can be sometimes difficult, if we now do abort()
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
93 } |