aboutsummaryrefslogtreecommitdiff
path: root/src/backend/utils/error
diff options
context:
space:
mode:
authorMarc G. Fournier <scrappy@hub.org>1996-07-09 06:22:35 +0000
committerMarc G. Fournier <scrappy@hub.org>1996-07-09 06:22:35 +0000
commitd31084e9d1118b25fd16580d9d8c2924b5740dff (patch)
tree3179e66307d54df9c7b966543550e601eb55e668 /src/backend/utils/error
downloadpostgresql-d31084e9d1118b25fd16580d9d8c2924b5740dff.tar.gz
postgresql-d31084e9d1118b25fd16580d9d8c2924b5740dff.zip
Postgres95 1.01 Distribution - Virgin SourcesPG95-1_01
Diffstat (limited to 'src/backend/utils/error')
-rw-r--r--src/backend/utils/error/Makefile.inc14
-rw-r--r--src/backend/utils/error/assert.c64
-rw-r--r--src/backend/utils/error/elog.c237
-rw-r--r--src/backend/utils/error/exc.c183
-rw-r--r--src/backend/utils/error/excabort.c28
-rw-r--r--src/backend/utils/error/excid.c64
-rw-r--r--src/backend/utils/error/format.c40
7 files changed, 630 insertions, 0 deletions
diff --git a/src/backend/utils/error/Makefile.inc b/src/backend/utils/error/Makefile.inc
new file mode 100644
index 00000000000..2c3d469669b
--- /dev/null
+++ b/src/backend/utils/error/Makefile.inc
@@ -0,0 +1,14 @@
+#-------------------------------------------------------------------------
+#
+# Makefile.inc--
+# Makefile for utils/error
+#
+# Copyright (c) 1994, Regents of the University of California
+#
+#
+# IDENTIFICATION
+# $Header: /cvsroot/pgsql/src/backend/utils/error/Attic/Makefile.inc,v 1.1.1.1 1996/07/09 06:22:07 scrappy Exp $
+#
+#-------------------------------------------------------------------------
+
+SUBSRCS+= assert.c elog.c exc.c excabort.c excid.c format.c
diff --git a/src/backend/utils/error/assert.c b/src/backend/utils/error/assert.c
new file mode 100644
index 00000000000..ac2de1631d1
--- /dev/null
+++ b/src/backend/utils/error/assert.c
@@ -0,0 +1,64 @@
+/*-------------------------------------------------------------------------
+ *
+ * assert.c--
+ * Assert code.
+ *
+ * Copyright (c) 1994, Regents of the University of California
+ *
+ *
+ * IDENTIFICATION
+ * $Header: /cvsroot/pgsql/src/backend/utils/error/assert.c,v 1.1.1.1 1996/07/09 06:22:07 scrappy Exp $
+ *
+ * NOTE
+ * This should eventually work with elog(), dlog(), etc.
+ *
+ *-------------------------------------------------------------------------
+ */
+#include <stdio.h>
+
+#include "c.h" /* where the declaration goes */
+#include "utils/module.h"
+
+#include "utils/exc.h"
+
+int
+ExceptionalCondition(char* conditionName,
+ Exception *exceptionP,
+ char* detail,
+ char* fileName,
+ int lineNumber)
+{
+ extern char* ExcFileName; /* XXX */
+ extern Index ExcLineNumber; /* XXX */
+
+ ExcFileName = fileName;
+ ExcLineNumber = lineNumber;
+
+ if (!PointerIsValid(conditionName)
+ || !PointerIsValid(fileName)
+ || !PointerIsValid(exceptionP)) {
+ fprintf(stderr, "ExceptionalCondition: bad arguments\n");
+
+ ExcAbort(exceptionP,
+ (ExcDetail)detail,
+ (ExcData)NULL,
+ (ExcMessage)NULL);
+ } else {
+ fprintf(stderr,
+ "%s(\"%s:%s\", File: \"%s\", Line: %d)\n",
+ exceptionP->message, conditionName, detail,
+ fileName, lineNumber);
+ }
+
+ /*
+ * XXX Depending on the Exception and tracing conditions, you will
+ * XXX want to stop here immediately and maybe dump core.
+ * XXX This may be especially true for Assert(), etc.
+ */
+
+ /* TraceDump(); dump the trace stack */
+
+ /* XXX FIXME: detail is lost */
+ ExcRaise(exceptionP, (ExcDetail)0, (ExcData)NULL, conditionName);
+ return(0);
+}
diff --git a/src/backend/utils/error/elog.c b/src/backend/utils/error/elog.c
new file mode 100644
index 00000000000..d5bef1ab1ba
--- /dev/null
+++ b/src/backend/utils/error/elog.c
@@ -0,0 +1,237 @@
+/*-------------------------------------------------------------------------
+ *
+ * elog.c--
+ * error logger
+ *
+ * Copyright (c) 1994, Regents of the University of California
+ *
+ *
+ * IDENTIFICATION
+ * $Header: /cvsroot/pgsql/src/backend/utils/error/elog.c,v 1.1.1.1 1996/07/09 06:22:07 scrappy Exp $
+ *
+ *-------------------------------------------------------------------------
+ */
+#include <stdio.h>
+#include <string.h>
+#include <time.h>
+#include <fcntl.h>
+#ifndef O_RDONLY
+#include <sys/file.h>
+#endif /* O_RDONLY */
+#include <sys/types.h>
+#include <stdarg.h>
+#include <errno.h>
+
+#include "postgres.h"
+#include "miscadmin.h"
+#include "utils/elog.h"
+#include "libpq/libpq.h"
+#include "storage/proc.h"
+
+static int Debugfile = -1;
+static int Err_file = -1;
+static int ElogDebugIndentLevel = 0;
+
+extern char OutputFileName[];
+#ifdef WIN32
+extern jmp_buf Warn_restart;
+#endif
+
+/*
+ * elog --
+ * Old error logging function.
+ */
+void
+elog(int lev, char *fmt, ... )
+{
+ va_list ap;
+ char buf[ELOG_MAXLEN], line[ELOG_MAXLEN];
+ register char *bp, *cp;
+ extern int errno, sys_nerr;
+#if !defined(PORTNAME_BSD44_derived) && !defined(PORTNAME_bsdi)
+ extern char *sys_errlist[];
+#endif /* !PORTNAME_BSD44_derived */
+#ifndef PG_STANDALONE
+ extern FILE *Pfout;
+#endif /* !PG_STANDALONE */
+ time_t tim, time();
+ int len;
+ int i = 0;
+
+ va_start(ap, fmt);
+ if (lev == DEBUG && Debugfile < 0) {
+ return;
+ }
+ switch (lev) {
+ case NOIND:
+ i = ElogDebugIndentLevel-1;
+ if (i < 0) i = 0;
+ if (i > 30) i = i%30;
+ cp = "DEBUG:";
+ break;
+ case DEBUG:
+ i = ElogDebugIndentLevel;
+ if (i < 0) i = 0;
+ if (i > 30) i = i%30;
+ cp = "DEBUG:";
+ break;
+ case NOTICE:
+ cp = "NOTICE:";
+ break;
+ case WARN:
+ cp = "WARN:";
+ break;
+ default:
+ sprintf(line, "FATAL %d:", lev);
+ cp = line;
+ }
+#ifdef ELOG_TIMESTAMPS
+ time(&tim);
+ strcat(strcpy(buf, cp), ctime(&tim)+4);
+ bp = buf+strlen(buf)-6;
+ *bp++ = ':';
+#else
+ strcpy(buf,cp);
+ bp = buf+strlen(buf);
+#endif
+ while (i-- >0) *bp++ = ' ';
+ for (cp = fmt; *cp; cp++)
+ if (*cp == '%' && *(cp+1) == 'm') {
+ if (errno < sys_nerr && errno >= 0)
+ strcpy(bp, sys_errlist[errno]);
+ else
+ sprintf(bp, "error %d", errno);
+ bp += strlen(bp);
+ cp++;
+ } else
+ *bp++ = *cp;
+ *bp = '\0';
+ vsprintf(line, buf, ap);
+ va_end(ap);
+ len = strlen(strcat(line, "\n"));
+ if (Debugfile > -1)
+ write(Debugfile, line, len);
+ if (lev == DEBUG || lev == NOIND)
+ return;
+
+ /*
+ * If there's an error log file other than our channel to the
+ * front-end program, write to it first. This is important
+ * because there's a bug in the socket code on ultrix. If the
+ * front end has gone away (so the channel to it has been closed
+ * at the other end), then writing here can cause this backend
+ * to exit without warning -- that is, write() does an exit().
+ * In this case, our only hope of finding out what's going on
+ * is if Err_file was set to some disk log. This is a major pain.
+ */
+
+ if (Err_file > -1 && Debugfile != Err_file) {
+ if (write(Err_file, line, len) < 0) {
+ write(open("/dev/console", O_WRONLY, 0666), line, len);
+ fflush(stdout);
+ fflush(stderr);
+ exitpg(lev);
+ }
+ fsync(Err_file);
+ }
+
+#ifndef PG_STANDALONE
+ /* Send IPC message to the front-end program */
+ if (Pfout != NULL && lev > DEBUG) {
+ /* notices are not exactly errors, handle it differently */
+ if (lev == NOTICE)
+ pq_putnchar("N", 1);
+ else
+ pq_putnchar("E", 1);
+ /* pq_putint(-101, 4);*/ /* should be query id */
+ pq_putstr(line);
+ pq_flush();
+ }
+#endif /* !PG_STANDALONE */
+
+ if (lev == WARN) {
+ ProcReleaseSpins(NULL); /* get rid of spinlocks we hold */
+#ifndef WIN32
+ kill(getpid(), 1); /* abort to traffic cop */
+ pause();
+#else
+ longjmp(Warn_restart, 1);
+#endif /* WIN32 */
+ /*
+ * The pause(3) is just to avoid race conditions where the
+ * thread of control on an MP system gets past here (i.e.,
+ * the signal is not received instantaneously).
+ */
+ }
+
+ if (lev == FATAL) {
+ /*
+ * Assume that if we have detected the failure we can
+ * exit with a normal exit status. This will prevent
+ * the postmaster from cleaning up when it's not needed.
+ */
+ fflush(stdout);
+ fflush(stderr);
+ ProcReleaseSpins(NULL); /* get rid of spinlocks we hold */
+ ProcReleaseLocks(); /* get rid of real locks we hold */
+ exitpg(0);
+ }
+
+ if (lev > FATAL) {
+ fflush(stdout);
+ fflush(stderr);
+ exitpg(lev);
+ }
+}
+
+#ifndef PG_STANDALONE
+int
+DebugFileOpen()
+{
+ int fd, istty;
+
+ Err_file = Debugfile = -1;
+ ElogDebugIndentLevel = 0;
+
+ if (OutputFileName[0]) {
+ OutputFileName[MAXPGPATH-1] = '\0';
+ if ((fd = open(OutputFileName, O_CREAT|O_APPEND|O_WRONLY,
+ 0666)) < 0)
+ elog(FATAL, "DebugFileOpen: open of %s: %m",
+ OutputFileName);
+ istty = isatty(fd);
+ (void) close(fd);
+ /* If the file is a tty and we're running under the
+ * postmaster, try to send stdout there as well (if it
+ * isn't a tty then stderr will block out stdout, so we
+ * may as well let stdout go wherever it was going before).
+ */
+ if (istty &&
+ IsUnderPostmaster &&
+ !freopen(OutputFileName, "a", stdout))
+ elog(FATAL, "DebugFileOpen: %s reopen as stdout: %m",
+ OutputFileName);
+ if (!freopen(OutputFileName, "a", stderr))
+ elog(FATAL, "DebugFileOpen: %s reopen as stderr: %m",
+ OutputFileName);
+ Err_file = Debugfile = fileno(stderr);
+ return(Debugfile);
+ }
+#ifndef WIN32
+ /* If no filename was specified, send debugging output to stderr.
+ * If stderr has been hosed, try to open a file.
+ */
+ fd = fileno(stderr);
+ if (fcntl(fd, F_GETFD, 0) < 0) {
+ sprintf(OutputFileName, "%s/pg.errors.%d",
+ GetPGData(), getpid());
+ fd = open(OutputFileName, O_CREAT|O_APPEND|O_WRONLY, 0666);
+ }
+#endif /* WIN32 */
+ if (fd < 0)
+ elog(FATAL, "DebugFileOpen: could not open debugging file");
+
+ Err_file = Debugfile = fd;
+ return(Debugfile);
+}
+#endif
diff --git a/src/backend/utils/error/exc.c b/src/backend/utils/error/exc.c
new file mode 100644
index 00000000000..35c5db9118f
--- /dev/null
+++ b/src/backend/utils/error/exc.c
@@ -0,0 +1,183 @@
+/*-------------------------------------------------------------------------
+ *
+ * exc.c--
+ * POSTGRES exception handling code.
+ *
+ * Copyright (c) 1994, Regents of the University of California
+ *
+ *
+ * IDENTIFICATION
+ * $Header: /cvsroot/pgsql/src/backend/utils/error/Attic/exc.c,v 1.1.1.1 1996/07/09 06:22:07 scrappy Exp $
+ *
+ * NOTE
+ * XXX this code needs improvement--check for state violations and
+ * XXX reset after handling an exception.
+ *
+ *-------------------------------------------------------------------------
+ */
+#include <stdio.h> /* XXX use own I/O routines */
+#include <errno.h>
+#include "utils/exc.h"
+#include "storage/ipc.h"
+
+/*
+ * Global Variables
+ */
+static bool ExceptionHandlingEnabled = false;
+
+char* ExcFileName = NULL;
+Index ExcLineNumber = 0;
+
+ExcFrame *ExcCurFrameP = NULL;
+
+static ExcProc *ExcUnCaughtP = NULL;
+
+extern char* ProgramName;
+
+/*
+ * Exported Functions
+ */
+
+/*
+ * EnableExceptionHandling --
+ * Enables/disables the exception handling system.
+ *
+ * Note:
+ * This must be called before any exceptions occur. I.e., call this first!
+ * This routine will not return if an error is detected.
+ * This does not follow the usual Enable... protocol.
+ * This should be merged more closely with the error logging and tracing
+ * packages.
+ *
+ * Exceptions:
+ * none
+ */
+/*
+ * Excection handling should be supported by the language, thus there should
+ * be no need to explicitly enable exception processing.
+ *
+ * This function should probably not be called, ever. Currently it does
+ * almost nothing. If there is a need for this intialization and checking.
+ * then this function should be converted to the new-style Enable code and
+ * called by all the other module Enable functions.
+ */
+void
+EnableExceptionHandling(bool on)
+{
+ if (on == ExceptionHandlingEnabled) {
+ /* XXX add logging of failed state */
+ exitpg(255);
+ /* ExitPostgres(FatalExitStatus); */
+ }
+
+ if (on) { /* initialize */
+ ;
+ } else { /* cleanup */
+ ExcFileName = NULL;
+ ExcLineNumber = 0;
+ ExcCurFrameP = NULL;
+ ExcUnCaughtP = NULL;
+ }
+
+ ExceptionHandlingEnabled = on;
+}
+
+void
+ExcPrint(Exception *excP,
+ ExcDetail detail,
+ ExcData data,
+ ExcMessage message)
+{
+ extern int errno;
+ extern int sys_nerr;
+#if !defined(PORTNAME_BSD44_derived) && !defined(PORTNAME_bsdi)
+ extern char *sys_errlist[];
+#endif /* !PORTNAME_BSD44_derived */
+
+#ifdef lint
+ data = data;
+#endif
+
+ (void) fflush(stdout); /* In case stderr is buffered */
+
+#if 0
+ if (ProgramName != NULL && *ProgramName != '\0')
+ (void) fprintf(stderr, "%s: ", ProgramName);
+#endif
+
+ if (message != NULL)
+ (void) fprintf(stderr, "%s", message);
+ else if (excP->message != NULL)
+ (void) fprintf(stderr, "%s", excP->message);
+ else
+#ifdef lint
+ (void) fprintf(stderr, "UNNAMED EXCEPTION 0x%lx", excP);
+#else
+ (void) fprintf(stderr, "UNNAMED EXCEPTION 0x%lx", (long)excP);
+#endif
+
+ (void) fprintf(stderr, " (%ld)", detail);
+
+ if (errno > 0 && errno < sys_nerr &&
+ sys_errlist[errno] != NULL && sys_errlist[errno][0] != '\0')
+ (void) fprintf(stderr, " [%s]", sys_errlist[errno]);
+ else if (errno != 0)
+ (void) fprintf(stderr, " [Error %d]", errno);
+
+ (void) fprintf(stderr, "\n");
+
+ (void) fflush(stderr);
+}
+
+ExcProc *
+ExcGetUnCaught()
+{
+ return (ExcUnCaughtP);
+}
+
+ExcProc *
+ExcSetUnCaught(ExcProc *newP)
+{
+ ExcProc *oldP = ExcUnCaughtP;
+
+ ExcUnCaughtP = newP;
+
+ return (oldP);
+}
+
+void
+ExcUnCaught(Exception *excP,
+ ExcDetail detail,
+ ExcData data,
+ ExcMessage message)
+{
+ ExcPrint(excP, detail, data, message);
+
+ ExcAbort(excP, detail, data, message);
+}
+
+void
+ExcRaise(Exception *excP,
+ ExcDetail detail,
+ ExcData data,
+ ExcMessage message)
+{
+ register ExcFrame *efp;
+
+ efp = ExcCurFrameP;
+ if (efp == NULL) {
+ if (ExcUnCaughtP != NULL)
+ (*ExcUnCaughtP)(excP, detail, data, message);
+
+ ExcUnCaught(excP, detail, data, message);
+ } else {
+ efp->id = excP;
+ efp->detail = detail;
+ efp->data = data;
+ efp->message = message;
+
+ ExcCurFrameP = efp->link;
+
+ longjmp(efp->context, 1);
+ }
+}
diff --git a/src/backend/utils/error/excabort.c b/src/backend/utils/error/excabort.c
new file mode 100644
index 00000000000..d1b14361ea5
--- /dev/null
+++ b/src/backend/utils/error/excabort.c
@@ -0,0 +1,28 @@
+/*-------------------------------------------------------------------------
+ *
+ * excabort.c--
+ * Default exception abort code.
+ *
+ * Copyright (c) 1994, Regents of the University of California
+ *
+ *
+ * IDENTIFICATION
+ * $Header: /cvsroot/pgsql/src/backend/utils/error/Attic/excabort.c,v 1.1.1.1 1996/07/09 06:22:07 scrappy Exp $
+ *
+ *-------------------------------------------------------------------------
+ */
+#include "utils/exc.h" /* where function declarations go */
+
+void
+ExcAbort(const Exception *excP,
+ ExcDetail detail,
+ ExcData data,
+ ExcMessage message)
+{
+#ifdef __SABER__
+ saber_stop();
+#else
+ /* dump core */
+ abort();
+#endif
+}
diff --git a/src/backend/utils/error/excid.c b/src/backend/utils/error/excid.c
new file mode 100644
index 00000000000..4d87c16344f
--- /dev/null
+++ b/src/backend/utils/error/excid.c
@@ -0,0 +1,64 @@
+/*-------------------------------------------------------------------------
+ *
+ * excid.c--
+ * POSTGRES known exception identifier code.
+ *
+ * Copyright (c) 1994, Regents of the University of California
+ *
+ *
+ * IDENTIFICATION
+ * $Header: /cvsroot/pgsql/src/backend/utils/error/Attic/excid.c,v 1.1.1.1 1996/07/09 06:22:07 scrappy Exp $
+ *
+ *-------------------------------------------------------------------------
+ */
+#include "utils/excid.h"
+
+/*****************************************************************************
+ * Generic Recoverable Exceptions *
+ *****************************************************************************/
+
+
+/*
+ * FailedAssertion --
+ * Indicates an Assert(...) failed.
+ */
+Exception FailedAssertion = { "Failed Assertion" };
+
+/*
+ * BadState --
+ * Indicates a function call request is inconsistent with module state.
+ */
+Exception BadState = { "Bad State for Function Call" };
+
+/*
+ * BadArg --
+ * Indicates a function call argument or arguments is out-of-bounds.
+ */
+Exception BadArg = { "Bad Argument to Function Call" };
+
+/*****************************************************************************
+ * Specific Recoverable Exceptions *
+ *****************************************************************************/
+
+/*
+ * BadAllocSize --
+ * Indicates that an allocation request is of unreasonable size.
+ */
+Exception BadAllocSize = { "Too Large Allocation Request" };
+
+/*
+ * ExhaustedMemory --
+ * Indicates an dynamic memory allocation failed.
+ */
+Exception ExhaustedMemory = { "Memory Allocation Failed" };
+
+/*
+ * Unimplemented --
+ * Indicates a function call request requires unimplemented code.
+ */
+Exception Unimplemented = { "Unimplemented Functionality" };
+
+Exception CatalogFailure = {"Catalog failure"}; /* XXX inconsistent */
+Exception InternalError = {"Internal Error"}; /* XXX inconsistent */
+Exception SemanticError = {"Semantic Error"}; /* XXX inconsistent */
+Exception SystemError = {"System Error"}; /* XXX inconsistent */
diff --git a/src/backend/utils/error/format.c b/src/backend/utils/error/format.c
new file mode 100644
index 00000000000..99a5d15af57
--- /dev/null
+++ b/src/backend/utils/error/format.c
@@ -0,0 +1,40 @@
+/*-------------------------------------------------------------------------
+ *
+ * format.c--
+ * a wrapper around code that does what vsprintf does.
+ *
+ * Copyright (c) 1994, Regents of the University of California
+ *
+ *
+ * IDENTIFICATION
+ * $Header: /cvsroot/pgsql/src/backend/utils/error/Attic/format.c,v 1.1.1.1 1996/07/09 06:22:07 scrappy Exp $
+ *
+ *-------------------------------------------------------------------------
+ */
+#include <stdio.h>
+#include <stdarg.h>
+#include "c.h"
+
+#define FormMaxSize 1024
+#define FormMinSize (FormMaxSize / 8)
+
+static char FormBuf[FormMaxSize];
+
+
+/* ----------------
+ * form
+ * ----------------
+ */
+char *
+form(char *fmt, ... )
+{
+ va_list args;
+
+ va_start(args, fmt);
+
+ (void) vsprintf(FormBuf, fmt, args);
+
+ va_end(args);
+
+ return (FormBuf);
+}