annotate src/lib/backtrace-string.c @ 9266:cd29b745c8dd HEAD

configure: clock_gettime()'s -lrt adding dropped everything else from $LIBS.
author Timo Sirainen <tss@iki.fi>
date Mon, 27 Jul 2009 06:32:42 -0400
parents b9faf4db2a9f
children 00cd9aacd03c
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
rev   line source
8590
b9faf4db2a9f Updated copyright notices to include year 2009.
Timo Sirainen <tss@iki.fi>
parents: 7086
diff changeset
1 /* Copyright (c) 2006-2009 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
6494
59490181469e Use N_ELEMENTS() macro instead of doing sizeof()/sizeof([0]) ourself.
Timo Sirainen <tss@iki.fi>
parents: 6429
diff changeset
21 ret = backtrace(stack, N_ELEMENTS(stack));
4840
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 }