00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022 #include <config.h>
00023
00024 #include <stdio.h>
00025 #include <stdlib.h>
00026
00027 #include <isc/assertions.h>
00028 #include <isc/backtrace.h>
00029 #include <isc/msgs.h>
00030 #include <isc/result.h>
00031
00032
00033
00034
00035 #ifndef BACKTRACE_MAXFRAME
00036 #define BACKTRACE_MAXFRAME 128
00037 #endif
00038
00039
00040
00041
00042 static void
00043 default_callback(const char *, int, isc_assertiontype_t, const char *);
00044
00045 static isc_assertioncallback_t isc_assertion_failed_cb = default_callback;
00046
00047
00048
00049
00050
00051
00052
00053 void
00054 isc_assertion_failed(const char *file, int line, isc_assertiontype_t type,
00055 const char *cond)
00056 {
00057 isc_assertion_failed_cb(file, line, type, cond);
00058 abort();
00059
00060 }
00061
00062
00063 void
00064 isc_assertion_setcallback(isc_assertioncallback_t cb) {
00065 if (cb == NULL)
00066 isc_assertion_failed_cb = default_callback;
00067 else
00068 isc_assertion_failed_cb = cb;
00069 }
00070
00071
00072 const char *
00073 isc_assertion_typetotext(isc_assertiontype_t type) {
00074 const char *result;
00075
00076
00077
00078
00079
00080
00081 switch (type) {
00082 case isc_assertiontype_require:
00083 result = "REQUIRE";
00084 break;
00085 case isc_assertiontype_ensure:
00086 result = "ENSURE";
00087 break;
00088 case isc_assertiontype_insist:
00089 result = "INSIST";
00090 break;
00091 case isc_assertiontype_invariant:
00092 result = "INVARIANT";
00093 break;
00094 default:
00095 result = NULL;
00096 }
00097 return (result);
00098 }
00099
00100
00101
00102
00103
00104 static void
00105 default_callback(const char *file, int line, isc_assertiontype_t type,
00106 const char *cond)
00107 {
00108 void *tracebuf[BACKTRACE_MAXFRAME];
00109 int i, nframes;
00110 const char *logsuffix = ".";
00111 const char *fname;
00112 isc_result_t result;
00113
00114 result = isc_backtrace_gettrace(tracebuf, BACKTRACE_MAXFRAME, &nframes);
00115 if (result == ISC_R_SUCCESS && nframes > 0)
00116 logsuffix = ", back trace";
00117
00118 fprintf(stderr, "%s:%d: %s(%s) %s%s\n",
00119 file, line, isc_assertion_typetotext(type), cond,
00120 isc_msgcat_get(isc_msgcat, ISC_MSGSET_GENERAL,
00121 ISC_MSG_FAILED, "failed"), logsuffix);
00122 if (result == ISC_R_SUCCESS) {
00123 for (i = 0; i < nframes; i++) {
00124 unsigned long offset;
00125
00126 fname = NULL;
00127 result = isc_backtrace_getsymbol(tracebuf[i], &fname,
00128 &offset);
00129 if (result == ISC_R_SUCCESS) {
00130 fprintf(stderr, "#%d %p in %s()+0x%lx\n", i,
00131 tracebuf[i], fname, offset);
00132 } else {
00133 fprintf(stderr, "#%d %p in ??\n", i,
00134 tracebuf[i]);
00135 }
00136 }
00137 }
00138 fflush(stderr);
00139 }