summaryrefslogtreecommitdiffstats
path: root/generic/tclPanic.c
diff options
context:
space:
mode:
Diffstat (limited to 'generic/tclPanic.c')
-rw-r--r--generic/tclPanic.c82
1 files changed, 52 insertions, 30 deletions
diff --git a/generic/tclPanic.c b/generic/tclPanic.c
index 9b1c36f..2a453b9 100644
--- a/generic/tclPanic.c
+++ b/generic/tclPanic.c
@@ -11,25 +11,23 @@
*
* See the file "license.terms" for information on usage and redistribution of
* this file, and for a DISCLAIMER OF ALL WARRANTIES.
- *
- * RCS: @(#) $Id: tclPanic.c,v 1.6 2005/07/19 22:45:35 dkf Exp $
*/
#include "tclInt.h"
+#if defined(_WIN32) || defined(__CYGWIN__)
+ MODULE_SCOPE void tclWinDebugPanic(const char *format, ...);
+#endif
/*
* The panicProc variable contains a pointer to an application specific panic
* procedure.
*/
+#if defined(__CYGWIN__)
+static Tcl_PanicProc *panicProc = tclWinDebugPanic;
+#else
static Tcl_PanicProc *panicProc = NULL;
-
-/*
- * The platformPanicProc variable contains a pointer to a platform specific
- * panic procedure, if any. (TclpPanic may be NULL via a macro.)
- */
-
-static Tcl_PanicProc *CONST platformPanicProc = TclpPanic;
+#endif
/*
*----------------------------------------------------------------------
@@ -48,9 +46,17 @@ static Tcl_PanicProc *CONST platformPanicProc = TclpPanic;
*/
void
-Tcl_SetPanicProc(proc)
- Tcl_PanicProc *proc;
+Tcl_SetPanicProc(
+ Tcl_PanicProc *proc)
{
+#if defined(_WIN32)
+ /* tclWinDebugPanic only installs if there is no panicProc yet. */
+ if ((proc != tclWinDebugPanic) || (panicProc == NULL))
+#elif defined(__CYGWIN__)
+ if (proc == NULL)
+ panicProc = tclWinDebugPanic;
+ else
+#endif
panicProc = proc;
}
@@ -71,14 +77,14 @@ Tcl_SetPanicProc(proc)
*/
void
-Tcl_PanicVA(format, argList)
- CONST char *format; /* Format string, suitable for passing to
+Tcl_PanicVA(
+ const char *format, /* Format string, suitable for passing to
* fprintf. */
- va_list argList; /* Variable argument list. */
+ va_list argList) /* Variable argument list. */
{
- char *arg1, *arg2, *arg3, *arg4; /* Additional arguments (variable in
- * number) to pass to fprintf. */
- char *arg5, *arg6, *arg7, *arg8;
+ char *arg1, *arg2, *arg3; /* Additional arguments (variable in number)
+ * to pass to fprintf. */
+ char *arg4, *arg5, *arg6, *arg7, *arg8;
arg1 = va_arg(argList, char *);
arg2 = va_arg(argList, char *);
@@ -90,17 +96,32 @@ Tcl_PanicVA(format, argList)
arg8 = va_arg(argList, char *);
if (panicProc != NULL) {
- (void) (*panicProc)(format, arg1, arg2, arg3, arg4,
- arg5, arg6, arg7, arg8);
- } else if (platformPanicProc != NULL) {
- (void) (*platformPanicProc)(format, arg1, arg2, arg3, arg4,
- arg5, arg6, arg7, arg8);
+ panicProc(format, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8);
+#ifdef _WIN32
+ } else if (IsDebuggerPresent()) {
+ tclWinDebugPanic(format, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8);
+#endif
} else {
- (void) fprintf(stderr, format, arg1, arg2, arg3, arg4, arg5, arg6,
- arg7, arg8);
- (void) fprintf(stderr, "\n");
- (void) fflush(stderr);
+ fprintf(stderr, format, arg1, arg2, arg3, arg4, arg5, arg6, arg7,
+ arg8);
+ fprintf(stderr, "\n");
+ fflush(stderr);
+#if defined(_WIN32) || defined(__CYGWIN__)
+# if defined(__GNUC__)
+ __builtin_trap();
+# elif defined(_WIN64)
+ __debugbreak();
+# elif defined(_MSC_VER)
+ _asm {int 3}
+# else
+ DebugBreak();
+# endif
+#endif
+#if defined(_WIN32)
+ ExitProcess(1);
+#else
abort();
+#endif
}
}
@@ -120,14 +141,15 @@ Tcl_PanicVA(format, argList)
*----------------------------------------------------------------------
*/
- /* VARARGS ARGSUSED */
+ /* ARGSUSED */
void
-Tcl_Panic TCL_VARARGS_DEF(CONST char *,arg1)
+Tcl_Panic(
+ const char *format,
+ ...)
{
va_list argList;
- CONST char *format;
- format = TCL_VARARGS_START(CONST char *,arg1,argList);
+ va_start(argList, format);
Tcl_PanicVA(format, argList);
va_end (argList);
}