1 /* $NetBSD: assertions.c,v 1.9 2025/01/26 16:25:36 christos Exp $ */ 2 3 /* 4 * Copyright (C) Internet Systems Consortium, Inc. ("ISC") 5 * 6 * SPDX-License-Identifier: MPL-2.0 7 * 8 * This Source Code Form is subject to the terms of the Mozilla Public 9 * License, v. 2.0. If a copy of the MPL was not distributed with this 10 * file, you can obtain one at https://mozilla.org/MPL/2.0/. 11 * 12 * See the COPYRIGHT file distributed with this work for additional 13 * information regarding copyright ownership. 14 */ 15 16 /*! \file */ 17 18 #include <stdio.h> 19 #include <stdlib.h> 20 21 #include <isc/assertions.h> 22 #include <isc/backtrace.h> 23 #include <isc/result.h> 24 #include <isc/strerr.h> 25 26 /* 27 * The maximum number of stack frames to dump on assertion failure. 28 */ 29 #ifndef BACKTRACE_MAXFRAME 30 #define BACKTRACE_MAXFRAME 128 31 #endif /* ifndef BACKTRACE_MAXFRAME */ 32 33 /*% 34 * Forward. 35 */ 36 static void 37 default_callback(const char *, int, isc_assertiontype_t, const char *); 38 39 static isc_assertioncallback_t isc_assertion_failed_cb = default_callback; 40 41 /*% 42 * Public. 43 */ 44 45 /*% assertion failed handler */ 46 /* coverity[+kill] */ 47 void 48 isc_assertion_failed(const char *file, int line, isc_assertiontype_t type, 49 const char *cond) { 50 isc_assertion_failed_cb(file, line, type, cond); 51 abort(); 52 } 53 54 /*% Set callback. */ 55 void 56 isc_assertion_setcallback(isc_assertioncallback_t cb) { 57 if (cb == NULL) { 58 isc_assertion_failed_cb = default_callback; 59 } else { 60 isc_assertion_failed_cb = cb; 61 } 62 } 63 64 /*% Type to Text */ 65 const char * 66 isc_assertion_typetotext(isc_assertiontype_t type) { 67 const char *result; 68 69 /* 70 * These strings have purposefully not been internationalized 71 * because they are considered to essentially be keywords of 72 * the ISC development environment. 73 */ 74 switch (type) { 75 case isc_assertiontype_require: 76 result = "REQUIRE"; 77 break; 78 case isc_assertiontype_ensure: 79 result = "ENSURE"; 80 break; 81 case isc_assertiontype_insist: 82 result = "INSIST"; 83 break; 84 case isc_assertiontype_invariant: 85 result = "INVARIANT"; 86 break; 87 default: 88 result = "UNKNOWN"; 89 } 90 return result; 91 } 92 93 /* 94 * Private. 95 */ 96 97 static void 98 default_callback(const char *file, int line, isc_assertiontype_t type, 99 const char *cond) { 100 void *tracebuf[ISC_BACKTRACE_MAXFRAME]; 101 int nframes = isc_backtrace(tracebuf, ISC_BACKTRACE_MAXFRAME); 102 103 fprintf(stderr, "%s:%d: %s(%s) failed%s\n", file, line, 104 isc_assertion_typetotext(type), cond, 105 (nframes > 0) ? ", back trace" : "."); 106 107 if (nframes > 0) { 108 isc_backtrace_symbols_fd(tracebuf, nframes, fileno(stderr)); 109 } 110 111 fflush(stderr); 112 } 113