1/* 2 * Copyright (C) 2004, 2005, 2007-2009 Internet Systems Consortium, Inc. ("ISC") 3 * Copyright (C) 1997-2001 Internet Software Consortium. 4 * 5 * Permission to use, copy, modify, and/or distribute this software for any 6 * purpose with or without fee is hereby granted, provided that the above 7 * copyright notice and this permission notice appear in all copies. 8 * 9 * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH 10 * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY 11 * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT, 12 * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM 13 * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE 14 * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR 15 * PERFORMANCE OF THIS SOFTWARE. 16 */ 17 18/* $Id: assertions.c,v 1.26 2009/09/29 15:06:07 fdupont Exp $ */ 19 20/*! \file */ 21 22#include <config.h> 23 24#include <stdio.h> 25#include <stdlib.h> 26 27#include <isc/assertions.h> 28#include <isc/backtrace.h> 29#include <isc/msgs.h> 30#include <isc/result.h> 31 32/* 33 * The maximum number of stack frames to dump on assertion failure. 34 */ 35#ifndef BACKTRACE_MAXFRAME 36#define BACKTRACE_MAXFRAME 128 37#endif 38 39/*% 40 * Forward. 41 */ 42static void 43default_callback(const char *, int, isc_assertiontype_t, const char *); 44 45static isc_assertioncallback_t isc_assertion_failed_cb = default_callback; 46 47/*% 48 * Public. 49 */ 50 51/*% assertion failed handler */ 52/* coverity[+kill] */ 53void 54isc_assertion_failed(const char *file, int line, isc_assertiontype_t type, 55 const char *cond) 56{ 57 isc_assertion_failed_cb(file, line, type, cond); 58 abort(); 59 /* NOTREACHED */ 60} 61 62/*% Set callback. */ 63void 64isc_assertion_setcallback(isc_assertioncallback_t cb) { 65 if (cb == NULL) 66 isc_assertion_failed_cb = default_callback; 67 else 68 isc_assertion_failed_cb = cb; 69} 70 71/*% Type to Text */ 72const char * 73isc_assertion_typetotext(isc_assertiontype_t type) { 74 const char *result; 75 76 /* 77 * These strings have purposefully not been internationalized 78 * because they are considered to essentially be keywords of 79 * the ISC development environment. 80 */ 81 switch (type) { 82 case isc_assertiontype_require: 83 result = "REQUIRE"; 84 break; 85 case isc_assertiontype_ensure: 86 result = "ENSURE"; 87 break; 88 case isc_assertiontype_insist: 89 result = "INSIST"; 90 break; 91 case isc_assertiontype_invariant: 92 result = "INVARIANT"; 93 break; 94 default: 95 result = NULL; 96 } 97 return (result); 98} 99 100/* 101 * Private. 102 */ 103 104static void 105default_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