source: trunk/third/sendmail/libsm/assert.c @ 19204

Revision 19204, 4.1 KB checked in by zacheiss, 22 years ago (diff)
This commit was generated by cvs2svn to compensate for changes in r19203, which included commits to RCS files with non-trunk default branches.
Line 
1/*
2 * Copyright (c) 2000-2001 Sendmail, Inc. and its suppliers.
3 *      All rights reserved.
4 *
5 * By using this file, you agree to the terms and conditions set
6 * forth in the LICENSE file which can be found at the top level of
7 * the sendmail distribution.
8 *
9 */
10
11#include <sm/gen.h>
12SM_RCSID("@(#)$Id: assert.c,v 1.1.1.1 2003-04-08 15:06:03 zacheiss Exp $")
13
14/*
15**  Abnormal program termination and assertion checking.
16**  For documentation, see assert.html.
17*/
18
19#include <signal.h>
20#include <stdlib.h>
21#include <unistd.h>
22
23#include <sm/assert.h>
24#include <sm/exc.h>
25#include <sm/io.h>
26#include <sm/varargs.h>
27
28/*
29**  Debug categories that are used to guard expensive assertion checks.
30*/
31
32SM_DEBUG_T SmExpensiveAssert = SM_DEBUG_INITIALIZER("sm_check_assert",
33        "@(#)$Debug: sm_check_assert - check assertions $");
34
35SM_DEBUG_T SmExpensiveRequire = SM_DEBUG_INITIALIZER("sm_check_require",
36        "@(#)$Debug: sm_check_require - check function preconditions $");
37
38SM_DEBUG_T SmExpensiveEnsure = SM_DEBUG_INITIALIZER("sm_check_ensure",
39        "@(#)$Debug: sm_check_ensure - check function postconditions $");
40
41/*
42**  Debug category: send self SIGSTOP on fatal error,
43**  so that you can run a debugger on the stopped process.
44*/
45
46SM_DEBUG_T SmAbortStop = SM_DEBUG_INITIALIZER("sm_abort_stop",
47        "@(#)$Debug: sm_abort_stop - stop process on fatal error $");
48
49/*
50**  SM_ABORT_DEFAULTHANDLER -- Default procedure for abnormal program
51**                              termination.
52**
53**      The goal is to display an error message without disturbing the
54**      process state too much, then dump core.
55**
56**      Parameters:
57**              filename -- filename (can be NULL).
58**              lineno -- line number.
59**              msg -- message.
60**
61**      Returns:
62**              doesn't return.
63*/
64
65static void
66sm_abort_defaulthandler __P((
67        const char *filename,
68        int lineno,
69        const char *msg));
70
71static void
72sm_abort_defaulthandler(filename, lineno, msg)
73        const char *filename;
74        int lineno;
75        const char *msg;
76{
77        if (filename != NULL)
78                sm_io_fprintf(smioerr, SM_TIME_DEFAULT, "%s:%d: %s\n", filename,
79                              lineno, msg);
80        else
81                sm_io_fprintf(smioerr, SM_TIME_DEFAULT, "%s\n", msg);
82        sm_io_flush(smioerr, SM_TIME_DEFAULT);
83#ifdef SIGSTOP
84        if (sm_debug_active(&SmAbortStop, 1))
85                kill(getpid(), SIGSTOP);
86#endif /* SIGSTOP */
87        abort();
88}
89
90/*
91**  This is the action to be taken to cause abnormal program termination.
92*/
93
94static SM_ABORT_HANDLER_T SmAbortHandler = sm_abort_defaulthandler;
95
96/*
97**  SM_ABORT_SETHANDLER -- Set handler for SM_ABORT()
98**
99**      This allows you to set a handler function for causing abnormal
100**      program termination; it is called when a logic bug is detected.
101**
102**      Parameters:
103**              f -- handler.
104**
105**      Returns:
106**              none.
107*/
108
109void
110sm_abort_sethandler(f)
111        SM_ABORT_HANDLER_T f;
112{
113        if (f == NULL)
114                SmAbortHandler = sm_abort_defaulthandler;
115        else
116                SmAbortHandler = f;
117}
118
119/*
120**  SM_ABORT -- Call it when you have detected a logic bug.
121**
122**      Parameters:
123**              fmt -- format string.
124**              ... -- arguments.
125**
126**      Returns:
127**              doesn't.
128*/
129
130void
131#if SM_VA_STD
132sm_abort(char *fmt, ...)
133#else /* SM_VA_STD */
134sm_abort(fmt, va_alist)
135        char *fmt;
136        va_dcl
137#endif /* SM_VA_STD */
138{
139        char msg[128];
140        SM_VA_LOCAL_DECL
141
142        SM_VA_START(ap, fmt);
143        sm_vsnprintf(msg, sizeof msg, fmt, ap);
144        SM_VA_END(ap);
145        sm_abort_at(NULL, 0, msg);
146}
147
148/*
149**  SM_ABORT_AT -- Initiate abnormal program termination.
150**
151**      This is the low level function that is called to initiate abnormal
152**      program termination.  It prints an error message and terminates the
153**      program.  It is called by sm_abort and by the assertion macros.
154**      If filename != NULL then filename and lineno specify the line of source
155**      code at which the bug was detected.
156**
157**      Parameters:
158**              filename -- filename (can be NULL).
159**              lineno -- line number.
160**              msg -- message.
161**
162**      Returns:
163**              doesn't.
164*/
165
166void
167sm_abort_at(filename, lineno, msg)
168        const char *filename;
169        int lineno;
170        const char *msg;
171{
172        SM_TRY
173                (*SmAbortHandler)(filename, lineno, msg);
174        SM_EXCEPT(exc, "*")
175                sm_io_fprintf(smioerr, SM_TIME_DEFAULT,
176                              "exception raised by abort handler:\n");
177                sm_exc_print(exc, smioerr);
178                sm_io_flush(smioerr, SM_TIME_DEFAULT);
179        SM_END_TRY
180
181        /*
182        **  SmAbortHandler isn't supposed to return.
183        **  Since it has, let's make sure that the program is terminated.
184        */
185
186        abort();
187}
Note: See TracBrowser for help on using the repository browser.