1120586Sbms/* $NetBSD: assertions.c,v 1.7 2020/09/07 00:48:45 mrg Exp $ */ 2120586Sbms 3120586Sbms/* 4120586Sbms * Copyright (C) 2004, 2005, 2007-2009 Internet Systems Consortium, Inc. ("ISC") 5120586Sbms * Copyright (C) 1997-2001 Internet Software Consortium. 6120586Sbms * 7120586Sbms * Permission to use, copy, modify, and/or distribute this software for any 8120586Sbms * purpose with or without fee is hereby granted, provided that the above 9120586Sbms * copyright notice and this permission notice appear in all copies. 10120586Sbms * 11120586Sbms * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH 12120586Sbms * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY 13120586Sbms * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT, 14120586Sbms * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM 15120586Sbms * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE 16120586Sbms * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR 17120586Sbms * PERFORMANCE OF THIS SOFTWARE. 18120586Sbms */ 19120586Sbms 20120586Sbms/* Id: assertions.c,v 1.26 2009/09/29 15:06:07 fdupont Exp */ 21120586Sbms 22120586Sbms/*! \file */ 23120586Sbms 24120586Sbms#include <config.h> 25120586Sbms 26120586Sbms#include <stdio.h> 27120586Sbms#include <stdlib.h> 28120586Sbms 29131680Sru#include <isc/assertions.h> 30131681Sru#include <isc/backtrace.h> 31120586Sbms#include <isc/msgs.h> 32120586Sbms#include <isc/result.h> 33120586Sbms 34120586Sbms/* 35120586Sbms * The maximum number of stack frames to dump on assertion failure. 36120586Sbms */ 37120586Sbms#ifndef BACKTRACE_MAXFRAME 38120586Sbms#define BACKTRACE_MAXFRAME 128 39120586Sbms#endif 40120586Sbms 41120586Sbms/*% 42120586Sbms * Forward. 43120586Sbms */ 44120586Sbmsstatic void 45120586Sbmsdefault_callback(const char *, int, isc_assertiontype_t, const char *); 46120586Sbms 47120586Sbmsstatic isc_assertioncallback_t isc_assertion_failed_cb = default_callback; 48120586Sbms 49120586Sbms/*% 50120586Sbms * Public. 51120586Sbms */ 52120586Sbms 53120586Sbms/*% assertion failed handler */ 54120586Sbms/* coverity[+kill] */ 55120586Sbmsvoid 56120586Sbmsisc_assertion_failed(const char *file, int line, isc_assertiontype_t type, 57120586Sbms const char *cond) 58147647Shmp{ 59120586Sbms isc_assertion_failed_cb(file, line, type, cond); 60 abort(); 61 /* NOTREACHED */ 62} 63 64/*% Set callback. */ 65void 66isc_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 */ 74const char * 75isc_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 default: 97 result = "*invalid*"; 98 } 99 return (result); 100} 101 102/* 103 * Private. 104 */ 105 106static void 107default_callback(const char *file, int line, isc_assertiontype_t type, 108 const char *cond) 109{ 110 void *tracebuf[BACKTRACE_MAXFRAME]; 111 int i, nframes; 112 const char *logsuffix = "."; 113 const char *fname; 114 isc_result_t result; 115 116 result = isc_backtrace_gettrace(tracebuf, BACKTRACE_MAXFRAME, &nframes); 117 if (result == ISC_R_SUCCESS && nframes > 0) 118 logsuffix = ", back trace"; 119 120 fprintf(stderr, "%s:%d: %s(%s) %s%s\n", 121 file, line, isc_assertion_typetotext(type), cond, 122 isc_msgcat_get(isc_msgcat, ISC_MSGSET_GENERAL, 123 ISC_MSG_FAILED, "failed"), logsuffix); 124 if (result == ISC_R_SUCCESS) { 125 for (i = 0; i < nframes; i++) { 126 unsigned long offset; 127 128 fname = NULL; 129 result = isc_backtrace_getsymbol(tracebuf[i], &fname, 130 &offset); 131 if (result == ISC_R_SUCCESS) { 132 fprintf(stderr, "#%d %p in %s()+0x%lx\n", i, 133 tracebuf[i], fname, offset); 134 } else { 135 fprintf(stderr, "#%d %p in ??\n", i, 136 tracebuf[i]); 137 } 138 } 139 } 140 fflush(stderr); 141} 142