]> CyberLeo.Net >> Repos - FreeBSD/stable/9.git/blob - contrib/bind9/lib/isc/assertions.c
Update BIND to 9.9.8
[FreeBSD/stable/9.git] / contrib / bind9 / lib / isc / assertions.c
1 /*
2  * Copyright (C) 2004, 2005, 2007-2009, 2015  Internet Systems Consortium, Inc. ("ISC")
3  * Copyright (C) 1997-2001  Internet Software Consortium.
4  *
5  * Permission to use, copy, modify, and/or distribute this software for any
6  * purpose with or without fee is hereby granted, provided that the above
7  * copyright notice and this permission notice appear in all copies.
8  *
9  * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
10  * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
11  * AND FITNESS.  IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
12  * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
13  * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
14  * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
15  * PERFORMANCE OF THIS SOFTWARE.
16  */
17
18 /* $Id: assertions.c,v 1.26 2009/09/29 15:06:07 fdupont Exp $ */
19
20 /*! \file */
21
22 #include <config.h>
23
24 #include <stdio.h>
25 #include <stdlib.h>
26
27 #include <isc/assertions.h>
28 #include <isc/backtrace.h>
29 #include <isc/msgs.h>
30 #include <isc/print.h>
31 #include <isc/result.h>
32
33 /*
34  * The maximum number of stack frames to dump on assertion failure.
35  */
36 #ifndef BACKTRACE_MAXFRAME
37 #define BACKTRACE_MAXFRAME 128
38 #endif
39
40 /*%
41  * Forward.
42  */
43 static void
44 default_callback(const char *, int, isc_assertiontype_t, const char *);
45
46 static isc_assertioncallback_t isc_assertion_failed_cb = default_callback;
47
48 /*%
49  * Public.
50  */
51
52 /*% assertion failed handler */
53 /* coverity[+kill] */
54 void
55 isc_assertion_failed(const char *file, int line, isc_assertiontype_t type,
56                      const char *cond)
57 {
58         isc_assertion_failed_cb(file, line, type, cond);
59         abort();
60         /* NOTREACHED */
61 }
62
63 /*% Set callback. */
64 void
65 isc_assertion_setcallback(isc_assertioncallback_t cb) {
66         if (cb == NULL)
67                 isc_assertion_failed_cb = default_callback;
68         else
69                 isc_assertion_failed_cb = cb;
70 }
71
72 /*% Type to Text */
73 const char *
74 isc_assertion_typetotext(isc_assertiontype_t type) {
75         const char *result;
76
77         /*
78          * These strings have purposefully not been internationalized
79          * because they are considered to essentially be keywords of
80          * the ISC development environment.
81          */
82         switch (type) {
83         case isc_assertiontype_require:
84                 result = "REQUIRE";
85                 break;
86         case isc_assertiontype_ensure:
87                 result = "ENSURE";
88                 break;
89         case isc_assertiontype_insist:
90                 result = "INSIST";
91                 break;
92         case isc_assertiontype_invariant:
93                 result = "INVARIANT";
94                 break;
95         default:
96                 result = NULL;
97         }
98         return (result);
99 }
100
101 /*
102  * Private.
103  */
104
105 static void
106 default_callback(const char *file, int line, isc_assertiontype_t type,
107                  const char *cond)
108 {
109         void *tracebuf[BACKTRACE_MAXFRAME];
110         int i, nframes;
111         const char *logsuffix = ".";
112         const char *fname;
113         isc_result_t result;
114
115         result = isc_backtrace_gettrace(tracebuf, BACKTRACE_MAXFRAME, &nframes);
116                 if (result == ISC_R_SUCCESS && nframes > 0)
117                         logsuffix = ", back trace";
118
119         fprintf(stderr, "%s:%d: %s(%s) %s%s\n",
120                 file, line, isc_assertion_typetotext(type), cond,
121                 isc_msgcat_get(isc_msgcat, ISC_MSGSET_GENERAL,
122                                ISC_MSG_FAILED, "failed"), logsuffix);
123         if (result == ISC_R_SUCCESS) {
124                 for (i = 0; i < nframes; i++) {
125                         unsigned long offset;
126
127                         fname = NULL;
128                         result = isc_backtrace_getsymbol(tracebuf[i], &fname,
129                                                          &offset);
130                         if (result == ISC_R_SUCCESS) {
131                                 fprintf(stderr, "#%d %p in %s()+0x%lx\n", i,
132                                         tracebuf[i], fname, offset);
133                         } else {
134                                 fprintf(stderr, "#%d %p in ??\n", i,
135                                         tracebuf[i]);
136                         }
137                 }
138         }
139         fflush(stderr);
140 }