]>
Commit | Line | Data |
---|---|---|
064af421 | 1 | /* |
482557e5 | 2 | * Copyright (c) 2008, 2009, 2010, 2011, 2013 Nicira, Inc. |
064af421 | 3 | * |
a14bc59f BP |
4 | * Licensed under the Apache License, Version 2.0 (the "License"); |
5 | * you may not use this file except in compliance with the License. | |
6 | * You may obtain a copy of the License at: | |
064af421 | 7 | * |
a14bc59f BP |
8 | * http://www.apache.org/licenses/LICENSE-2.0 |
9 | * | |
10 | * Unless required by applicable law or agreed to in writing, software | |
11 | * distributed under the License is distributed on an "AS IS" BASIS, | |
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | |
13 | * See the License for the specific language governing permissions and | |
14 | * limitations under the License. | |
064af421 BP |
15 | */ |
16 | ||
17 | #include <config.h> | |
d0b99d38 | 18 | #include <inttypes.h> |
0e6644c3 | 19 | |
064af421 | 20 | #include "backtrace.h" |
d0b99d38 AZ |
21 | #include "vlog.h" |
22 | ||
23 | VLOG_DEFINE_THIS_MODULE(backtrace); | |
0e6644c3 | 24 | |
0e6644c3 BP |
25 | #ifdef HAVE_BACKTRACE |
26 | #include <execinfo.h> | |
27 | void | |
28 | backtrace_capture(struct backtrace *b) | |
29 | { | |
30 | void *frames[BACKTRACE_MAX_FRAMES]; | |
31 | int i; | |
32 | ||
33 | b->n_frames = backtrace(frames, BACKTRACE_MAX_FRAMES); | |
34 | for (i = 0; i < b->n_frames; i++) { | |
35 | b->frames[i] = (uintptr_t) frames[i]; | |
36 | } | |
37 | } | |
d0b99d38 | 38 | |
482557e5 | 39 | #else |
0e6644c3 BP |
40 | void |
41 | backtrace_capture(struct backtrace *backtrace) | |
42 | { | |
e4fd8d28 | 43 | backtrace->n_frames = 0; |
064af421 | 44 | } |
0e6644c3 | 45 | #endif |
d0b99d38 AZ |
46 | |
47 | static char * | |
48 | backtrace_format(const struct backtrace *b, struct ds *ds) | |
49 | { | |
50 | if (b->n_frames) { | |
51 | int i; | |
52 | ||
53 | ds_put_cstr(ds, " (backtrace:"); | |
54 | for (i = 0; i < b->n_frames; i++) { | |
55 | ds_put_format(ds, " 0x%08"PRIxPTR, b->frames[i]); | |
56 | } | |
57 | ds_put_cstr(ds, ")"); | |
58 | } | |
59 | ||
60 | return ds_cstr(ds); | |
61 | } | |
62 | ||
63 | void | |
64 | log_backtrace_at(const char *msg, const char *where) | |
65 | { | |
66 | struct backtrace b; | |
67 | struct ds ds = DS_EMPTY_INITIALIZER; | |
68 | ||
69 | backtrace_capture(&b); | |
70 | if (msg) { | |
71 | ds_put_format(&ds, "%s ", msg); | |
72 | } | |
73 | ||
74 | ds_put_cstr(&ds, where); | |
75 | VLOG_ERR("%s", backtrace_format(&b, &ds)); | |
76 | ||
77 | ds_destroy(&ds); | |
78 | } |