xref: /netbsd-src/external/bsd/ntp/dist/libntp/lib/isc/assertions.c (revision 4021daa96568863ea08835b47396d9e9ef84da0e)
1*4021daa9Smartin /*	$NetBSD: assertions.c,v 1.4 2024/08/19 08:28:32 martin Exp $	*/
2897be3a4Schristos 
3897be3a4Schristos /*
4897be3a4Schristos  * Copyright (C) 2004, 2005, 2007-2009  Internet Systems Consortium, Inc. ("ISC")
5897be3a4Schristos  * Copyright (C) 1997-2001  Internet Software Consortium.
6897be3a4Schristos  *
7897be3a4Schristos  * Permission to use, copy, modify, and/or distribute this software for any
8897be3a4Schristos  * purpose with or without fee is hereby granted, provided that the above
9897be3a4Schristos  * copyright notice and this permission notice appear in all copies.
10897be3a4Schristos  *
11897be3a4Schristos  * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
12897be3a4Schristos  * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
13897be3a4Schristos  * AND FITNESS.  IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
14897be3a4Schristos  * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
15897be3a4Schristos  * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
16897be3a4Schristos  * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
17897be3a4Schristos  * PERFORMANCE OF THIS SOFTWARE.
18897be3a4Schristos  */
19897be3a4Schristos 
20897be3a4Schristos /* Id: assertions.c,v 1.26 2009/09/29 15:06:07 fdupont Exp  */
21897be3a4Schristos 
22897be3a4Schristos /*! \file */
23897be3a4Schristos 
24897be3a4Schristos #include <config.h>
25897be3a4Schristos 
26897be3a4Schristos #include <stdio.h>
27897be3a4Schristos #include <stdlib.h>
28897be3a4Schristos 
29897be3a4Schristos #include <isc/assertions.h>
30897be3a4Schristos #include <isc/backtrace.h>
31897be3a4Schristos #include <isc/msgs.h>
32897be3a4Schristos #include <isc/result.h>
33897be3a4Schristos 
34897be3a4Schristos /*
35897be3a4Schristos  * The maximum number of stack frames to dump on assertion failure.
36897be3a4Schristos  */
37897be3a4Schristos #ifndef BACKTRACE_MAXFRAME
38897be3a4Schristos #define BACKTRACE_MAXFRAME 128
39897be3a4Schristos #endif
40897be3a4Schristos 
41897be3a4Schristos /*%
42897be3a4Schristos  * Forward.
43897be3a4Schristos  */
44897be3a4Schristos static void
45897be3a4Schristos default_callback(const char *, int, isc_assertiontype_t, const char *);
46897be3a4Schristos 
47897be3a4Schristos static isc_assertioncallback_t isc_assertion_failed_cb = default_callback;
48897be3a4Schristos 
49897be3a4Schristos /*%
50897be3a4Schristos  * Public.
51897be3a4Schristos  */
52897be3a4Schristos 
53897be3a4Schristos /*% assertion failed handler */
54897be3a4Schristos /* coverity[+kill] */
55897be3a4Schristos void
56897be3a4Schristos isc_assertion_failed(const char *file, int line, isc_assertiontype_t type,
57897be3a4Schristos 		     const char *cond)
58897be3a4Schristos {
59897be3a4Schristos 	isc_assertion_failed_cb(file, line, type, cond);
60897be3a4Schristos 	abort();
61897be3a4Schristos 	/* NOTREACHED */
62897be3a4Schristos }
63897be3a4Schristos 
64897be3a4Schristos /*% Set callback. */
65897be3a4Schristos void
66897be3a4Schristos isc_assertion_setcallback(isc_assertioncallback_t cb) {
67897be3a4Schristos 	if (cb == NULL)
68897be3a4Schristos 		isc_assertion_failed_cb = default_callback;
69897be3a4Schristos 	else
70897be3a4Schristos 		isc_assertion_failed_cb = cb;
71897be3a4Schristos }
72897be3a4Schristos 
73897be3a4Schristos /*% Type to Text */
74897be3a4Schristos const char *
75897be3a4Schristos isc_assertion_typetotext(isc_assertiontype_t type) {
76*4021daa9Smartin 	const char *result = "?";
77897be3a4Schristos 
78897be3a4Schristos 	/*
79897be3a4Schristos 	 * These strings have purposefully not been internationalized
80897be3a4Schristos 	 * because they are considered to essentially be keywords of
81897be3a4Schristos 	 * the ISC development environment.
82897be3a4Schristos 	 */
83897be3a4Schristos 	switch (type) {
84897be3a4Schristos 	case isc_assertiontype_require:
85897be3a4Schristos 		result = "REQUIRE";
86897be3a4Schristos 		break;
87897be3a4Schristos 	case isc_assertiontype_ensure:
88897be3a4Schristos 		result = "ENSURE";
89897be3a4Schristos 		break;
90897be3a4Schristos 	case isc_assertiontype_insist:
91897be3a4Schristos 		result = "INSIST";
92897be3a4Schristos 		break;
93897be3a4Schristos 	case isc_assertiontype_invariant:
94897be3a4Schristos 		result = "INVARIANT";
95897be3a4Schristos 		break;
96897be3a4Schristos 	}
97897be3a4Schristos 	return (result);
98897be3a4Schristos }
99897be3a4Schristos 
100897be3a4Schristos /*
101897be3a4Schristos  * Private.
102897be3a4Schristos  */
103897be3a4Schristos 
104897be3a4Schristos static void
105897be3a4Schristos default_callback(const char *file, int line, isc_assertiontype_t type,
106897be3a4Schristos 		 const char *cond)
107897be3a4Schristos {
108897be3a4Schristos 	void *tracebuf[BACKTRACE_MAXFRAME];
109897be3a4Schristos 	int i, nframes;
110897be3a4Schristos 	const char *logsuffix = ".";
111897be3a4Schristos 	const char *fname;
112897be3a4Schristos 	isc_result_t result;
113897be3a4Schristos 
114897be3a4Schristos 	result = isc_backtrace_gettrace(tracebuf, BACKTRACE_MAXFRAME, &nframes);
115897be3a4Schristos 		if (result == ISC_R_SUCCESS && nframes > 0)
116897be3a4Schristos 			logsuffix = ", back trace";
117897be3a4Schristos 
118897be3a4Schristos 	fprintf(stderr, "%s:%d: %s(%s) %s%s\n",
119897be3a4Schristos 		file, line, isc_assertion_typetotext(type), cond,
120897be3a4Schristos 		isc_msgcat_get(isc_msgcat, ISC_MSGSET_GENERAL,
121897be3a4Schristos 			       ISC_MSG_FAILED, "failed"), logsuffix);
122897be3a4Schristos 	if (result == ISC_R_SUCCESS) {
123897be3a4Schristos 		for (i = 0; i < nframes; i++) {
124897be3a4Schristos 			unsigned long offset;
125897be3a4Schristos 
126897be3a4Schristos 			fname = NULL;
127897be3a4Schristos 			result = isc_backtrace_getsymbol(tracebuf[i], &fname,
128897be3a4Schristos 							 &offset);
129897be3a4Schristos 			if (result == ISC_R_SUCCESS) {
130897be3a4Schristos 				fprintf(stderr, "#%d %p in %s()+0x%lx\n", i,
131897be3a4Schristos 					tracebuf[i], fname, offset);
132897be3a4Schristos 			} else {
133897be3a4Schristos 				fprintf(stderr, "#%d %p in ??\n", i,
134897be3a4Schristos 					tracebuf[i]);
135897be3a4Schristos 			}
136897be3a4Schristos 		}
137897be3a4Schristos 	}
138897be3a4Schristos 	fflush(stderr);
139897be3a4Schristos }
140