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