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