/[ascend]/trunk/base/generic/utilities/ascPanic.c
ViewVC logotype

Contents of /trunk/base/generic/utilities/ascPanic.c

Parent Directory Parent Directory | Revision Log Revision Log


Revision 976 - (show annotations) (download) (as text)
Tue Dec 19 13:52:51 2006 UTC (16 years, 9 months ago) by johnpye
File MIME type: text/x-csrc
File size: 5556 byte(s)
Improved line/file/func reporting via Asc_Panic, using CPP var-arg macros under GCC.
Added ASC_ASSERT_LT and ASC_ASSERT_EQ assertion macros.
Tracking down a crash in IDA (ongoing).
1 /*
2 ASCEND Language Interpreter
3 AscPanic by Mark Thomas, created 15 May 1997
4 Copyright (C) 2005 Carnegie-Mellon University
5
6 This program is free software; you can redistribute it and/or modify
7 it under the terms of the GNU General Public License as published by
8 the Free Software Foundation; either version 2 of the License, or
9 (at your option) any later version.
10
11 This program is distributed in the hope that it will be useful,
12 but WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 GNU General Public License for more details.
15
16 You should have received a copy of the GNU General Public License
17 along with this program; if not, write to the Free Software
18 Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
19 This file is part of the SLV solver.
20 */
21
22 /* removed changelog -- please consult commit comments in ViewCVS */
23
24 #include <stdarg.h>
25 #include "ascConfig.h"
26 #include "ascPanic.h"
27
28 #define PANIC_MSG_MAXLEN 2047
29 /**< The maximum length of the panic message.
30 Used to create a buffer to hold the message.
31 */
32
33 static PanicCallbackFunc f_panic_callback_func = NULL;
34 /**< Holds a pointer to a callback function if registered using
35 Asc_PanicSetCallback(). If NULL (the default), nothing is called.
36 */
37
38 /*
39 disable the windows message box...
40 #if defined(__WIN32__)
41 # define USE_WIN32_FATAL_MSGBOX
42 #endif
43 */
44
45 #ifdef USE_WIN32_FATAL_MSGBOX
46 static int f_display_MessageBox = TRUE;
47 /**< On Windows only, flag to enable/disable display of the MessageBox
48 in Asc_Panic().
49 */
50 #endif
51
52 static char g_panic_outfile[PATH_MAX];
53 /**< Holds the name of the file in which to write panic messages.
54 Use the Asc_PanicSetOutfile(filename) function to set it.
55 */
56
57
58 /**
59 This static function does the actual output of a PANIC message. It aims
60 to do a few things to ensure that the user always gets the message.
61
62 @TODO We could can improve even further by integrating with some crash
63 reporting facility in GNOME, etc?
64 */
65 static void asc_va_panic(const int status, const char *filename, const int line
66 , const char *function, const char *fmt, const va_list args
67 ){
68 FILE *outfile; /* The file to save the message into */
69 int cancel = FALSE; /* If non-zero, do not call exit(). Default is to exit() */
70 char msg[PANIC_MSG_MAXLEN];
71 size_t p;
72
73 /* Fail loudly if ASCERR isn't set to a file pointer -- can't use asc_assert here! */
74 assert(NULL != ASCERR);
75
76 p = snprintf(msg,PANIC_MSG_MAXLEN-2,"%s:%d (%s): ",filename,line,function);
77
78 /* Add the variable args to the panic message using the format "format" */
79 vsnprintf(msg+p, PANIC_MSG_MAXLEN-p-2, fmt, args );
80
81 p = strlen(msg);
82 msg[p++] = '\n';
83 msg[p++] = '\0';
84
85 /*
86 Always write the message to g_panic_outfile if it is not empty
87 and we can actually write to that location. Print a
88 message on ASCERR (if valid) saying that we did that.
89 */
90 if(( *g_panic_outfile != '\0' )
91 && ( (outfile=fopen(g_panic_outfile,"w")) != NULL )
92 ){
93 fprintf(outfile, msg);
94 CONSOLE_DEBUG("Error message written to %s\n", g_panic_outfile);
95
96 fclose(outfile);
97 }
98
99 if (NULL == f_panic_callback_func) {
100 /* No panic-callback, so we reset the error handler and output to console */
101 error_reporter_set_callback(NULL);
102
103 /* Print the message to the default error reporter (ASCERR) */
104 fprintf(stderr,"\n\n");
105 va_error_reporter(ASC_PROG_FATAL,filename,line,function,fmt,args);
106 fprintf(stderr,"\n");
107
108 }else{
109 /* just use the callback, don't make any output */
110 cancel = (*f_panic_callback_func)(status);
111 if(cancel){
112 ERROR_REPORTER_HERE(ASC_PROG_ERR,
113 "AscPanic 'cancel' facility has been disabled, program will exit"
114 );
115 }
116 }
117
118 /* Display msg in a MessageBox under Windows unless turned off */
119 #ifdef USE_WIN32_FATAL_MSGBOX
120 if(FALSE != f_display_MessageBox) {
121 (void)MessageBeep(MB_ICONEXCLAMATION);
122 MessageBox(NULL, msg, "Fatal Error in ASCEND"
123 ,(UINT)(MB_ICONSTOP | MB_OK | MB_TASKMODAL | MB_SETFOREGROUND)
124 );
125 }
126 #endif
127 }
128
129 /**
130 This is a new replacement for Asc_Panic that handles error source
131 details (line, file, function) itself.
132 */
133 void asc_panic_line(const int status, const char *filename, const int line
134 , const char *function, const char *fmt, ...
135 ){
136 va_list args;
137
138 va_start(args,fmt);
139 asc_va_panic(status,filename,line,function,fmt,args);
140 va_end(args);
141
142 #ifdef USE_WIN32_FATAL_MSGBOX
143 ExitProcess((UINT)status);
144 #else
145 # ifndef NDEBUG
146 abort();
147 # else
148 exit(status);
149 # endif
150 #endif
151 }
152
153 #if defined(__GNUC__) && !defined(__STRICT_ANSI__)
154 /**
155 we only need this function if our platform doesn't support var-arg macros
156 */
157 void asc_panic(CONST int status, CONST CONST char *function
158 ,CONST char *fmt, ...
159 ){
160 va_list args;
161
162 va_start(args,fmt);
163 asc_va_panic(status,NULL,0,function,fmt,args);
164 va_end(args);
165 # ifdef USE_WIN32_FATAL_MSGBOX
166 ExitProcess((UINT)status);
167 # else
168 # ifndef NDEBUG
169 abort();
170 # else
171 exit(status);
172 # endif
173 # endif
174 }
175 #endif
176
177 void Asc_PanicSetOutfile(CONST char *filename)
178 {
179 if( filename != NULL ) {
180 strncpy( g_panic_outfile, filename, PATH_MAX-1 );
181 g_panic_outfile[PATH_MAX-1] = '\0';
182 } else {
183 g_panic_outfile[0] = '\0';
184 }
185 }
186
187 PanicCallbackFunc Asc_PanicSetCallback(PanicCallbackFunc func)
188 {
189 PanicCallbackFunc old_func = f_panic_callback_func;
190 f_panic_callback_func = func;
191 return old_func;
192 }
193
194
195 void Asc_PanicDisplayMessageBox(int is_displayed)
196 {
197 #ifdef USE_WIN32_FATAL_MSGBOX
198 f_display_MessageBox = is_displayed;
199 #else
200 UNUSED_PARAMETER(is_displayed);
201 #endif
202 }

john.pye@anu.edu.au
ViewVC Help
Powered by ViewVC 1.1.22