diff options
Diffstat (limited to 'generic/tclPanic.c')
-rw-r--r-- | generic/tclPanic.c | 64 |
1 files changed, 42 insertions, 22 deletions
diff --git a/generic/tclPanic.c b/generic/tclPanic.c index 600307e..84a9136 100644 --- a/generic/tclPanic.c +++ b/generic/tclPanic.c @@ -14,20 +14,20 @@ */ #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 /* *---------------------------------------------------------------------- @@ -49,6 +49,10 @@ void Tcl_SetPanicProc( Tcl_PanicProc *proc) { +#if defined(_WIN32) + /* tclWinDebugPanic only installs if there is no panicProc yet. */ + if ((proc != tclWinDebugPanic) || (panicProc == NULL)) +#endif panicProc = proc; } @@ -70,13 +74,13 @@ Tcl_SetPanicProc( void Tcl_PanicVA( - CONST char *format, /* Format string, suitable for passing to + const char *format, /* Format string, suitable for passing to * fprintf. */ 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 *); @@ -88,18 +92,34 @@ Tcl_PanicVA( 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); - abort(); + fprintf(stderr, format, arg1, arg2, arg3, arg4, arg5, arg6, arg7, + arg8); + fprintf(stderr, "\n"); + fflush(stderr); } + /* In case the users panic proc does not abort, we do it here */ +#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 } /* @@ -121,7 +141,7 @@ Tcl_PanicVA( /* ARGSUSED */ void Tcl_Panic( - CONST char *format, + const char *format, ...) { va_list argList; |