Age Owner TLA Line data Source code
1 : /*-------------------------------------------------------------------------
2 : *
3 : * elog.c
4 : * error logging and reporting
5 : *
6 : * Because of the extremely high rate at which log messages can be generated,
7 : * we need to be mindful of the performance cost of obtaining any information
8 : * that may be logged. Also, it's important to keep in mind that this code may
9 : * get called from within an aborted transaction, in which case operations
10 : * such as syscache lookups are unsafe.
11 : *
12 : * Some notes about recursion and errors during error processing:
13 : *
14 : * We need to be robust about recursive-error scenarios --- for example,
15 : * if we run out of memory, it's important to be able to report that fact.
16 : * There are a number of considerations that go into this.
17 : *
18 : * First, distinguish between re-entrant use and actual recursion. It
19 : * is possible for an error or warning message to be emitted while the
20 : * parameters for an error message are being computed. In this case
21 : * errstart has been called for the outer message, and some field values
22 : * may have already been saved, but we are not actually recursing. We handle
23 : * this by providing a (small) stack of ErrorData records. The inner message
24 : * can be computed and sent without disturbing the state of the outer message.
25 : * (If the inner message is actually an error, this isn't very interesting
26 : * because control won't come back to the outer message generator ... but
27 : * if the inner message is only debug or log data, this is critical.)
28 : *
29 : * Second, actual recursion will occur if an error is reported by one of
30 : * the elog.c routines or something they call. By far the most probable
31 : * scenario of this sort is "out of memory"; and it's also the nastiest
32 : * to handle because we'd likely also run out of memory while trying to
33 : * report this error! Our escape hatch for this case is to reset the
34 : * ErrorContext to empty before trying to process the inner error. Since
35 : * ErrorContext is guaranteed to have at least 8K of space in it (see mcxt.c),
36 : * we should be able to process an "out of memory" message successfully.
37 : * Since we lose the prior error state due to the reset, we won't be able
38 : * to return to processing the original error, but we wouldn't have anyway.
39 : * (NOTE: the escape hatch is not used for recursive situations where the
40 : * inner message is of less than ERROR severity; in that case we just
41 : * try to process it and return normally. Usually this will work, but if
42 : * it ends up in infinite recursion, we will PANIC due to error stack
43 : * overflow.)
44 : *
45 : *
46 : * Portions Copyright (c) 1996-2023, PostgreSQL Global Development Group
47 : * Portions Copyright (c) 1994, Regents of the University of California
48 : *
49 : *
50 : * IDENTIFICATION
51 : * src/backend/utils/error/elog.c
52 : *
53 : *-------------------------------------------------------------------------
54 : */
55 : #include "postgres.h"
56 :
57 : #include <fcntl.h>
58 : #include <time.h>
59 : #include <unistd.h>
60 : #include <signal.h>
61 : #include <ctype.h>
62 : #ifdef HAVE_SYSLOG
63 : #include <syslog.h>
64 : #endif
65 : #ifdef HAVE_EXECINFO_H
66 : #include <execinfo.h>
67 : #endif
68 :
69 : #include "access/transam.h"
70 : #include "access/xact.h"
71 : #include "libpq/libpq.h"
72 : #include "libpq/pqformat.h"
73 : #include "mb/pg_wchar.h"
74 : #include "nodes/miscnodes.h"
75 : #include "miscadmin.h"
76 : #include "pgstat.h"
77 : #include "postmaster/bgworker.h"
78 : #include "postmaster/postmaster.h"
79 : #include "postmaster/syslogger.h"
80 : #include "storage/ipc.h"
81 : #include "storage/proc.h"
82 : #include "tcop/tcopprot.h"
83 : #include "utils/guc_hooks.h"
84 : #include "utils/memutils.h"
85 : #include "utils/ps_status.h"
86 : #include "utils/varlena.h"
87 :
88 :
89 : /* In this module, access gettext() via err_gettext() */
90 : #undef _
91 : #define _(x) err_gettext(x)
92 :
93 :
94 : /* Global variables */
95 : ErrorContextCallback *error_context_stack = NULL;
96 :
97 : sigjmp_buf *PG_exception_stack = NULL;
98 :
99 : extern bool redirection_done;
100 :
101 : /*
102 : * Hook for intercepting messages before they are sent to the server log.
103 : * Note that the hook will not get called for messages that are suppressed
104 : * by log_min_messages. Also note that logging hooks implemented in preload
105 : * libraries will miss any log messages that are generated before the
106 : * library is loaded.
107 : */
108 : emit_log_hook_type emit_log_hook = NULL;
109 :
110 : /* GUC parameters */
111 : int Log_error_verbosity = PGERROR_DEFAULT;
112 : char *Log_line_prefix = NULL; /* format for extra log line info */
113 : int Log_destination = LOG_DESTINATION_STDERR;
114 : char *Log_destination_string = NULL;
115 : bool syslog_sequence_numbers = true;
116 : bool syslog_split_messages = true;
117 :
118 : /* Processed form of backtrace_symbols GUC */
119 : static char *backtrace_symbol_list;
120 :
121 : #ifdef HAVE_SYSLOG
122 :
123 : /*
124 : * Max string length to send to syslog(). Note that this doesn't count the
125 : * sequence-number prefix we add, and of course it doesn't count the prefix
126 : * added by syslog itself. Solaris and sysklogd truncate the final message
127 : * at 1024 bytes, so this value leaves 124 bytes for those prefixes. (Most
128 : * other syslog implementations seem to have limits of 2KB or so.)
129 : */
130 : #ifndef PG_SYSLOG_LIMIT
131 : #define PG_SYSLOG_LIMIT 900
132 : #endif
133 :
134 : static bool openlog_done = false;
135 : static char *syslog_ident = NULL;
136 : static int syslog_facility = LOG_LOCAL0;
137 :
138 : static void write_syslog(int level, const char *line);
139 : #endif
140 :
141 : #ifdef WIN32
142 : extern char *event_source;
143 :
144 : static void write_eventlog(int level, const char *line, int len);
145 : #endif
146 :
147 : /* We provide a small stack of ErrorData records for re-entrant cases */
148 : #define ERRORDATA_STACK_SIZE 5
149 :
150 : static ErrorData errordata[ERRORDATA_STACK_SIZE];
151 :
152 : static int errordata_stack_depth = -1; /* index of topmost active frame */
153 :
154 : static int recursion_depth = 0; /* to detect actual recursion */
155 :
156 : /*
157 : * Saved timeval and buffers for formatted timestamps that might be used by
158 : * both log_line_prefix and csv logs.
159 : */
160 : static struct timeval saved_timeval;
161 : static bool saved_timeval_set = false;
162 :
163 : #define FORMATTED_TS_LEN 128
164 : static char formatted_start_time[FORMATTED_TS_LEN];
165 : static char formatted_log_time[FORMATTED_TS_LEN];
166 :
167 :
168 : /* Macro for checking errordata_stack_depth is reasonable */
169 : #define CHECK_STACK_DEPTH() \
170 : do { \
171 : if (errordata_stack_depth < 0) \
172 : { \
173 : errordata_stack_depth = -1; \
174 : ereport(ERROR, (errmsg_internal("errstart was not called"))); \
175 : } \
176 : } while (0)
177 :
178 :
179 : static const char *err_gettext(const char *str) pg_attribute_format_arg(1);
180 : static ErrorData *get_error_stack_entry(void);
181 : static void set_stack_entry_domain(ErrorData *edata, const char *domain);
182 : static void set_stack_entry_location(ErrorData *edata,
183 : const char *filename, int lineno,
184 : const char *funcname);
185 : static bool matches_backtrace_functions(const char *funcname);
186 : static pg_noinline void set_backtrace(ErrorData *edata, int num_skip);
187 : static void set_errdata_field(MemoryContextData *cxt, char **ptr, const char *str);
188 : static void FreeErrorDataContents(ErrorData *edata);
189 : static void write_console(const char *line, int len);
190 : static const char *process_log_prefix_padding(const char *p, int *ppadding);
191 : static void log_line_prefix(StringInfo buf, ErrorData *edata);
192 : static void send_message_to_server_log(ErrorData *edata);
193 : static void send_message_to_frontend(ErrorData *edata);
194 : static void append_with_tabs(StringInfo buf, const char *str);
195 :
196 :
197 : /*
198 : * is_log_level_output -- is elevel logically >= log_min_level?
199 : *
200 : * We use this for tests that should consider LOG to sort out-of-order,
201 : * between ERROR and FATAL. Generally this is the right thing for testing
202 : * whether a message should go to the postmaster log, whereas a simple >=
203 : * test is correct for testing whether the message should go to the client.
204 : */
205 : static inline bool
867 tgl 206 GIC 100682342 : is_log_level_output(int elevel, int log_min_level)
207 : {
208 100682342 : if (elevel == LOG || elevel == LOG_SERVER_ONLY)
209 : {
210 323431 : if (log_min_level == LOG || log_min_level <= ERROR)
211 323430 : return true;
212 : }
831 213 100358911 : else if (elevel == WARNING_CLIENT_ONLY)
214 : {
215 : /* never sent to log, regardless of log_min_level */
831 tgl 216 UIC 0 : return false;
217 : }
867 tgl 218 CBC 100358911 : else if (log_min_level == LOG)
219 : {
867 tgl 220 ECB : /* elevel != LOG */
867 tgl 221 UIC 0 : if (elevel >= FATAL)
867 tgl 222 LBC 0 : return true;
867 tgl 223 ECB : }
224 : /* Neither is LOG */
867 tgl 225 CBC 100358911 : else if (elevel >= log_min_level)
867 tgl 226 GIC 49540 : return true;
227 :
867 tgl 228 GBC 100309372 : return false;
229 : }
867 tgl 230 ECB :
231 : /*
232 : * Policy-setting subroutines. These are fairly simple, but it seems wise
867 tgl 233 EUB : * to have the code in just one place.
234 : */
235 :
236 : /*
867 tgl 237 ECB : * should_output_to_server --- should message of given elevel go to the log?
238 : */
239 : static inline bool
867 tgl 240 CBC 100494831 : should_output_to_server(int elevel)
241 : {
867 tgl 242 GIC 100494831 : return is_log_level_output(elevel, log_min_messages);
243 : }
244 :
245 : /*
246 : * should_output_to_client --- should message of given elevel go to the client?
247 : */
248 : static inline bool
249 100492384 : should_output_to_client(int elevel)
250 : {
251 100492384 : if (whereToSendOutput == DestRemote && elevel != LOG_SERVER_ONLY)
867 tgl 252 ECB : {
253 : /*
254 : * client_min_messages is honored only after we complete the
255 : * authentication handshake. This is required both for security
256 : * reasons and because many clients can't handle NOTICE messages
257 : * during authentication.
258 : */
867 tgl 259 GIC 919677 : if (ClientAuthInProgress)
260 30261 : return (elevel >= ERROR);
867 tgl 261 ECB : else
867 tgl 262 GIC 889416 : return (elevel >= client_min_messages || elevel == INFO);
867 tgl 263 ECB : }
867 tgl 264 GIC 99572707 : return false;
265 : }
266 :
267 :
268 : /*
269 : * message_level_is_interesting --- would ereport/elog do anything?
270 : *
867 tgl 271 ECB : * Returns true if ereport/elog with this elevel will not be a no-op.
272 : * This is useful to short-circuit any expensive preparatory work that
273 : * might be needed for a logging message. There is no point in
274 : * prepending this to a bare ereport/elog call, however.
275 : */
276 : bool
867 tgl 277 GIC 1090165 : message_level_is_interesting(int elevel)
278 : {
279 : /*
280 : * Keep this in sync with the decision-making in errstart().
281 : */
282 2180330 : if (elevel >= ERROR ||
283 2177883 : should_output_to_server(elevel) ||
284 1087718 : should_output_to_client(elevel))
285 3535 : return true;
286 1086630 : return false;
287 : }
288 :
5277 tgl 289 ECB :
290 : /*
291 : * in_error_recursion_trouble --- are we at risk of infinite error recursion?
292 : *
293 : * This function exists to provide common control of various fallback steps
294 : * that we take if we think we are facing infinite error recursion. See the
295 : * callers for details.
296 : */
297 : bool
5277 tgl 298 CBC 704543 : in_error_recursion_trouble(void)
299 : {
300 : /* Pull the plug if recurse more than once */
5277 tgl 301 GIC 704543 : return (recursion_depth > 2);
302 : }
303 :
304 : /*
305 : * One of those fallback steps is to stop trying to localize the error
306 : * message, since there's a significant probability that that's exactly
307 : * what's causing the recursion.
308 : */
309 : static inline const char *
5151 tgl 310 CBC 264171 : err_gettext(const char *str)
311 : {
312 : #ifdef ENABLE_NLS
313 264171 : if (in_error_recursion_trouble())
5151 tgl 314 GIC 2 : return str;
315 : else
316 264169 : return gettext(str);
317 : #else
318 : return str;
319 : #endif
320 : }
321 :
866 drowley 322 ECB : /*
323 : * errstart_cold
324 : * A simple wrapper around errstart, but hinted to be "cold". Supporting
325 : * compilers are more likely to move code for branches containing this
326 : * function into an area away from the calling function's code. This can
327 : * result in more commonly executed code being more compact and fitting
328 : * on fewer cache lines.
329 : */
330 : pg_attribute_cold bool
866 drowley 331 GIC 17840 : errstart_cold(int elevel, const char *domain)
332 : {
333 17840 : return errstart(elevel, domain);
334 : }
335 :
336 : /*
337 : * errstart --- begin an error-reporting cycle
338 : *
339 : * Create and initialize error stack entry. Subsequently, errmsg() and
340 : * perhaps other routines will be called to further populate the stack entry.
341 : * Finally, errfinish() will be called to actually process the error report.
342 : *
2062 peter_e 343 ECB : * Returns true in normal case. Returns false to short-circuit the error
344 : * report (if it's a warning or lower and not to be reported anywhere).
9770 scrappy 345 : */
346 : bool
1111 tgl 347 GIC 99404666 : errstart(int elevel, const char *domain)
348 : {
349 : ErrorData *edata;
350 : bool output_to_server;
7708 bruce 351 99404666 : bool output_to_client = false;
352 : int i;
353 :
354 : /*
355 : * Check some cases in which we want to promote an error into a more
356 : * severe error. None of this logic applies for non-error messages.
357 : */
7290 tgl 358 99404666 : if (elevel >= ERROR)
8115 tgl 359 ECB : {
360 : /*
361 : * If we are inside a critical section, all errors become PANIC
362 : * errors. See miscadmin.h.
6790 363 : */
8115 tgl 364 GIC 21315 : if (CritSectionCount > 0)
7290 tgl 365 UIC 0 : elevel = PANIC;
366 :
367 : /*
368 : * Check reasons for treating ERROR as FATAL:
369 : *
6790 tgl 370 ECB : * 1. we have no handler to pass the error to (implies we are in the
371 : * postmaster or in backend startup).
372 : *
373 : * 2. ExitOnAnyError mode switch is set (initdb uses this).
374 : *
375 : * 3. the error occurred after proc_exit has begun to run. (It's
376 : * proc_exit's responsibility to see that this doesn't turn into
6790 tgl 377 EUB : * infinite recursion!)
378 : */
6790 tgl 379 GIC 21315 : if (elevel == ERROR)
380 : {
381 21056 : if (PG_exception_stack == NULL ||
382 20906 : ExitOnAnyError ||
383 : proc_exit_inprogress)
384 150 : elevel = FATAL;
385 : }
386 :
387 : /*
388 : * If the error level is ERROR or more, errfinish is not going to
389 : * return to caller; therefore, if there is any stacked error already
390 : * in progress it will be lost. This is more or less okay, except we
6790 tgl 391 ECB : * do not want to have a FATAL or PANIC error downgraded because the
392 : * reporting process was interrupted by a lower-grade error. So check
393 : * the stack and make sure we panic if panic is warranted.
394 : */
6790 tgl 395 GIC 21316 : for (i = 0; i <= errordata_stack_depth; i++)
6790 tgl 396 CBC 1 : elevel = Max(elevel, errordata[i].elevel);
397 : }
398 :
399 : /*
400 : * Now decide whether we need to process this report at all; if it's
401 : * warning or less and not enabled for logging, just return false without
402 : * starting up any error logging machinery.
403 : */
867 tgl 404 GIC 99404666 : output_to_server = should_output_to_server(elevel);
405 99404666 : output_to_client = should_output_to_client(elevel);
7290 406 99404666 : if (elevel < ERROR && !output_to_server && !output_to_client)
7290 tgl 407 CBC 99205007 : return false;
8344 peter_e 408 ECB :
409 : /*
410 : * We need to do some actual work. Make sure that memory context
411 : * initialization has finished, else we can't do anything useful.
412 : */
3375 tgl 413 GIC 199659 : if (ErrorContext == NULL)
414 : {
415 : /* Oops, hard crash time; very little we can do safely here */
1111 tgl 416 LBC 0 : write_stderr("error occurred before error message processing is available\n");
3375 417 0 : exit(2);
3375 tgl 418 ECB : }
419 :
420 : /*
421 : * Okay, crank up a stack entry to store the info in.
422 : */
423 :
6790 tgl 424 GIC 199659 : if (recursion_depth++ > 0 && elevel >= ERROR)
7975 peter_e 425 ECB : {
426 : /*
427 : * Oops, error during error processing. Clear ErrorContext as
6790 tgl 428 EUB : * discussed at top of file. We will not return to the original
429 : * error's reporter or handler, so we don't need it.
430 : */
7290 tgl 431 UIC 0 : MemoryContextReset(ErrorContext);
432 :
433 : /*
434 : * Infinite error recursion might be due to something broken in a
435 : * context traceback routine. Abandon them too. We also abandon
5624 bruce 436 ECB : * attempting to print the error statement (which, if long, could
437 : * itself be the source of the recursive failure).
438 : */
5277 tgl 439 UIC 0 : if (in_error_recursion_trouble())
440 : {
7290 441 0 : error_context_stack = NULL;
5741 442 0 : debug_query_string = NULL;
5741 tgl 443 EUB : }
444 : }
445 :
446 : /* Initialize data for this error frame */
123 tgl 447 GNC 199659 : edata = get_error_stack_entry();
7290 tgl 448 CBC 199659 : edata->elevel = elevel;
449 199659 : edata->output_to_server = output_to_server;
450 199659 : edata->output_to_client = output_to_client;
123 tgl 451 GNC 199659 : set_stack_entry_domain(edata, domain);
7205 tgl 452 ECB : /* Select default errcode based on elevel */
7205 tgl 453 CBC 199659 : if (elevel >= ERROR)
454 21315 : edata->sqlerrcode = ERRCODE_INTERNAL_ERROR;
831 tgl 455 GIC 178344 : else if (elevel >= WARNING)
7205 tgl 456 CBC 1411 : edata->sqlerrcode = ERRCODE_WARNING;
457 : else
7205 tgl 458 GIC 176933 : edata->sqlerrcode = ERRCODE_SUCCESSFUL_COMPLETION;
7290 tgl 459 ECB :
460 : /*
3538 sfrost 461 : * Any allocations for this error state level should go into ErrorContext
462 : */
3538 sfrost 463 GIC 199659 : edata->assoc_context = ErrorContext;
464 :
7290 tgl 465 199659 : recursion_depth--;
466 199659 : return true;
467 : }
468 :
469 : /*
7290 tgl 470 ECB : * errfinish --- end an error-reporting cycle
471 : *
472 : * Produce the appropriate error report(s) and pop the error stack.
473 : *
1111 tgl 474 EUB : * If elevel, as passed to errstart(), is ERROR or worse, control does not
475 : * return to the caller. See elog.h for the error level definitions.
476 : */
477 : void
1111 tgl 478 GIC 199659 : errfinish(const char *filename, int lineno, const char *funcname)
479 : {
7290 480 199659 : ErrorData *edata = &errordata[errordata_stack_depth];
3415 rhaas 481 ECB : int elevel;
7290 tgl 482 : MemoryContext oldcontext;
483 : ErrorContextCallback *econtext;
8344 peter_e 484 :
7189 tgl 485 GIC 199659 : recursion_depth++;
7290 486 199659 : CHECK_STACK_DEPTH();
487 :
488 : /* Save the last few bits of error state into the stack entry */
123 tgl 489 GNC 199659 : set_stack_entry_location(edata, filename, lineno, funcname);
490 :
3415 rhaas 491 GIC 199659 : elevel = edata->elevel;
492 :
493 : /*
494 : * Do processing in ErrorContext, which we hope has enough reserved space
495 : * to report an error.
7189 tgl 496 ECB : */
7189 tgl 497 CBC 199659 : oldcontext = MemoryContextSwitchTo(ErrorContext);
498 :
499 : /* Collect backtrace, if enabled and we didn't already */
1248 alvherre 500 GIC 199659 : if (!edata->backtrace &&
501 199659 : edata->funcname &&
1248 alvherre 502 CBC 199659 : backtrace_functions &&
1248 alvherre 503 GIC 199659 : matches_backtrace_functions(edata->funcname))
1248 alvherre 504 UIC 0 : set_backtrace(edata, 2);
1248 alvherre 505 ECB :
7189 tgl 506 : /*
507 : * Call any context callback functions. Errors occurring in callback
508 : * functions will be treated as recursive errors --- this ensures we will
6385 bruce 509 : * avoid infinite recursion (see errstart).
7290 tgl 510 : */
7290 tgl 511 GIC 199659 : for (econtext = error_context_stack;
512 221787 : econtext != NULL;
513 22128 : econtext = econtext->previous)
2040 peter_e 514 22128 : econtext->callback(econtext->arg);
8456 bruce 515 ECB :
516 : /*
517 : * If ERROR (not more nor less) we pass it off to the current handler.
518 : * Printing it and popping the stack is the responsibility of the handler.
519 : */
6790 tgl 520 GIC 199659 : if (elevel == ERROR)
521 : {
522 : /*
6385 bruce 523 ECB : * We do some minimal cleanup before longjmp'ing so that handlers can
524 : * execute in a reasonably sane state.
525 : *
526 : * Reset InterruptHoldoffCount in case we ereport'd from inside an
527 : * interrupt holdoff section. (We assume here that no handler will
528 : * itself be inside a holdoff section. If necessary, such a handler
529 : * could save and restore InterruptHoldoffCount for itself, but this
530 : * should make life easier for most.)
531 : */
6790 tgl 532 CBC 20906 : InterruptHoldoffCount = 0;
2988 heikki.linnakangas 533 GIC 20906 : QueryCancelHoldoffCount = 0;
534 :
6385 bruce 535 20906 : CritSectionCount = 0; /* should be unnecessary, but... */
536 :
537 : /*
6385 bruce 538 ECB : * Note that we leave CurrentMemoryContext set to ErrorContext. The
539 : * handler should reset it to something else soon.
540 : */
541 :
6790 tgl 542 GIC 20906 : recursion_depth--;
543 20906 : PG_RE_THROW();
544 : }
545 :
6826 tgl 546 ECB : /* Emit the message to the right places */
6826 tgl 547 GIC 178753 : EmitErrorReport();
548 :
7290 tgl 549 ECB : /* Now free up subsidiary data attached to stack entry, and release it */
123 tgl 550 GNC 178753 : FreeErrorDataContents(edata);
7290 tgl 551 GIC 178753 : errordata_stack_depth--;
552 :
553 : /* Exit error-handling context */
6826 554 178753 : MemoryContextSwitchTo(oldcontext);
7290 555 178753 : recursion_depth--;
556 :
557 : /*
558 : * Perform error recovery action as specified by elevel.
559 : */
6826 560 178753 : if (elevel == FATAL)
561 : {
562 : /*
563 : * For a FATAL error, we let proc_exit clean up and exit.
564 : *
6385 bruce 565 ECB : * If we just reported a startup failure, the client will disconnect
566 : * on receiving it, so don't send any more to the client.
567 : */
6366 alvherre 568 GIC 409 : if (PG_exception_stack == NULL && whereToSendOutput == DestRemote)
569 81 : whereToSendOutput = DestNone;
570 :
571 : /*
572 : * fflush here is just to improve the odds that we get to see the
573 : * error message, in case things are so hosed that proc_exit crashes.
6385 bruce 574 ECB : * Any other code you might be tempted to add here should probably be
5983 tgl 575 : * in an on_proc_exit or on_shmem_exit callback instead.
576 : */
223 tgl 577 GNC 409 : fflush(NULL);
8397 bruce 578 ECB :
579 : /*
580 : * Let the cumulative stats system know. Only mark the session as
812 magnus 581 : * terminated by fatal error if there is no other known cause.
582 : */
812 magnus 583 GIC 409 : if (pgStatSessionEndCause == DISCONNECT_NORMAL)
584 333 : pgStatSessionEndCause = DISCONNECT_FATAL;
585 :
586 : /*
587 : * Do normal process-exit cleanup, then return exit code 1 to indicate
5983 tgl 588 ECB : * FATAL termination. The postmaster may or may not consider this
589 : * worthy of panic, depending on which subprocess returns it.
590 : */
5983 tgl 591 CBC 409 : proc_exit(1);
9345 bruce 592 ECB : }
593 :
7290 tgl 594 GIC 178344 : if (elevel >= PANIC)
9345 bruce 595 ECB : {
596 : /*
597 : * Serious crash time. Postmaster will observe SIGABRT process exit
598 : * status and kill the other backends too.
599 : *
600 : * XXX: what if we are *in* the postmaster? abort() won't kill our
601 : * children...
8611 tgl 602 : */
223 tgl 603 UNC 0 : fflush(NULL);
7464 tgl 604 LBC 0 : abort();
605 : }
606 :
607 : /*
608 : * Check for cancel/die interrupt first --- this is so that the user can
609 : * stop a query emitting tons of notice or warning messages, even if it's
610 : * in a loop that otherwise fails to check for interrupts.
611 : */
6034 tgl 612 GIC 178344 : CHECK_FOR_INTERRUPTS();
7290 613 178344 : }
614 :
121 tgl 615 ECB :
616 : /*
617 : * errsave_start --- begin a "soft" error-reporting cycle
618 : *
619 : * If "context" isn't an ErrorSaveContext node, this behaves as
620 : * errstart(ERROR, domain), and the errsave() macro ends up acting
621 : * exactly like ereport(ERROR, ...).
622 : *
623 : * If "context" is an ErrorSaveContext node, but the node creator only wants
624 : * notification of the fact of a soft error without any details, we just set
625 : * the error_occurred flag in the ErrorSaveContext node and return false,
626 : * which will cause us to skip the remaining error processing steps.
627 : *
628 : * Otherwise, create and initialize error stack entry and return true.
629 : * Subsequently, errmsg() and perhaps other routines will be called to further
630 : * populate the stack entry. Finally, errsave_finish() will be called to
631 : * tidy up.
632 : */
633 : bool
121 tgl 634 GNC 11440 : errsave_start(struct Node *context, const char *domain)
635 : {
636 : ErrorSaveContext *escontext;
637 : ErrorData *edata;
638 :
639 : /*
640 : * Do we have a context for soft error reporting? If not, just punt to
641 : * errstart().
642 : */
643 11440 : if (context == NULL || !IsA(context, ErrorSaveContext))
644 2502 : return errstart(ERROR, domain);
645 :
646 : /* Report that a soft error was detected */
647 8938 : escontext = (ErrorSaveContext *) context;
648 8938 : escontext->error_occurred = true;
649 :
650 : /* Nothing else to do if caller wants no further details */
651 8938 : if (!escontext->details_wanted)
652 8583 : return false;
653 :
654 : /*
655 : * Okay, crank up a stack entry to store the info in.
656 : */
657 :
658 355 : recursion_depth++;
659 :
660 : /* Initialize data for this error frame */
661 355 : edata = get_error_stack_entry();
662 355 : edata->elevel = LOG; /* signal all is well to errsave_finish */
663 355 : set_stack_entry_domain(edata, domain);
664 : /* Select default errcode based on the assumed elevel of ERROR */
665 355 : edata->sqlerrcode = ERRCODE_INTERNAL_ERROR;
666 :
667 : /*
668 : * Any allocations for this error state level should go into the caller's
669 : * context. We don't need to pollute ErrorContext, or even require it to
670 : * exist, in this code path.
671 : */
672 355 : edata->assoc_context = CurrentMemoryContext;
673 :
674 355 : recursion_depth--;
675 355 : return true;
676 : }
677 :
678 : /*
679 : * errsave_finish --- end a "soft" error-reporting cycle
680 : *
681 : * If errsave_start() decided this was a regular error, behave as
682 : * errfinish(). Otherwise, package up the error details and save
683 : * them in the ErrorSaveContext node.
684 : */
685 : void
686 2857 : errsave_finish(struct Node *context, const char *filename, int lineno,
687 : const char *funcname)
688 : {
689 2857 : ErrorSaveContext *escontext = (ErrorSaveContext *) context;
690 2857 : ErrorData *edata = &errordata[errordata_stack_depth];
691 :
692 : /* verify stack depth before accessing *edata */
693 2857 : CHECK_STACK_DEPTH();
694 :
695 : /*
696 : * If errsave_start punted to errstart, then elevel will be ERROR or
697 : * perhaps even PANIC. Punt likewise to errfinish.
698 : */
699 2857 : if (edata->elevel >= ERROR)
700 : {
701 2502 : errfinish(filename, lineno, funcname);
121 tgl 702 UNC 0 : pg_unreachable();
703 : }
704 :
705 : /*
706 : * Else, we should package up the stack entry contents and deliver them to
707 : * the caller.
708 : */
121 tgl 709 GNC 355 : recursion_depth++;
710 :
711 : /* Save the last few bits of error state into the stack entry */
712 355 : set_stack_entry_location(edata, filename, lineno, funcname);
713 :
714 : /* Replace the LOG value that errsave_start inserted */
715 355 : edata->elevel = ERROR;
716 :
717 : /*
718 : * We skip calling backtrace and context functions, which are more likely
719 : * to cause trouble than provide useful context; they might act on the
720 : * assumption that a transaction abort is about to occur.
721 : */
722 :
723 : /*
724 : * Make a copy of the error info for the caller. All the subsidiary
725 : * strings are already in the caller's context, so it's sufficient to
726 : * flat-copy the stack entry.
727 : */
728 355 : escontext->error_data = palloc_object(ErrorData);
729 355 : memcpy(escontext->error_data, edata, sizeof(ErrorData));
730 :
731 : /* Exit error-handling context */
732 355 : errordata_stack_depth--;
733 355 : recursion_depth--;
734 355 : }
735 :
736 :
737 : /*
738 : * get_error_stack_entry --- allocate and initialize a new stack entry
739 : *
740 : * The entry should be freed, when we're done with it, by calling
741 : * FreeErrorDataContents() and then decrementing errordata_stack_depth.
742 : *
743 : * Returning the entry's address is just a notational convenience,
744 : * since it had better be errordata[errordata_stack_depth].
745 : *
746 : * Although the error stack is not large, we don't expect to run out of space.
747 : * Using more than one entry implies a new error report during error recovery,
748 : * which is possible but already suggests we're in trouble. If we exhaust the
749 : * stack, almost certainly we are in an infinite loop of errors during error
750 : * recovery, so we give up and PANIC.
751 : *
752 : * (Note that this is distinct from the recursion_depth checks, which
753 : * guard against recursion while handling a single stack entry.)
754 : */
755 : static ErrorData *
123 756 200070 : get_error_stack_entry(void)
757 : {
758 : ErrorData *edata;
759 :
760 : /* Allocate error frame */
761 200070 : errordata_stack_depth++;
762 200070 : if (unlikely(errordata_stack_depth >= ERRORDATA_STACK_SIZE))
763 : {
764 : /* Wups, stack not big enough */
123 tgl 765 UNC 0 : errordata_stack_depth = -1; /* make room on stack */
766 0 : ereport(PANIC, (errmsg_internal("ERRORDATA_STACK_SIZE exceeded")));
767 : }
768 :
769 : /* Initialize error frame to all zeroes/NULLs */
123 tgl 770 GNC 200070 : edata = &errordata[errordata_stack_depth];
771 200070 : memset(edata, 0, sizeof(ErrorData));
772 :
773 : /* Save errno immediately to ensure error parameter eval can't change it */
774 200070 : edata->saved_errno = errno;
775 :
776 200070 : return edata;
777 : }
778 :
779 : /*
780 : * set_stack_entry_domain --- fill in the internationalization domain
781 : */
782 : static void
783 200014 : set_stack_entry_domain(ErrorData *edata, const char *domain)
784 : {
785 : /* the default text domain is the backend's */
786 200014 : edata->domain = domain ? domain : PG_TEXTDOMAIN("postgres");
787 : /* initialize context_domain the same way (see set_errcontext_domain()) */
788 200014 : edata->context_domain = edata->domain;
789 200014 : }
790 :
791 : /*
792 : * set_stack_entry_location --- fill in code-location details
793 : *
794 : * Store the values of __FILE__, __LINE__, and __func__ from the call site.
795 : * We make an effort to normalize __FILE__, since compilers are inconsistent
796 : * about how much of the path they'll include, and we'd prefer that the
797 : * behavior not depend on that (especially, that it not vary with build path).
798 : */
799 : static void
800 200014 : set_stack_entry_location(ErrorData *edata,
801 : const char *filename, int lineno,
802 : const char *funcname)
803 : {
804 200014 : if (filename)
805 : {
806 : const char *slash;
807 :
808 : /* keep only base name, useful especially for vpath builds */
809 200014 : slash = strrchr(filename, '/');
810 200014 : if (slash)
811 200009 : filename = slash + 1;
812 : /* Some Windows compilers use backslashes in __FILE__ strings */
813 200014 : slash = strrchr(filename, '\\');
814 200014 : if (slash)
123 tgl 815 UNC 0 : filename = slash + 1;
816 : }
817 :
123 tgl 818 GNC 200014 : edata->filename = filename;
819 200014 : edata->lineno = lineno;
820 200014 : edata->funcname = funcname;
821 200014 : }
822 :
823 : /*
824 : * matches_backtrace_functions --- checks whether the given funcname matches
825 : * backtrace_functions
826 : *
827 : * See check_backtrace_functions.
828 : */
829 : static bool
830 199659 : matches_backtrace_functions(const char *funcname)
831 : {
832 : const char *p;
833 :
834 199659 : if (!backtrace_symbol_list || funcname == NULL || funcname[0] == '\0')
835 199659 : return false;
836 :
123 tgl 837 UNC 0 : p = backtrace_symbol_list;
838 : for (;;)
839 : {
840 0 : if (*p == '\0') /* end of backtrace_symbol_list */
841 0 : break;
842 :
843 0 : if (strcmp(funcname, p) == 0)
844 0 : return true;
845 0 : p += strlen(p) + 1;
846 : }
847 :
848 0 : return false;
849 : }
850 :
851 :
852 : /*
853 : * errcode --- add SQLSTATE error code to the current error
7290 tgl 854 ECB : *
855 : * The code is expected to be represented as per MAKE_SQLSTATE().
856 : */
857 : int
7290 tgl 858 CBC 22682 : errcode(int sqlerrcode)
859 : {
7290 tgl 860 GIC 22682 : ErrorData *edata = &errordata[errordata_stack_depth];
861 :
862 : /* we don't bother incrementing recursion_depth */
863 22682 : CHECK_STACK_DEPTH();
7290 tgl 864 ECB :
7290 tgl 865 GIC 22682 : edata->sqlerrcode = sqlerrcode;
1110 tgl 866 ECB :
1110 tgl 867 GBC 22682 : return 0; /* return value does not matter */
868 : }
869 :
870 :
871 : /*
872 : * errcode_for_file_access --- add SQLSTATE error code to the current error
873 : *
3260 bruce 874 ECB : * The SQLSTATE code is chosen based on the saved errno value. We assume
875 : * that the failing operation was some type of disk file access.
876 : *
7205 tgl 877 : * NOTE: the primary error message string should generally include %m
878 : * when this is used.
879 : */
1110 880 : int
7205 tgl 881 GIC 65 : errcode_for_file_access(void)
882 : {
883 65 : ErrorData *edata = &errordata[errordata_stack_depth];
884 :
885 : /* we don't bother incrementing recursion_depth */
886 65 : CHECK_STACK_DEPTH();
887 :
888 65 : switch (edata->saved_errno)
889 : {
890 : /* Permission-denied failures */
7205 tgl 891 UIC 0 : case EPERM: /* Not super-user */
892 : case EACCES: /* Permission denied */
7205 tgl 893 ECB : #ifdef EROFS
894 : case EROFS: /* Read only file system */
895 : #endif
7205 tgl 896 UIC 0 : edata->sqlerrcode = ERRCODE_INSUFFICIENT_PRIVILEGE;
7205 tgl 897 LBC 0 : break;
7205 tgl 898 ECB :
7166 899 : /* File not found */
7205 tgl 900 GIC 62 : case ENOENT: /* No such file or directory */
7166 901 62 : edata->sqlerrcode = ERRCODE_UNDEFINED_FILE;
7205 902 62 : break;
903 :
904 : /* Duplicate file */
7205 tgl 905 UIC 0 : case EEXIST: /* File exists */
7166 906 0 : edata->sqlerrcode = ERRCODE_DUPLICATE_FILE;
7205 907 0 : break;
908 :
909 : /* Wrong object type or state */
7205 tgl 910 GIC 2 : case ENOTDIR: /* Not a directory */
911 : case EISDIR: /* Is a directory */
912 : #if defined(ENOTEMPTY) && (ENOTEMPTY != EEXIST) /* same code on AIX */
913 : case ENOTEMPTY: /* Directory not empty */
914 : #endif
915 2 : edata->sqlerrcode = ERRCODE_WRONG_OBJECT_TYPE;
916 2 : break;
917 :
918 : /* Insufficient resources */
7205 tgl 919 UIC 0 : case ENOSPC: /* No space left on device */
920 0 : edata->sqlerrcode = ERRCODE_DISK_FULL;
7205 tgl 921 LBC 0 : break;
922 :
7205 tgl 923 UIC 0 : case ENFILE: /* File table overflow */
924 : case EMFILE: /* Too many open files */
925 0 : edata->sqlerrcode = ERRCODE_INSUFFICIENT_RESOURCES;
7205 tgl 926 LBC 0 : break;
7205 tgl 927 ECB :
928 : /* Hardware failure */
7205 tgl 929 UIC 0 : case EIO: /* I/O error */
7205 tgl 930 UBC 0 : edata->sqlerrcode = ERRCODE_IO_ERROR;
931 0 : break;
932 :
933 : /* All else is classified as internal errors */
7205 tgl 934 GIC 1 : default:
7205 tgl 935 CBC 1 : edata->sqlerrcode = ERRCODE_INTERNAL_ERROR;
936 1 : break;
937 : }
938 :
1110 939 65 : return 0; /* return value does not matter */
940 : }
7205 tgl 941 ECB :
942 : /*
943 : * errcode_for_socket_access --- add SQLSTATE error code to the current error
944 : *
945 : * The SQLSTATE code is chosen based on the saved errno value. We assume
946 : * that the failing operation was some type of socket access.
947 : *
7201 948 : * NOTE: the primary error message string should generally include %m
949 : * when this is used.
950 : */
1110 951 : int
7201 tgl 952 GIC 42 : errcode_for_socket_access(void)
7201 tgl 953 ECB : {
7201 tgl 954 CBC 42 : ErrorData *edata = &errordata[errordata_stack_depth];
955 :
956 : /* we don't bother incrementing recursion_depth */
7201 tgl 957 GIC 42 : CHECK_STACK_DEPTH();
958 :
959 42 : switch (edata->saved_errno)
960 : {
961 : /* Loss of connection */
911 962 38 : case ALL_CONNECTION_FAILURE_ERRNOS:
7201 963 38 : edata->sqlerrcode = ERRCODE_CONNECTION_FAILURE;
964 38 : break;
7201 tgl 965 ECB :
966 : /* All else is classified as internal errors */
7201 tgl 967 GIC 4 : default:
968 4 : edata->sqlerrcode = ERRCODE_INTERNAL_ERROR;
7201 tgl 969 CBC 4 : break;
970 : }
971 :
1110 tgl 972 GIC 42 : return 0; /* return value does not matter */
973 : }
7201 tgl 974 ECB :
7205 975 :
7290 976 : /*
977 : * This macro handles expansion of a format string and associated parameters;
978 : * it's common code for errmsg(), errdetail(), etc. Must be called inside
979 : * a routine that is declared like "const char *fmt, ..." and has an edata
3260 bruce 980 EUB : * pointer set up. The message is assigned to edata->targetfield, or
981 : * appended to it if appendval is true. The message is subject to translation
982 : * if translateit is true.
7290 tgl 983 ECB : *
984 : * Note: we pstrdup the buffer rather than just transferring its storage
985 : * to the edata field because the buffer might be considerably larger than
986 : * really necessary.
987 : */
988 : #define EVALUATE_MESSAGE(domain, targetfield, appendval, translateit) \
989 : { \
990 : StringInfoData buf; \
991 : /* Internationalize the error format string */ \
992 : if ((translateit) && !in_error_recursion_trouble()) \
993 : fmt = dgettext((domain), fmt); \
994 : initStringInfo(&buf); \
4539 995 : if ((appendval) && edata->targetfield) { \
996 : appendStringInfoString(&buf, edata->targetfield); \
997 : appendStringInfoChar(&buf, '\n'); \
998 : } \
7290 999 : /* Generate actual output --- have to use appendStringInfoVA */ \
1000 : for (;;) \
1001 : { \
7290 tgl 1002 EUB : va_list args; \
1003 : int needed; \
1004 : errno = edata->saved_errno; \
1005 : va_start(args, fmt); \
1656 1006 : needed = appendStringInfoVA(&buf, fmt, args); \
1007 : va_end(args); \
3454 1008 : if (needed == 0) \
7290 1009 : break; \
3454 1010 : enlargeStringInfo(&buf, needed); \
1011 : } \
1012 : /* Save the completed message into the stack item */ \
7290 1013 : if (edata->targetfield) \
1014 : pfree(edata->targetfield); \
1015 : edata->targetfield = pstrdup(buf.data); \
1016 : pfree(buf.data); \
1017 : }
1018 :
1019 : /*
1020 : * Same as above, except for pluralized error messages. The calling routine
1021 : * must be declared like "const char *fmt_singular, const char *fmt_plural,
1022 : * unsigned long n, ...". Translation is assumed always wanted.
5057 tgl 1023 ECB : */
1024 : #define EVALUATE_MESSAGE_PLURAL(domain, targetfield, appendval) \
1025 : { \
1026 : const char *fmt; \
1027 : StringInfoData buf; \
1028 : /* Internationalize the error format string */ \
1029 : if (!in_error_recursion_trouble()) \
3602 bruce 1030 : fmt = dngettext((domain), fmt_singular, fmt_plural, n); \
1031 : else \
5057 tgl 1032 : fmt = (n == 1 ? fmt_singular : fmt_plural); \
1033 : initStringInfo(&buf); \
1034 : if ((appendval) && edata->targetfield) { \
1035 : appendStringInfoString(&buf, edata->targetfield); \
1036 : appendStringInfoChar(&buf, '\n'); \
1037 : } \
1038 : /* Generate actual output --- have to use appendStringInfoVA */ \
1039 : for (;;) \
1040 : { \
1041 : va_list args; \
1042 : int needed; \
1043 : errno = edata->saved_errno; \
1044 : va_start(args, n); \
1045 : needed = appendStringInfoVA(&buf, fmt, args); \
1046 : va_end(args); \
1047 : if (needed == 0) \
1048 : break; \
1049 : enlargeStringInfo(&buf, needed); \
1050 : } \
1051 : /* Save the completed message into the stack item */ \
1052 : if (edata->targetfield) \
1053 : pfree(edata->targetfield); \
1054 : edata->targetfield = pstrdup(buf.data); \
1055 : pfree(buf.data); \
5057 tgl 1056 EUB : }
1057 :
1058 :
1059 : /*
1060 : * errmsg --- add a primary error message text to the current error
7290 1061 : *
1062 : * In addition to the usual %-escapes recognized by printf, "%m" in
1063 : * fmt is replaced by the error message for the caller's value of errno.
1064 : *
7290 tgl 1065 ECB : * Note: no newline is needed at the end of the fmt string, since
1066 : * ereport will provide one for the output methods that need it.
1067 : */
1068 : int
7188 bruce 1069 GIC 184338 : errmsg(const char *fmt,...)
7290 tgl 1070 EUB : {
7290 tgl 1071 GBC 184338 : ErrorData *edata = &errordata[errordata_stack_depth];
7290 tgl 1072 EUB : MemoryContext oldcontext;
1073 :
7290 tgl 1074 GIC 184338 : recursion_depth++;
7290 tgl 1075 CBC 184338 : CHECK_STACK_DEPTH();
3538 sfrost 1076 GIC 184338 : oldcontext = MemoryContextSwitchTo(edata->assoc_context);
1077 :
2585 simon 1078 184338 : edata->message_id = fmt;
3800 heikki.linnakangas 1079 185413 : EVALUATE_MESSAGE(edata->domain, message, false, true);
7290 tgl 1080 ECB :
7290 tgl 1081 CBC 184338 : MemoryContextSwitchTo(oldcontext);
7290 tgl 1082 GIC 184338 : recursion_depth--;
1110 1083 184338 : return 0; /* return value does not matter */
7290 tgl 1084 EUB : }
1085 :
1248 alvherre 1086 : /*
1087 : * Add a backtrace to the containing ereport() call. This is intended to be
1088 : * added temporarily during debugging.
1089 : */
1110 tgl 1090 : int
1248 alvherre 1091 UBC 0 : errbacktrace(void)
1092 : {
1060 tgl 1093 UIC 0 : ErrorData *edata = &errordata[errordata_stack_depth];
1248 alvherre 1094 EUB : MemoryContext oldcontext;
1095 :
1248 alvherre 1096 UBC 0 : recursion_depth++;
1248 alvherre 1097 UIC 0 : CHECK_STACK_DEPTH();
1098 0 : oldcontext = MemoryContextSwitchTo(edata->assoc_context);
1248 alvherre 1099 ECB :
1248 alvherre 1100 LBC 0 : set_backtrace(edata, 1);
1248 alvherre 1101 ECB :
1248 alvherre 1102 UIC 0 : MemoryContextSwitchTo(oldcontext);
1103 0 : recursion_depth--;
1110 tgl 1104 ECB :
1110 tgl 1105 UIC 0 : return 0;
1106 : }
1107 :
1108 : /*
1109 : * Compute backtrace data and add it to the supplied ErrorData. num_skip
1110 : * specifies how many inner frames to skip. Use this to avoid showing the
1111 : * internal backtrace support functions in the backtrace. This requires that
1112 : * this and related functions are not inlined.
1113 : */
1114 : static void
1248 alvherre 1115 0 : set_backtrace(ErrorData *edata, int num_skip)
1116 : {
1248 alvherre 1117 ECB : StringInfoData errtrace;
1118 :
1248 alvherre 1119 LBC 0 : initStringInfo(&errtrace);
1120 :
1121 : #ifdef HAVE_BACKTRACE_SYMBOLS
1248 alvherre 1122 ECB : {
1123 : void *buf[100];
1124 : int nframes;
1125 : char **strfrms;
1126 :
1248 alvherre 1127 LBC 0 : nframes = backtrace(buf, lengthof(buf));
1128 0 : strfrms = backtrace_symbols(buf, nframes);
1129 0 : if (strfrms == NULL)
1248 alvherre 1130 UIC 0 : return;
1131 :
1248 alvherre 1132 LBC 0 : for (int i = num_skip; i < nframes; i++)
1133 0 : appendStringInfo(&errtrace, "\n%s", strfrms[i]);
1134 0 : free(strfrms);
1135 : }
1136 : #else
1248 alvherre 1137 ECB : appendStringInfoString(&errtrace,
1138 : "backtrace generation is not supported by this installation");
1139 : #endif
1140 :
1248 alvherre 1141 UIC 0 : edata->backtrace = errtrace.data;
1142 : }
1143 :
1144 : /*
1145 : * errmsg_internal --- add a primary error message text to the current error
1146 : *
1147 : * This is exactly like errmsg() except that strings passed to errmsg_internal
1148 : * are not translated, and are customarily left out of the
1149 : * internationalization message dictionary. This should be used for "can't
1150 : * happen" cases that are probably not worth spending translation effort on.
1151 : * We also use this for certain cases where we *must* not try to translate
1152 : * the message because the translation would fail and result in infinite
1153 : * error recursion.
1154 : */
1155 : int
7188 bruce 1156 GIC 15314 : errmsg_internal(const char *fmt,...)
1157 : {
7290 tgl 1158 15314 : ErrorData *edata = &errordata[errordata_stack_depth];
1159 : MemoryContext oldcontext;
1160 :
1161 15314 : recursion_depth++;
1162 15314 : CHECK_STACK_DEPTH();
3538 sfrost 1163 15314 : oldcontext = MemoryContextSwitchTo(edata->assoc_context);
1164 :
2585 simon 1165 15314 : edata->message_id = fmt;
3800 heikki.linnakangas 1166 15320 : EVALUATE_MESSAGE(edata->domain, message, false, false);
1167 :
7290 tgl 1168 15314 : MemoryContextSwitchTo(oldcontext);
1169 15314 : recursion_depth--;
1110 1170 15314 : return 0; /* return value does not matter */
1171 : }
1172 :
1173 :
1174 : /*
1175 : * errmsg_plural --- add a primary error message text to the current error,
1176 : * with support for pluralization of the message text
1177 : */
1178 : int
5057 1179 359 : errmsg_plural(const char *fmt_singular, const char *fmt_plural,
1180 : unsigned long n,...)
1181 : {
1182 359 : ErrorData *edata = &errordata[errordata_stack_depth];
1183 : MemoryContext oldcontext;
1184 :
1185 359 : recursion_depth++;
1186 359 : CHECK_STACK_DEPTH();
3538 sfrost 1187 359 : oldcontext = MemoryContextSwitchTo(edata->assoc_context);
1188 :
2585 simon 1189 359 : edata->message_id = fmt_singular;
3800 heikki.linnakangas 1190 359 : EVALUATE_MESSAGE_PLURAL(edata->domain, message, false);
1191 :
5057 tgl 1192 359 : MemoryContextSwitchTo(oldcontext);
1193 359 : recursion_depth--;
1110 1194 359 : return 0; /* return value does not matter */
1195 : }
1196 :
1197 :
1198 : /*
1199 : * errdetail --- add a detail error message text to the current error
1200 : */
1201 : int
7188 bruce 1202 11147 : errdetail(const char *fmt,...)
1203 : {
7290 tgl 1204 11147 : ErrorData *edata = &errordata[errordata_stack_depth];
1205 : MemoryContext oldcontext;
1206 :
1207 11147 : recursion_depth++;
1208 11147 : CHECK_STACK_DEPTH();
3538 sfrost 1209 11147 : oldcontext = MemoryContextSwitchTo(edata->assoc_context);
1210 :
3800 heikki.linnakangas 1211 11153 : EVALUATE_MESSAGE(edata->domain, detail, false, true);
1212 :
7290 tgl 1213 11147 : MemoryContextSwitchTo(oldcontext);
1214 11147 : recursion_depth--;
1110 1215 11147 : return 0; /* return value does not matter */
1216 : }
1217 :
1218 :
1219 : /*
1220 : * errdetail_internal --- add a detail error message text to the current error
1221 : *
1222 : * This is exactly like errdetail() except that strings passed to
1223 : * errdetail_internal are not translated, and are customarily left out of the
1224 : * internationalization message dictionary. This should be used for detail
1225 : * messages that seem not worth translating for one reason or another
1226 : * (typically, that they don't seem to be useful to average users).
1227 : */
1228 : int
4285 1229 1411 : errdetail_internal(const char *fmt,...)
1230 : {
1231 1411 : ErrorData *edata = &errordata[errordata_stack_depth];
1232 : MemoryContext oldcontext;
1233 :
4285 tgl 1234 CBC 1411 : recursion_depth++;
4285 tgl 1235 GIC 1411 : CHECK_STACK_DEPTH();
3538 sfrost 1236 CBC 1411 : oldcontext = MemoryContextSwitchTo(edata->assoc_context);
1237 :
3800 heikki.linnakangas 1238 GIC 1420 : EVALUATE_MESSAGE(edata->domain, detail, false, false);
4285 tgl 1239 ECB :
4285 tgl 1240 CBC 1411 : MemoryContextSwitchTo(oldcontext);
1241 1411 : recursion_depth--;
1110 tgl 1242 GIC 1411 : return 0; /* return value does not matter */
4285 tgl 1243 ECB : }
1244 :
1245 :
5494 1246 : /*
1247 : * errdetail_log --- add a detail_log error message text to the current error
1248 : */
1249 : int
5494 tgl 1250 GIC 559 : errdetail_log(const char *fmt,...)
1251 : {
1252 559 : ErrorData *edata = &errordata[errordata_stack_depth];
1253 : MemoryContext oldcontext;
1254 :
1255 559 : recursion_depth++;
5494 tgl 1256 GBC 559 : CHECK_STACK_DEPTH();
3538 sfrost 1257 GIC 559 : oldcontext = MemoryContextSwitchTo(edata->assoc_context);
5494 tgl 1258 EUB :
3800 heikki.linnakangas 1259 GIC 569 : EVALUATE_MESSAGE(edata->domain, detail_log, false, true);
1260 :
5494 tgl 1261 GBC 559 : MemoryContextSwitchTo(oldcontext);
1262 559 : recursion_depth--;
1110 1263 559 : return 0; /* return value does not matter */
1264 : }
5494 tgl 1265 EUB :
1266 : /*
3314 fujii 1267 : * errdetail_log_plural --- add a detail_log error message text to the current error
1268 : * with support for pluralization of the message text
1269 : */
1110 tgl 1270 : int
3314 fujii 1271 GIC 19 : errdetail_log_plural(const char *fmt_singular, const char *fmt_plural,
1272 : unsigned long n,...)
1273 : {
1274 19 : ErrorData *edata = &errordata[errordata_stack_depth];
1275 : MemoryContext oldcontext;
1276 :
1277 19 : recursion_depth++;
1278 19 : CHECK_STACK_DEPTH();
1279 19 : oldcontext = MemoryContextSwitchTo(edata->assoc_context);
3314 fujii 1280 EUB :
3314 fujii 1281 GIC 19 : EVALUATE_MESSAGE_PLURAL(edata->domain, detail_log, false);
1282 :
1283 19 : MemoryContextSwitchTo(oldcontext);
3314 fujii 1284 GBC 19 : recursion_depth--;
1110 tgl 1285 GIC 19 : return 0; /* return value does not matter */
1286 : }
1287 :
1288 :
1289 : /*
1290 : * errdetail_plural --- add a detail error message text to the current error,
1291 : * with support for pluralization of the message text
5057 tgl 1292 EUB : */
1110 1293 : int
5057 tgl 1294 GBC 18 : errdetail_plural(const char *fmt_singular, const char *fmt_plural,
5050 bruce 1295 EUB : unsigned long n,...)
1296 : {
5057 tgl 1297 GBC 18 : ErrorData *edata = &errordata[errordata_stack_depth];
5057 tgl 1298 EUB : MemoryContext oldcontext;
1299 :
5057 tgl 1300 GIC 18 : recursion_depth++;
1301 18 : CHECK_STACK_DEPTH();
3538 sfrost 1302 18 : oldcontext = MemoryContextSwitchTo(edata->assoc_context);
1303 :
3800 heikki.linnakangas 1304 18 : EVALUATE_MESSAGE_PLURAL(edata->domain, detail, false);
1305 :
5057 tgl 1306 GBC 18 : MemoryContextSwitchTo(oldcontext);
5057 tgl 1307 GIC 18 : recursion_depth--;
1110 1308 18 : return 0; /* return value does not matter */
1309 : }
1310 :
1311 :
1312 : /*
1313 : * errhint --- add a hint error message text to the current error
1314 : */
1315 : int
7188 bruce 1316 2230 : errhint(const char *fmt,...)
1317 : {
7290 tgl 1318 2230 : ErrorData *edata = &errordata[errordata_stack_depth];
1319 : MemoryContext oldcontext;
1320 :
7290 tgl 1321 CBC 2230 : recursion_depth++;
7290 tgl 1322 GIC 2230 : CHECK_STACK_DEPTH();
3538 sfrost 1323 CBC 2230 : oldcontext = MemoryContextSwitchTo(edata->assoc_context);
1324 :
3800 heikki.linnakangas 1325 GIC 2230 : EVALUATE_MESSAGE(edata->domain, hint, false, true);
7290 tgl 1326 ECB :
7290 tgl 1327 CBC 2230 : MemoryContextSwitchTo(oldcontext);
1328 2230 : recursion_depth--;
1110 tgl 1329 GIC 2230 : return 0; /* return value does not matter */
7290 tgl 1330 ECB : }
1331 :
1332 :
739 peter 1333 : /*
1334 : * errhint_plural --- add a hint error message text to the current error,
1335 : * with support for pluralization of the message text
1336 : */
1337 : int
739 peter 1338 UIC 0 : errhint_plural(const char *fmt_singular, const char *fmt_plural,
1339 : unsigned long n,...)
1340 : {
1341 0 : ErrorData *edata = &errordata[errordata_stack_depth];
1342 : MemoryContext oldcontext;
1343 :
739 peter 1344 LBC 0 : recursion_depth++;
739 peter 1345 UIC 0 : CHECK_STACK_DEPTH();
1346 0 : oldcontext = MemoryContextSwitchTo(edata->assoc_context);
739 peter 1347 ECB :
739 peter 1348 UIC 0 : EVALUATE_MESSAGE_PLURAL(edata->domain, hint, false);
1349 :
739 peter 1350 LBC 0 : MemoryContextSwitchTo(oldcontext);
1351 0 : recursion_depth--;
1352 0 : return 0; /* return value does not matter */
1353 : }
739 peter 1354 ECB :
1355 :
1356 : /*
3800 heikki.linnakangas 1357 : * errcontext_msg --- add a context error message text to the current error
7290 tgl 1358 : *
1359 : * Unlike other cases, multiple calls are allowed to build up a stack of
1360 : * context information. We assume earlier calls represent more-closely-nested
1361 : * states.
1362 : */
1363 : int
3800 heikki.linnakangas 1364 GIC 19815 : errcontext_msg(const char *fmt,...)
1365 : {
7290 tgl 1366 19815 : ErrorData *edata = &errordata[errordata_stack_depth];
7290 tgl 1367 ECB : MemoryContext oldcontext;
1368 :
7290 tgl 1369 CBC 19815 : recursion_depth++;
7290 tgl 1370 GIC 19815 : CHECK_STACK_DEPTH();
3538 sfrost 1371 19815 : oldcontext = MemoryContextSwitchTo(edata->assoc_context);
7290 tgl 1372 ECB :
3800 heikki.linnakangas 1373 CBC 39652 : EVALUATE_MESSAGE(edata->context_domain, context, true, true);
7290 tgl 1374 ECB :
7290 tgl 1375 GIC 19815 : MemoryContextSwitchTo(oldcontext);
7290 tgl 1376 CBC 19815 : recursion_depth--;
1110 tgl 1377 GIC 19815 : return 0; /* return value does not matter */
7290 tgl 1378 ECB : }
1379 :
3800 heikki.linnakangas 1380 : /*
1381 : * set_errcontext_domain --- set message domain to be used by errcontext()
1382 : *
1383 : * errcontext_msg() can be called from a different module than the original
1384 : * ereport(), so we cannot use the message domain passed in errstart() to
1385 : * translate it. Instead, each errcontext_msg() call should be preceded by
1386 : * a set_errcontext_domain() call to specify the domain. This is usually
1387 : * done transparently by the errcontext() macro.
1388 : */
1389 : int
3800 heikki.linnakangas 1390 GIC 19815 : set_errcontext_domain(const char *domain)
1391 : {
1392 19815 : ErrorData *edata = &errordata[errordata_stack_depth];
1393 :
3800 heikki.linnakangas 1394 ECB : /* we don't bother incrementing recursion_depth */
3800 heikki.linnakangas 1395 GIC 19815 : CHECK_STACK_DEPTH();
3800 heikki.linnakangas 1396 ECB :
1397 : /* the default text domain is the backend's */
3009 tgl 1398 GIC 19815 : edata->context_domain = domain ? domain : PG_TEXTDOMAIN("postgres");
1110 tgl 1399 ECB :
1110 tgl 1400 CBC 19815 : return 0; /* return value does not matter */
3800 heikki.linnakangas 1401 ECB : }
1402 :
7290 tgl 1403 :
1404 : /*
5882 1405 : * errhidestmt --- optionally suppress STATEMENT: field of log entry
1406 : *
1407 : * This should be called if the message text already includes the statement.
1408 : */
1409 : int
5882 tgl 1410 GIC 147977 : errhidestmt(bool hide_stmt)
1411 : {
1412 147977 : ErrorData *edata = &errordata[errordata_stack_depth];
1413 :
1414 : /* we don't bother incrementing recursion_depth */
5882 tgl 1415 CBC 147977 : CHECK_STACK_DEPTH();
1416 :
1417 147977 : edata->hide_stmt = hide_stmt;
1418 :
1110 tgl 1419 GIC 147977 : return 0; /* return value does not matter */
5882 tgl 1420 ECB : }
1421 :
3027 andres 1422 : /*
1423 : * errhidecontext --- optionally suppress CONTEXT: field of log entry
1424 : *
1425 : * This should only be used for verbose debugging messages where the repeated
2568 tgl 1426 : * inclusion of context would bloat the log volume too much.
3027 andres 1427 : */
1110 tgl 1428 : int
3027 andres 1429 GIC 785 : errhidecontext(bool hide_ctx)
1430 : {
1431 785 : ErrorData *edata = &errordata[errordata_stack_depth];
1432 :
1433 : /* we don't bother incrementing recursion_depth */
1434 785 : CHECK_STACK_DEPTH();
1435 :
3027 andres 1436 CBC 785 : edata->hide_ctx = hide_ctx;
1437 :
1110 tgl 1438 GIC 785 : return 0; /* return value does not matter */
3027 andres 1439 ECB : }
1440 :
1441 : /*
7290 tgl 1442 : * errposition --- add cursor position to the current error
1443 : */
1110 1444 : int
7290 tgl 1445 GIC 4660 : errposition(int cursorpos)
7290 tgl 1446 ECB : {
7290 tgl 1447 GIC 4660 : ErrorData *edata = &errordata[errordata_stack_depth];
7290 tgl 1448 ECB :
1449 : /* we don't bother incrementing recursion_depth */
7290 tgl 1450 CBC 4660 : CHECK_STACK_DEPTH();
1451 :
7290 tgl 1452 GIC 4660 : edata->cursorpos = cursorpos;
1453 :
1110 1454 4660 : return 0; /* return value does not matter */
1455 : }
1456 :
1457 : /*
1458 : * internalerrposition --- add internal cursor position to the current error
6958 tgl 1459 ECB : */
1460 : int
6958 tgl 1461 GIC 257 : internalerrposition(int cursorpos)
6958 tgl 1462 ECB : {
6958 tgl 1463 GIC 257 : ErrorData *edata = &errordata[errordata_stack_depth];
1464 :
6958 tgl 1465 ECB : /* we don't bother incrementing recursion_depth */
6958 tgl 1466 CBC 257 : CHECK_STACK_DEPTH();
6958 tgl 1467 ECB :
6958 tgl 1468 GIC 257 : edata->internalpos = cursorpos;
1110 tgl 1469 ECB :
1110 tgl 1470 GIC 257 : return 0; /* return value does not matter */
6958 tgl 1471 ECB : }
1472 :
1473 : /*
1474 : * internalerrquery --- add internal query text to the current error
1475 : *
1476 : * Can also pass NULL to drop the internal query text entry. This case
1477 : * is intended for use in error callback subroutines that are editorializing
1478 : * on the layout of the error report.
1479 : */
1480 : int
6958 tgl 1481 CBC 248 : internalerrquery(const char *query)
1482 : {
1483 248 : ErrorData *edata = &errordata[errordata_stack_depth];
1484 :
1485 : /* we don't bother incrementing recursion_depth */
1486 248 : CHECK_STACK_DEPTH();
6958 tgl 1487 ECB :
6958 tgl 1488 CBC 248 : if (edata->internalquery)
1489 : {
1490 86 : pfree(edata->internalquery);
6958 tgl 1491 GIC 86 : edata->internalquery = NULL;
6958 tgl 1492 ECB : }
1493 :
6958 tgl 1494 CBC 248 : if (query)
3538 sfrost 1495 GIC 147 : edata->internalquery = MemoryContextStrdup(edata->assoc_context, query);
1496 :
1110 tgl 1497 248 : return 0; /* return value does not matter */
1498 : }
1499 :
1500 : /*
1501 : * err_generic_string -- used to set individual ErrorData string fields
1502 : * identified by PG_DIAG_xxx codes.
3722 tgl 1503 EUB : *
1504 : * This intentionally only supports fields that don't use localized strings,
1505 : * so that there are no translation considerations.
1506 : *
1507 : * Most potential callers should not use this directly, but instead prefer
1508 : * higher-level abstractions, such as errtablecol() (see relcache.c).
1509 : */
1110 1510 : int
3722 tgl 1511 GBC 5048 : err_generic_string(int field, const char *str)
1512 : {
1513 5048 : ErrorData *edata = &errordata[errordata_stack_depth];
1514 :
3722 tgl 1515 EUB : /* we don't bother incrementing recursion_depth */
3722 tgl 1516 GBC 5048 : CHECK_STACK_DEPTH();
3722 tgl 1517 EUB :
3722 tgl 1518 GIC 5048 : switch (field)
1519 : {
1520 1781 : case PG_DIAG_SCHEMA_NAME:
3538 sfrost 1521 1781 : set_errdata_field(edata->assoc_context, &edata->schema_name, str);
3722 tgl 1522 1781 : break;
1523 1460 : case PG_DIAG_TABLE_NAME:
3538 sfrost 1524 1460 : set_errdata_field(edata->assoc_context, &edata->table_name, str);
3722 tgl 1525 1460 : break;
1526 180 : case PG_DIAG_COLUMN_NAME:
3538 sfrost 1527 180 : set_errdata_field(edata->assoc_context, &edata->column_name, str);
3722 tgl 1528 180 : break;
3722 tgl 1529 CBC 338 : case PG_DIAG_DATATYPE_NAME:
3538 sfrost 1530 GIC 338 : set_errdata_field(edata->assoc_context, &edata->datatype_name, str);
3722 tgl 1531 CBC 338 : break;
3722 tgl 1532 GIC 1289 : case PG_DIAG_CONSTRAINT_NAME:
3538 sfrost 1533 1289 : set_errdata_field(edata->assoc_context, &edata->constraint_name, str);
3722 tgl 1534 CBC 1289 : break;
3722 tgl 1535 LBC 0 : default:
1536 0 : elog(ERROR, "unsupported ErrorData field id: %d", field);
1537 : break;
3722 tgl 1538 ECB : }
1539 :
1110 tgl 1540 CBC 5048 : return 0; /* return value does not matter */
3722 tgl 1541 ECB : }
1542 :
1543 : /*
1544 : * set_errdata_field --- set an ErrorData string field
1545 : */
1546 : static void
3538 sfrost 1547 GIC 5048 : set_errdata_field(MemoryContextData *cxt, char **ptr, const char *str)
1548 : {
3722 tgl 1549 5048 : Assert(*ptr == NULL);
3538 sfrost 1550 5048 : *ptr = MemoryContextStrdup(cxt, str);
3722 tgl 1551 5048 : }
1552 :
1553 : /*
1554 : * geterrcode --- return the currently set SQLSTATE error code
5333 tgl 1555 ECB : *
1556 : * This is only intended for use in error callback subroutines, since there
1557 : * is no other place outside elog.c where the concept is meaningful.
1558 : */
1559 : int
5333 tgl 1560 CBC 2282 : geterrcode(void)
1561 : {
5333 tgl 1562 GIC 2282 : ErrorData *edata = &errordata[errordata_stack_depth];
5333 tgl 1563 ECB :
1564 : /* we don't bother incrementing recursion_depth */
5333 tgl 1565 CBC 2282 : CHECK_STACK_DEPTH();
1566 :
5333 tgl 1567 GIC 2282 : return edata->sqlerrcode;
1568 : }
1569 :
1570 : /*
1571 : * geterrposition --- return the currently set error position (0 if none)
1572 : *
1573 : * This is only intended for use in error callback subroutines, since there
1574 : * is no other place outside elog.c where the concept is meaningful.
6958 tgl 1575 ECB : */
1576 : int
6958 tgl 1577 CBC 7653 : geterrposition(void)
1578 : {
6958 tgl 1579 GIC 7653 : ErrorData *edata = &errordata[errordata_stack_depth];
6958 tgl 1580 ECB :
1581 : /* we don't bother incrementing recursion_depth */
6958 tgl 1582 CBC 7653 : CHECK_STACK_DEPTH();
1583 :
1584 7653 : return edata->cursorpos;
1585 : }
1586 :
1587 : /*
1588 : * getinternalerrposition --- same for internal error position
1589 : *
1590 : * This is only intended for use in error callback subroutines, since there
1591 : * is no other place outside elog.c where the concept is meaningful.
1592 : */
1593 : int
1594 113 : getinternalerrposition(void)
1595 : {
1596 113 : ErrorData *edata = &errordata[errordata_stack_depth];
1597 :
1598 : /* we don't bother incrementing recursion_depth */
1599 113 : CHECK_STACK_DEPTH();
1600 :
1601 113 : return edata->internalpos;
1602 : }
6958 tgl 1603 ECB :
1604 :
1605 : /*
1606 : * Functions to allow construction of error message strings separately from
1607 : * the ereport() call itself.
1608 : *
1609 : * The expected calling convention is
4385 1610 : *
1611 : * pre_format_elog_string(errno, domain), var = format_elog_string(format,...)
1612 : *
1613 : * which can be hidden behind a macro such as GUC_check_errdetail(). We
1614 : * assume that any functions called in the arguments of format_elog_string()
1615 : * cannot result in re-entrant use of these functions --- otherwise the wrong
1616 : * text domain might be used, or the wrong errno substituted for %m. This is
1617 : * okay for the current usage with GUC check hooks, but might need further
1618 : * effort someday.
1619 : *
1620 : * The result of format_elog_string() is stored in ErrorContext, and will
1621 : * therefore survive until FlushErrorState() is called.
1622 : */
1623 : static int save_format_errnumber;
1624 : static const char *save_format_domain;
1625 :
1626 : void
4385 tgl 1627 GIC 25 : pre_format_elog_string(int errnumber, const char *domain)
4385 tgl 1628 ECB : {
1629 : /* Save errno before evaluation of argument functions can change it */
4385 tgl 1630 GIC 25 : save_format_errnumber = errnumber;
4385 tgl 1631 ECB : /* Save caller's text domain */
4385 tgl 1632 GIC 25 : save_format_domain = domain;
4385 tgl 1633 CBC 25 : }
1634 :
4385 tgl 1635 ECB : char *
4382 bruce 1636 GIC 25 : format_elog_string(const char *fmt,...)
1637 : {
1638 : ErrorData errdata;
1639 : ErrorData *edata;
1640 : MemoryContext oldcontext;
1641 :
1642 : /* Initialize a mostly-dummy error frame */
4385 tgl 1643 25 : edata = &errdata;
1644 600 : MemSet(edata, 0, sizeof(ErrorData));
1645 : /* the default text domain is the backend's */
4385 tgl 1646 CBC 25 : edata->domain = save_format_domain ? save_format_domain : PG_TEXTDOMAIN("postgres");
1647 : /* set the errno to be used to interpret %m */
1648 25 : edata->saved_errno = save_format_errnumber;
1649 :
4385 tgl 1650 GIC 25 : oldcontext = MemoryContextSwitchTo(ErrorContext);
4385 tgl 1651 ECB :
2585 simon 1652 GIC 25 : edata->message_id = fmt;
3800 heikki.linnakangas 1653 CBC 25 : EVALUATE_MESSAGE(edata->domain, message, false, true);
1654 :
4385 tgl 1655 25 : MemoryContextSwitchTo(oldcontext);
4385 tgl 1656 ECB :
4385 tgl 1657 GIC 25 : return edata->message;
1658 : }
4385 tgl 1659 ECB :
1660 :
1661 : /*
6826 1662 : * Actual output of the top-of-stack error message
1663 : *
1664 : * In the ereport(ERROR) case this is called from PostgresMain (or not at all,
1665 : * if the error is caught by somebody). For all other severity levels this
1666 : * is called by errfinish.
1667 : */
1668 : void
6826 tgl 1669 GIC 196571 : EmitErrorReport(void)
1670 : {
1671 196571 : ErrorData *edata = &errordata[errordata_stack_depth];
1672 : MemoryContext oldcontext;
1673 :
1674 196571 : recursion_depth++;
1675 196571 : CHECK_STACK_DEPTH();
3538 sfrost 1676 CBC 196571 : oldcontext = MemoryContextSwitchTo(edata->assoc_context);
1677 :
4051 tgl 1678 ECB : /*
1679 : * Call hook before sending message to log. The hook function is allowed
1680 : * to turn off edata->output_to_server, so we must recheck that afterward.
1681 : * Making any other change in the content of edata is not considered
1682 : * supported.
1683 : *
1684 : * Note: the reason why the hook can only turn off output_to_server, and
1685 : * not turn it on, is that it'd be unreliable: we will never get here at
1686 : * all if errstart() deems the message uninteresting. A hook that could
1687 : * make decisions in that direction would have to hook into errstart(),
1688 : * where it would have much less information available. emit_log_hook is
1689 : * intended for custom log filtering and custom log message transmission
1690 : * mechanisms.
2585 simon 1691 : *
1692 : * The log hook has access to both the translated and original English
2495 rhaas 1693 : * error message text, which is passed through to allow it to be used as a
1694 : * message identifier. Note that the original text is not available for
1695 : * detail, detail_log, hint and context text elements.
4051 tgl 1696 : */
4051 tgl 1697 CBC 196571 : if (edata->output_to_server && emit_log_hook)
4051 tgl 1698 LBC 0 : (*emit_log_hook) (edata);
4051 tgl 1699 ECB :
6826 tgl 1700 EUB : /* Send to server log, if enabled */
6826 tgl 1701 GBC 196571 : if (edata->output_to_server)
6826 tgl 1702 GIC 187471 : send_message_to_server_log(edata);
1703 :
1704 : /* Send to client, if enabled */
6826 tgl 1705 CBC 196571 : if (edata->output_to_client)
6826 tgl 1706 GIC 28251 : send_message_to_frontend(edata);
1707 :
1708 196571 : MemoryContextSwitchTo(oldcontext);
1709 196571 : recursion_depth--;
1710 196571 : }
1711 :
6826 tgl 1712 ECB : /*
1713 : * CopyErrorData --- obtain a copy of the topmost error stack entry
1714 : *
3260 bruce 1715 : * This is only for use in error handler code. The data is copied into the
6826 tgl 1716 : * current memory context, so callers should always switch away from
1717 : * ErrorContext first; otherwise it will be lost when FlushErrorState is done.
1718 : */
1719 : ErrorData *
6826 tgl 1720 GIC 3123 : CopyErrorData(void)
1721 : {
1722 3123 : ErrorData *edata = &errordata[errordata_stack_depth];
1723 : ErrorData *newedata;
1724 :
6826 tgl 1725 ECB : /*
1726 : * we don't increment recursion_depth because out-of-memory here does not
6385 bruce 1727 : * indicate a problem within the error subsystem.
1728 : */
6826 tgl 1729 GIC 3123 : CHECK_STACK_DEPTH();
6826 tgl 1730 ECB :
6826 tgl 1731 GIC 3123 : Assert(CurrentMemoryContext != ErrorContext);
6826 tgl 1732 ECB :
1733 : /* Copy the struct itself */
6826 tgl 1734 GIC 3123 : newedata = (ErrorData *) palloc(sizeof(ErrorData));
1735 3123 : memcpy(newedata, edata, sizeof(ErrorData));
1736 :
1737 : /* Make copies of separately-allocated fields */
1738 3123 : if (newedata->message)
1739 3123 : newedata->message = pstrdup(newedata->message);
1740 3123 : if (newedata->detail)
1741 72 : newedata->detail = pstrdup(newedata->detail);
5494 tgl 1742 CBC 3123 : if (newedata->detail_log)
5494 tgl 1743 UIC 0 : newedata->detail_log = pstrdup(newedata->detail_log);
6826 tgl 1744 CBC 3123 : if (newedata->hint)
6826 tgl 1745 GIC 27 : newedata->hint = pstrdup(newedata->hint);
1746 3123 : if (newedata->context)
6826 tgl 1747 CBC 3105 : newedata->context = pstrdup(newedata->context);
1248 alvherre 1748 GIC 3123 : if (newedata->backtrace)
1248 alvherre 1749 LBC 0 : newedata->backtrace = pstrdup(newedata->backtrace);
3722 tgl 1750 GIC 3123 : if (newedata->schema_name)
1751 28 : newedata->schema_name = pstrdup(newedata->schema_name);
1752 3123 : if (newedata->table_name)
1753 30 : newedata->table_name = pstrdup(newedata->table_name);
1754 3123 : if (newedata->column_name)
1755 9 : newedata->column_name = pstrdup(newedata->column_name);
1756 3123 : if (newedata->datatype_name)
1757 10 : newedata->datatype_name = pstrdup(newedata->datatype_name);
1758 3123 : if (newedata->constraint_name)
3722 tgl 1759 CBC 27 : newedata->constraint_name = pstrdup(newedata->constraint_name);
6826 tgl 1760 GIC 3123 : if (newedata->internalquery)
6826 tgl 1761 CBC 17 : newedata->internalquery = pstrdup(newedata->internalquery);
1762 :
1763 : /* Use the calling context for string allocation */
3538 sfrost 1764 3123 : newedata->assoc_context = CurrentMemoryContext;
1765 :
6826 tgl 1766 3123 : return newedata;
1767 : }
1768 :
1769 : /*
1770 : * FreeErrorData --- free the structure returned by CopyErrorData.
1771 : *
1772 : * Error handlers should use this in preference to assuming they know all
1773 : * the separately-allocated fields.
1774 : */
1775 : void
6826 tgl 1776 GIC 69 : FreeErrorData(ErrorData *edata)
1777 : {
123 tgl 1778 GNC 69 : FreeErrorDataContents(edata);
1779 69 : pfree(edata);
1780 69 : }
1781 :
1782 : /*
1783 : * FreeErrorDataContents --- free the subsidiary data of an ErrorData.
1784 : *
1785 : * This can be used on either an error stack entry or a copied ErrorData.
1786 : */
1787 : static void
1788 178822 : FreeErrorDataContents(ErrorData *edata)
1789 : {
6826 tgl 1790 GIC 178822 : if (edata->message)
1791 178822 : pfree(edata->message);
1792 178822 : if (edata->detail)
1793 8402 : pfree(edata->detail);
5494 1794 178822 : if (edata->detail_log)
1795 357 : pfree(edata->detail_log);
6826 1796 178822 : if (edata->hint)
1797 306 : pfree(edata->hint);
1798 178822 : if (edata->context)
1799 7607 : pfree(edata->context);
1248 alvherre 1800 178822 : if (edata->backtrace)
1248 alvherre 1801 UIC 0 : pfree(edata->backtrace);
3722 tgl 1802 GIC 178822 : if (edata->schema_name)
1803 19 : pfree(edata->schema_name);
3722 tgl 1804 CBC 178822 : if (edata->table_name)
3722 tgl 1805 GIC 21 : pfree(edata->table_name);
1806 178822 : if (edata->column_name)
3722 tgl 1807 CBC 6 : pfree(edata->column_name);
3722 tgl 1808 GIC 178822 : if (edata->datatype_name)
3722 tgl 1809 CBC 7 : pfree(edata->datatype_name);
1810 178822 : if (edata->constraint_name)
3722 tgl 1811 GIC 12 : pfree(edata->constraint_name);
6826 1812 178822 : if (edata->internalquery)
6826 tgl 1813 CBC 17 : pfree(edata->internalquery);
6826 tgl 1814 GIC 178822 : }
1815 :
1816 : /*
1817 : * FlushErrorState --- flush the error state after error recovery
1818 : *
6826 tgl 1819 ECB : * This should be called by an error handler after it's done processing
1820 : * the error; or as soon as it's done CopyErrorData, if it intends to
1821 : * do stuff that is likely to provoke another error. You are not "out" of
1822 : * the error subsystem until you have done this.
1823 : */
1824 : void
6826 tgl 1825 GIC 20871 : FlushErrorState(void)
6826 tgl 1826 ECB : {
1827 : /*
6385 bruce 1828 : * Reset stack to empty. The only case where it would be more than one
1829 : * deep is if we serviced an error that interrupted construction of
1830 : * another message. We assume control escaped out of that message
6797 1831 : * construction and won't ever go back.
1832 : */
6826 tgl 1833 CBC 20871 : errordata_stack_depth = -1;
6826 tgl 1834 GIC 20871 : recursion_depth = 0;
1835 : /* Delete all data in ErrorContext */
1836 20871 : MemoryContextResetAndDeleteChildren(ErrorContext);
1837 20871 : }
1838 :
1839 : /*
1840 : * ThrowErrorData --- report an error described by an ErrorData structure
1841 : *
1842 : * This is somewhat like ReThrowError, but it allows elevels besides ERROR,
1843 : * and the boolean flags such as output_to_server are computed via the
1844 : * default rules rather than being copied from the given ErrorData.
2417 tgl 1845 ECB : * This is primarily used to re-report errors originally reported by
1846 : * background worker processes and then propagated (with or without
3082 rhaas 1847 : * modification) to the backend responsible for them.
1848 : */
1849 : void
3082 rhaas 1850 CBC 3 : ThrowErrorData(ErrorData *edata)
3082 rhaas 1851 ECB : {
2878 bruce 1852 : ErrorData *newedata;
1853 : MemoryContext oldcontext;
1854 :
1111 tgl 1855 GIC 3 : if (!errstart(edata->elevel, edata->domain))
2417 tgl 1856 UIC 0 : return; /* error is not to be reported at all */
1857 :
3082 rhaas 1858 GIC 3 : newedata = &errordata[errordata_stack_depth];
2417 tgl 1859 3 : recursion_depth++;
1860 3 : oldcontext = MemoryContextSwitchTo(newedata->assoc_context);
1861 :
1862 : /* Copy the supplied fields to the error stack entry. */
1863 3 : if (edata->sqlerrcode != 0)
3082 rhaas 1864 3 : newedata->sqlerrcode = edata->sqlerrcode;
1865 3 : if (edata->message)
1866 3 : newedata->message = pstrdup(edata->message);
1867 3 : if (edata->detail)
3082 rhaas 1868 UIC 0 : newedata->detail = pstrdup(edata->detail);
3082 rhaas 1869 GIC 3 : if (edata->detail_log)
3082 rhaas 1870 UIC 0 : newedata->detail_log = pstrdup(edata->detail_log);
3082 rhaas 1871 GIC 3 : if (edata->hint)
3082 rhaas 1872 UIC 0 : newedata->hint = pstrdup(edata->hint);
3082 rhaas 1873 CBC 3 : if (edata->context)
3082 rhaas 1874 GBC 3 : newedata->context = pstrdup(edata->context);
1248 alvherre 1875 GIC 3 : if (edata->backtrace)
1248 alvherre 1876 UIC 0 : newedata->backtrace = pstrdup(edata->backtrace);
2417 tgl 1877 ECB : /* assume message_id is not available */
3082 rhaas 1878 CBC 3 : if (edata->schema_name)
3082 rhaas 1879 UIC 0 : newedata->schema_name = pstrdup(edata->schema_name);
3082 rhaas 1880 GIC 3 : if (edata->table_name)
3082 rhaas 1881 LBC 0 : newedata->table_name = pstrdup(edata->table_name);
3082 rhaas 1882 CBC 3 : if (edata->column_name)
3082 rhaas 1883 UIC 0 : newedata->column_name = pstrdup(edata->column_name);
3082 rhaas 1884 CBC 3 : if (edata->datatype_name)
3082 rhaas 1885 LBC 0 : newedata->datatype_name = pstrdup(edata->datatype_name);
3082 rhaas 1886 CBC 3 : if (edata->constraint_name)
3082 rhaas 1887 UIC 0 : newedata->constraint_name = pstrdup(edata->constraint_name);
2417 tgl 1888 GIC 3 : newedata->cursorpos = edata->cursorpos;
1889 3 : newedata->internalpos = edata->internalpos;
3082 rhaas 1890 3 : if (edata->internalquery)
3082 rhaas 1891 UIC 0 : newedata->internalquery = pstrdup(edata->internalquery);
1892 :
3082 rhaas 1893 GIC 3 : MemoryContextSwitchTo(oldcontext);
2417 tgl 1894 3 : recursion_depth--;
1895 :
2417 tgl 1896 ECB : /* Process the error. */
1111 tgl 1897 GIC 3 : errfinish(edata->filename, edata->lineno, edata->funcname);
3082 rhaas 1898 ECB : }
1899 :
1900 : /*
1901 : * ReThrowError --- re-throw a previously copied error
1902 : *
1903 : * A handler can do CopyErrorData/FlushErrorState to get out of the error
1904 : * subsystem, then do some processing, and finally ReThrowError to re-throw
3260 bruce 1905 : * the original error. This is slower than just PG_RE_THROW() but should
1906 : * be used if the "some processing" is likely to incur another error.
6826 tgl 1907 : */
1908 : void
6826 tgl 1909 GIC 32 : ReThrowError(ErrorData *edata)
6826 tgl 1910 ECB : {
1911 : ErrorData *newedata;
1912 :
6826 tgl 1913 GIC 32 : Assert(edata->elevel == ERROR);
6826 tgl 1914 ECB :
1915 : /* Push the data back into the error context */
6826 tgl 1916 CBC 32 : recursion_depth++;
1917 32 : MemoryContextSwitchTo(ErrorContext);
6826 tgl 1918 ECB :
123 tgl 1919 GNC 32 : newedata = get_error_stack_entry();
6826 tgl 1920 CBC 32 : memcpy(newedata, edata, sizeof(ErrorData));
6826 tgl 1921 ECB :
1922 : /* Make copies of separately-allocated fields */
6826 tgl 1923 CBC 32 : if (newedata->message)
1924 32 : newedata->message = pstrdup(newedata->message);
1925 32 : if (newedata->detail)
1926 19 : newedata->detail = pstrdup(newedata->detail);
5494 tgl 1927 GIC 32 : if (newedata->detail_log)
5494 tgl 1928 UIC 0 : newedata->detail_log = pstrdup(newedata->detail_log);
6826 tgl 1929 CBC 32 : if (newedata->hint)
6826 tgl 1930 UIC 0 : newedata->hint = pstrdup(newedata->hint);
6826 tgl 1931 CBC 32 : if (newedata->context)
6826 tgl 1932 GIC 30 : newedata->context = pstrdup(newedata->context);
1248 alvherre 1933 32 : if (newedata->backtrace)
1248 alvherre 1934 UIC 0 : newedata->backtrace = pstrdup(newedata->backtrace);
3722 tgl 1935 GIC 32 : if (newedata->schema_name)
1936 7 : newedata->schema_name = pstrdup(newedata->schema_name);
1937 32 : if (newedata->table_name)
1938 7 : newedata->table_name = pstrdup(newedata->table_name);
1939 32 : if (newedata->column_name)
3722 tgl 1940 UIC 0 : newedata->column_name = pstrdup(newedata->column_name);
3722 tgl 1941 CBC 32 : if (newedata->datatype_name)
3722 tgl 1942 UIC 0 : newedata->datatype_name = pstrdup(newedata->datatype_name);
3722 tgl 1943 CBC 32 : if (newedata->constraint_name)
1944 7 : newedata->constraint_name = pstrdup(newedata->constraint_name);
6826 1945 32 : if (newedata->internalquery)
6826 tgl 1946 UIC 0 : newedata->internalquery = pstrdup(newedata->internalquery);
1947 :
1948 : /* Reset the assoc_context to be ErrorContext */
3538 sfrost 1949 GIC 32 : newedata->assoc_context = ErrorContext;
1950 :
6826 tgl 1951 32 : recursion_depth--;
1952 32 : PG_RE_THROW();
6826 tgl 1953 ECB : }
1954 :
5821 1955 : /*
1956 : * pg_re_throw --- out-of-line implementation of PG_RE_THROW() macro
1957 : */
1958 : void
5821 tgl 1959 CBC 44776 : pg_re_throw(void)
5821 tgl 1960 ECB : {
1961 : /* If possible, throw the error to the next outer setjmp handler */
5821 tgl 1962 CBC 44776 : if (PG_exception_stack != NULL)
1963 44776 : siglongjmp(*PG_exception_stack, 1);
5821 tgl 1964 ECB : else
1965 : {
5821 tgl 1966 EUB : /*
5821 tgl 1967 ECB : * If we get here, elog(ERROR) was thrown inside a PG_TRY block, which
1968 : * we have now exited only to discover that there is no outer setjmp
5624 bruce 1969 : * handler to pass the error to. Had the error been thrown outside
1970 : * the block to begin with, we'd have promoted the error to FATAL, so
1971 : * the correct behavior is to make it FATAL now; that is, emit it and
1972 : * then call proc_exit.
5821 tgl 1973 : */
5821 tgl 1974 LBC 0 : ErrorData *edata = &errordata[errordata_stack_depth];
5821 tgl 1975 ECB :
5821 tgl 1976 LBC 0 : Assert(errordata_stack_depth >= 0);
1977 0 : Assert(edata->elevel == ERROR);
1978 0 : edata->elevel = FATAL;
5821 tgl 1979 ECB :
1980 : /*
1981 : * At least in principle, the increase in severity could have changed
1982 : * where-to-output decisions, so recalculate.
1983 : */
867 tgl 1984 UIC 0 : edata->output_to_server = should_output_to_server(FATAL);
1985 0 : edata->output_to_client = should_output_to_client(FATAL);
1986 :
1987 : /*
1988 : * We can use errfinish() for the rest, but we don't want it to call
1989 : * any error context routines a second time. Since we know we are
5821 tgl 1990 ECB : * about to exit, it should be OK to just clear the context stack.
1991 : */
5821 tgl 1992 UIC 0 : error_context_stack = NULL;
1993 :
1111 1994 0 : errfinish(edata->filename, edata->lineno, edata->funcname);
1995 : }
1996 :
1997 : /* Doesn't return ... */
181 tgl 1998 UNC 0 : ExceptionalCondition("pg_re_throw tried to return", __FILE__, __LINE__);
1999 : }
5821 tgl 2000 ECB :
2001 :
2002 : /*
2003 : * GetErrorContextStack - Return the context stack, for display/diags
2004 : *
2005 : * Returns a pstrdup'd string in the caller's context which includes the PG
2006 : * error call stack. It is the caller's responsibility to ensure this string
2007 : * is pfree'd (or its context cleaned up) when done.
2008 : *
2009 : * This information is collected by traversing the error contexts and calling
2010 : * each context's callback function, each of which is expected to call
2011 : * errcontext() to return a string which can be presented to the user.
2012 : */
2013 : char *
3546 sfrost 2014 CBC 24 : GetErrorContextStack(void)
2015 : {
2016 : ErrorData *edata;
2017 : ErrorContextCallback *econtext;
2018 :
3545 sfrost 2019 ECB : /*
2020 : * Crank up a stack entry to store the info in.
2021 : */
3538 sfrost 2022 CBC 24 : recursion_depth++;
3538 sfrost 2023 ECB :
123 tgl 2024 GNC 24 : edata = get_error_stack_entry();
3546 sfrost 2025 EUB :
2026 : /*
3538 sfrost 2027 ECB : * Set up assoc_context to be the caller's context, so any allocations
3538 sfrost 2028 EUB : * done (which will include edata->context) will use their context.
3545 sfrost 2029 ECB : */
3538 sfrost 2030 GBC 24 : edata->assoc_context = CurrentMemoryContext;
3546 sfrost 2031 ECB :
3546 sfrost 2032 EUB : /*
3546 sfrost 2033 ECB : * Call any context callback functions to collect the context information
3546 sfrost 2034 EUB : * into edata->context.
3546 sfrost 2035 ECB : *
3546 sfrost 2036 EUB : * Errors occurring in callback functions should go through the regular
3260 bruce 2037 ECB : * error handling code which should handle any recursive errors, though we
2038 : * double-check above, just in case.
3546 sfrost 2039 : */
3546 sfrost 2040 GBC 24 : for (econtext = error_context_stack;
3546 sfrost 2041 GIC 96 : econtext != NULL;
3546 sfrost 2042 CBC 72 : econtext = econtext->previous)
2040 peter_e 2043 72 : econtext->callback(econtext->arg);
2044 :
2045 : /*
3538 sfrost 2046 ECB : * Clean ourselves off the stack, any allocations done should have been
2047 : * using edata->assoc_context, which we set up earlier to be the caller's
2048 : * context, so we're free to just remove our entry off the stack and
2049 : * decrement recursion depth and exit.
2050 : */
3538 sfrost 2051 GIC 24 : errordata_stack_depth--;
2052 24 : recursion_depth--;
2053 :
2054 : /*
2055 : * Return a pointer to the string the caller asked for, which should have
2056 : * been allocated in their context.
2057 : */
3538 sfrost 2058 CBC 24 : return edata->context;
2059 : }
2060 :
2061 :
7290 tgl 2062 ECB : /*
2063 : * Initialization of error output file
2064 : */
2065 : void
9646 bruce 2066 CBC 13367 : DebugFileOpen(void)
2067 : {
9344 bruce 2068 ECB : int fd,
2069 : istty;
2070 :
9345 bruce 2071 GIC 13367 : if (OutputFileName[0])
9345 bruce 2072 ECB : {
8170 tgl 2073 : /*
2074 : * A debug-output file name was given.
2075 : *
2076 : * Make sure we can write the file, and find out if it's a tty.
8170 tgl 2077 EUB : */
9345 bruce 2078 LBC 0 : if ((fd = open(OutputFileName, O_CREAT | O_APPEND | O_WRONLY,
9345 bruce 2079 EUB : 0666)) < 0)
7290 tgl 2080 LBC 0 : ereport(FATAL,
7205 tgl 2081 ECB : (errcode_for_file_access(),
2118 2082 : errmsg("could not open file \"%s\": %m", OutputFileName)));
9345 bruce 2083 UBC 0 : istty = isatty(fd);
9345 bruce 2084 LBC 0 : close(fd);
9345 bruce 2085 ECB :
8170 tgl 2086 : /*
2087 : * Redirect our stderr to the debug output file.
2088 : */
8170 tgl 2089 UBC 0 : if (!freopen(OutputFileName, "a", stderr))
7290 tgl 2090 LBC 0 : ereport(FATAL,
7205 tgl 2091 EUB : (errcode_for_file_access(),
7136 peter_e 2092 ECB : errmsg("could not reopen file \"%s\" as stderr: %m",
7290 tgl 2093 : OutputFileName)));
8053 bruce 2094 :
9345 bruce 2095 EUB : /*
2096 : * If the file is a tty and we're running under the postmaster, try to
2097 : * send stdout there as well (if it isn't a tty then stderr will block
6385 bruce 2098 ECB : * out stdout, so we may as well let stdout go wherever it was going
2099 : * before).
9345 2100 : */
8170 tgl 2101 LBC 0 : if (istty && IsUnderPostmaster)
8170 tgl 2102 UIC 0 : if (!freopen(OutputFileName, "a", stdout))
7290 2103 0 : ereport(FATAL,
2104 : (errcode_for_file_access(),
2105 : errmsg("could not reopen file \"%s\" as stdout: %m",
2106 : OutputFileName)));
2107 : }
8344 peter_e 2108 CBC 13367 : }
2109 :
2110 :
2111 : /*
2112 : * GUC check_hook for backtrace_functions
2113 : *
2114 : * We split the input string, where commas separate function names
2115 : * and certain whitespace chars are ignored, into a \0-separated (and
2116 : * \0\0-terminated) list of function names. This formulation allows
2117 : * easy scanning when an error is thrown while avoiding the use of
2118 : * non-reentrant strtok(), as well as keeping the output data in a
2119 : * single palloc() chunk.
2120 : */
2121 : bool
208 tgl 2122 GNC 1857 : check_backtrace_functions(char **newval, void **extra, GucSource source)
2123 : {
2124 1857 : int newvallen = strlen(*newval);
2125 : char *someval;
2126 : int validlen;
2127 : int i;
2128 : int j;
2129 :
2130 : /*
2131 : * Allow characters that can be C identifiers and commas as separators, as
2132 : * well as some whitespace for readability.
2133 : */
2134 1857 : validlen = strspn(*newval,
2135 : "0123456789_"
2136 : "abcdefghijklmnopqrstuvwxyz"
2137 : "ABCDEFGHIJKLMNOPQRSTUVWXYZ"
2138 : ", \n\t");
2139 1857 : if (validlen != newvallen)
2140 : {
208 tgl 2141 UNC 0 : GUC_check_errdetail("invalid character");
2142 0 : return false;
2143 : }
2144 :
208 tgl 2145 GNC 1857 : if (*newval[0] == '\0')
2146 : {
2147 1857 : *extra = NULL;
2148 1857 : return true;
2149 : }
2150 :
2151 : /*
2152 : * Allocate space for the output and create the copy. We could discount
2153 : * whitespace chars to save some memory, but it doesn't seem worth the
2154 : * trouble.
2155 : */
208 tgl 2156 UNC 0 : someval = guc_malloc(ERROR, newvallen + 1 + 1);
2157 0 : for (i = 0, j = 0; i < newvallen; i++)
2158 : {
2159 0 : if ((*newval)[i] == ',')
2160 0 : someval[j++] = '\0'; /* next item */
2161 0 : else if ((*newval)[i] == ' ' ||
2162 0 : (*newval)[i] == '\n' ||
2163 0 : (*newval)[i] == '\t')
2164 : ; /* ignore these */
2165 : else
2166 0 : someval[j++] = (*newval)[i]; /* copy anything else */
2167 : }
2168 :
2169 : /* two \0s end the setting */
2170 0 : someval[j] = '\0';
2171 0 : someval[j + 1] = '\0';
2172 :
2173 0 : *extra = someval;
2174 0 : return true;
2175 : }
208 tgl 2176 ECB :
2177 : /*
2178 : * GUC assign_hook for backtrace_functions
2179 : */
2180 : void
208 tgl 2181 GNC 1857 : assign_backtrace_functions(const char *newval, void *extra)
2182 : {
2183 1857 : backtrace_symbol_list = (char *) extra;
2184 1857 : }
2185 :
2186 : /*
2187 : * GUC check_hook for log_destination
2188 : */
2189 : bool
2190 1858 : check_log_destination(char **newval, void **extra, GucSource source)
2191 : {
2192 : char *rawstring;
2193 : List *elemlist;
2194 : ListCell *l;
2195 1858 : int newlogdest = 0;
2196 : int *myextra;
2197 :
2198 : /* Need a modifiable copy of string */
2199 1858 : rawstring = pstrdup(*newval);
2200 :
2201 : /* Parse string into list of identifiers */
2202 1858 : if (!SplitIdentifierString(rawstring, ',', &elemlist))
2203 : {
2204 : /* syntax error in list */
208 tgl 2205 UNC 0 : GUC_check_errdetail("List syntax is invalid.");
2206 0 : pfree(rawstring);
2207 0 : list_free(elemlist);
2208 0 : return false;
2209 : }
2210 :
208 tgl 2211 GNC 3718 : foreach(l, elemlist)
2212 : {
2213 1860 : char *tok = (char *) lfirst(l);
2214 :
2215 1860 : if (pg_strcasecmp(tok, "stderr") == 0)
2216 1858 : newlogdest |= LOG_DESTINATION_STDERR;
2217 2 : else if (pg_strcasecmp(tok, "csvlog") == 0)
2218 1 : newlogdest |= LOG_DESTINATION_CSVLOG;
2219 1 : else if (pg_strcasecmp(tok, "jsonlog") == 0)
2220 1 : newlogdest |= LOG_DESTINATION_JSONLOG;
2221 : #ifdef HAVE_SYSLOG
208 tgl 2222 UNC 0 : else if (pg_strcasecmp(tok, "syslog") == 0)
2223 0 : newlogdest |= LOG_DESTINATION_SYSLOG;
2224 : #endif
2225 : #ifdef WIN32
2226 : else if (pg_strcasecmp(tok, "eventlog") == 0)
2227 : newlogdest |= LOG_DESTINATION_EVENTLOG;
2228 : #endif
2229 : else
2230 : {
2231 0 : GUC_check_errdetail("Unrecognized key word: \"%s\".", tok);
2232 0 : pfree(rawstring);
2233 0 : list_free(elemlist);
2234 0 : return false;
2235 : }
2236 : }
2237 :
208 tgl 2238 GNC 1858 : pfree(rawstring);
2239 1858 : list_free(elemlist);
2240 :
2241 1858 : myextra = (int *) guc_malloc(ERROR, sizeof(int));
2242 1858 : *myextra = newlogdest;
2243 1858 : *extra = (void *) myextra;
2244 :
2245 1858 : return true;
2246 : }
2247 :
2248 : /*
2249 : * GUC assign_hook for log_destination
2250 : */
2251 : void
2252 1858 : assign_log_destination(const char *newval, void *extra)
2253 : {
2254 1858 : Log_destination = *((int *) extra);
2255 1858 : }
2256 :
2257 : /*
2258 : * GUC assign_hook for syslog_ident
2259 : */
2260 : void
2261 1857 : assign_syslog_ident(const char *newval, void *extra)
2262 : {
2263 : #ifdef HAVE_SYSLOG
2264 : /*
2265 : * guc.c is likely to call us repeatedly with same parameters, so don't
2266 : * thrash the syslog connection unnecessarily. Also, we do not re-open
2267 : * the connection until needed, since this routine will get called whether
6385 bruce 2268 EUB : * or not Log_destination actually mentions syslog.
2269 : *
6347 2270 : * Note that we make our own copy of the ident string rather than relying
2271 : * on guc.c's. This may be overly paranoid, but it ensures that we cannot
6386 tgl 2272 : * accidentally free a string that syslog is still using.
2273 : */
208 tgl 2274 GNC 1857 : if (syslog_ident == NULL || strcmp(syslog_ident, newval) != 0)
2275 : {
6386 tgl 2276 GIC 1857 : if (openlog_done)
6386 tgl 2277 EUB : {
6386 tgl 2278 UBC 0 : closelog();
6386 tgl 2279 UIC 0 : openlog_done = false;
2280 : }
297 peter 2281 GNC 1857 : free(syslog_ident);
208 tgl 2282 1857 : syslog_ident = strdup(newval);
2283 : /* if the strdup fails, we will cope in write_syslog() */
2284 : }
2285 : #endif
2286 : /* Without syslog support, just ignore it */
208 tgl 2287 GBC 1857 : }
2288 :
2289 : /*
2290 : * GUC assign_hook for syslog_facility
2291 : */
2292 : void
208 tgl 2293 GNC 1857 : assign_syslog_facility(int newval, void *extra)
2294 : {
2295 : #ifdef HAVE_SYSLOG
2296 : /*
2297 : * As above, don't thrash the syslog connection unnecessarily.
2298 : */
2299 1857 : if (syslog_facility != newval)
2300 : {
208 tgl 2301 UNC 0 : if (openlog_done)
2302 : {
2303 0 : closelog();
2304 0 : openlog_done = false;
2305 : }
2306 0 : syslog_facility = newval;
2307 : }
2308 : #endif
2309 : /* Without syslog support, just ignore it */
6386 tgl 2310 GNC 1857 : }
2311 :
2312 : #ifdef HAVE_SYSLOG
2313 :
2314 : /*
6386 tgl 2315 EUB : * Write a message line to syslog
2316 : */
2317 : static void
8348 peter_e 2318 UIC 0 : write_syslog(int level, const char *line)
2319 : {
2320 : static unsigned long seq = 0;
2321 :
2322 : int len;
2323 : const char *nlpos;
2324 :
2325 : /* Open syslog connection if not done yet */
2326 0 : if (!openlog_done)
2327 : {
6386 tgl 2328 0 : openlog(syslog_ident ? syslog_ident : "postgres",
2329 : LOG_PID | LOG_NDELAY | LOG_NOWAIT,
2330 : syslog_facility);
8348 peter_e 2331 LBC 0 : openlog_done = true;
2332 : }
2333 :
2334 : /*
2335 : * We add a sequence number to each log message to suppress "same"
2336 : * messages.
2337 : */
8348 peter_e 2338 UIC 0 : seq++;
8348 peter_e 2339 ECB :
2340 : /*
6385 bruce 2341 : * Our problem here is that many syslog implementations don't handle long
2342 : * messages in an acceptable manner. While this function doesn't help that
2343 : * fact, it does work around by splitting up messages into smaller pieces.
2344 : *
2345 : * We divide into multiple syslog() calls if message is too long or if the
2346 : * message contains embedded newline(s).
6386 tgl 2347 : */
6386 tgl 2348 UIC 0 : len = strlen(line);
5388 2349 0 : nlpos = strchr(line, '\n');
2581 peter_e 2350 0 : if (syslog_split_messages && (len > PG_SYSLOG_LIMIT || nlpos != NULL))
8348 2351 0 : {
8053 bruce 2352 0 : int chunk_nr = 0;
2353 :
8348 peter_e 2354 0 : while (len > 0)
2355 : {
2356 : char buf[PG_SYSLOG_LIMIT + 1];
8053 bruce 2357 ECB : int buflen;
2358 : int i;
8164 tgl 2359 :
8170 bruce 2360 : /* if we start at a newline, move ahead one char */
8170 bruce 2361 UIC 0 : if (line[0] == '\n')
2362 : {
2363 0 : line++;
2364 0 : len--;
2365 : /* we need to recompute the next newline's position, too */
5388 tgl 2366 0 : nlpos = strchr(line, '\n');
8164 2367 0 : continue;
8170 bruce 2368 ECB : }
8348 peter_e 2369 :
2370 : /* copy one line, or as much as will fit, to buf */
6038 tgl 2371 UIC 0 : if (nlpos != NULL)
2372 0 : buflen = nlpos - line;
2373 : else
2374 0 : buflen = len;
6038 tgl 2375 LBC 0 : buflen = Min(buflen, PG_SYSLOG_LIMIT);
6038 tgl 2376 UIC 0 : memcpy(buf, line, buflen);
2377 0 : buf[buflen] = '\0';
2378 :
2379 : /* trim to multibyte letter boundary */
7290 2380 0 : buflen = pg_mbcliplen(buf, buflen, buflen);
8082 ishii 2381 0 : if (buflen <= 0)
8053 bruce 2382 0 : return;
8348 peter_e 2383 LBC 0 : buf[buflen] = '\0';
2384 :
2385 : /* already word boundary? */
6386 tgl 2386 UIC 0 : if (line[buflen] != '\0' &&
2387 0 : !isspace((unsigned char) line[buflen]))
8348 peter_e 2388 ECB : {
2389 : /* try to divide at word boundary */
7290 tgl 2390 UIC 0 : i = buflen - 1;
8162 2391 0 : while (i > 0 && !isspace((unsigned char) buf[i]))
8348 peter_e 2392 0 : i--;
2393 :
7290 tgl 2394 0 : if (i > 0) /* else couldn't divide word boundary */
8348 peter_e 2395 EUB : {
8348 peter_e 2396 UIC 0 : buflen = i;
8348 peter_e 2397 UBC 0 : buf[i] = '\0';
2398 : }
2399 : }
8348 peter_e 2400 EUB :
8348 peter_e 2401 UBC 0 : chunk_nr++;
2402 :
2599 peter_e 2403 UIC 0 : if (syslog_sequence_numbers)
2404 0 : syslog(level, "[%lu-%d] %s", seq, chunk_nr, buf);
2405 : else
2599 peter_e 2406 UBC 0 : syslog(level, "[%d] %s", chunk_nr, buf);
2599 peter_e 2407 EUB :
8348 peter_e 2408 UIC 0 : line += buflen;
2409 0 : len -= buflen;
2410 : }
2411 : }
2412 : else
2413 : {
2414 : /* message short enough */
2599 2415 0 : if (syslog_sequence_numbers)
2416 0 : syslog(level, "[%lu] %s", seq, line);
2417 : else
2599 peter_e 2418 UBC 0 : syslog(level, "%s", line);
8164 tgl 2419 EUB : }
8348 peter_e 2420 : }
2421 : #endif /* HAVE_SYSLOG */
2422 :
2423 : #ifdef WIN32
2424 : /*
3574 noah 2425 ECB : * Get the PostgreSQL equivalent of the Windows ANSI code page. "ANSI" system
2426 : * interfaces (e.g. CreateFileA()) expect string arguments in this encoding.
2427 : * Every process in a given system will find the same value at all times.
2428 : */
2429 : static int
2430 : GetACPEncoding(void)
2431 : {
2432 : static int encoding = -2;
2433 :
2434 : if (encoding == -2)
2435 : encoding = pg_codepage_to_encoding(GetACP());
2436 :
2437 : return encoding;
2438 : }
2439 :
2440 : /*
6943 bruce 2441 : * Write a message line to the windows event log
2442 : */
2443 : static void
2444 : write_eventlog(int level, const char *line, int len)
2445 : {
2446 : WCHAR *utf16;
2447 : int eventlevel = EVENTLOG_ERROR_TYPE;
2448 : static HANDLE evtHandle = INVALID_HANDLE_VALUE;
2449 :
2450 : if (evtHandle == INVALID_HANDLE_VALUE)
6797 2451 : {
2452 : evtHandle = RegisterEventSource(NULL,
2453 : event_source ? event_source : DEFAULT_EVENT_SOURCE);
2454 : if (evtHandle == NULL)
2455 : {
6943 2456 : evtHandle = INVALID_HANDLE_VALUE;
2457 : return;
6943 bruce 2458 EUB : }
2459 : }
2460 :
2461 : switch (level)
6449 bruce 2462 ECB : {
2463 : case DEBUG5:
2464 : case DEBUG4:
2465 : case DEBUG3:
2466 : case DEBUG2:
2467 : case DEBUG1:
2468 : case LOG:
2469 : case LOG_SERVER_ONLY:
2470 : case INFO:
2471 : case NOTICE:
2472 : eventlevel = EVENTLOG_INFORMATION_TYPE;
6449 bruce 2473 EUB : break;
2474 : case WARNING:
2475 : case WARNING_CLIENT_ONLY:
2476 : eventlevel = EVENTLOG_WARNING_TYPE;
2477 : break;
2478 : case ERROR:
2479 : case FATAL:
2480 : case PANIC:
2481 : default:
2482 : eventlevel = EVENTLOG_ERROR_TYPE;
2483 : break;
2484 : }
2485 :
2486 : /*
3574 noah 2487 : * If message character encoding matches the encoding expected by
2488 : * ReportEventA(), call it to avoid the hazards of conversion. Otherwise,
2489 : * try to convert the message to UTF16 and write it with ReportEventW().
2490 : * Fall back on ReportEventA() if conversion failed.
4922 magnus 2491 : *
2492 : * Since we palloc the structure required for conversion, also fall
2493 : * through to writing unconverted if we have not yet set up
2494 : * CurrentMemoryContext.
2495 : *
2496 : * Also verify that we are not on our way into error recursion trouble due
2497 : * to error messages thrown deep inside pgwin32_message_to_UTF16().
4922 magnus 2498 ECB : */
2499 : if (!in_error_recursion_trouble() &&
1974 noah 2500 : CurrentMemoryContext != NULL &&
3574 2501 : GetMessageEncoding() != GetACPEncoding())
2502 : {
2503 : utf16 = pgwin32_message_to_UTF16(line, len, NULL);
2504 : if (utf16)
2505 : {
2506 : ReportEventW(evtHandle,
4790 bruce 2507 : eventlevel,
2508 : 0,
2509 : 0, /* All events are Id 0 */
2510 : NULL,
2511 : 1,
2512 : 0,
2513 : (LPCWSTR *) &utf16,
2514 : NULL);
2515 : /* XXX Try ReportEventA() when ReportEventW() fails? */
4922 magnus 2516 :
2517 : pfree(utf16);
2518 : return;
2519 : }
2520 : }
2521 : ReportEventA(evtHandle,
4790 bruce 2522 EUB : eventlevel,
2523 : 0,
2524 : 0, /* All events are Id 0 */
2525 : NULL,
2526 : 1,
2527 : 0,
4790 bruce 2528 ECB : &line,
2529 : NULL);
6943 2530 : }
2531 : #endif /* WIN32 */
7290 tgl 2532 :
4922 magnus 2533 : static void
4922 magnus 2534 CBC 187451 : write_console(const char *line, int len)
4922 magnus 2535 ECB : {
4191 tgl 2536 : int rc;
2537 :
2538 : #ifdef WIN32
3260 bruce 2539 EUB :
4922 magnus 2540 : /*
2541 : * Try to convert the message to UTF16 and write it with WriteConsoleW().
2542 : * Fall back on write() if anything fails.
2543 : *
2544 : * In contrast to write_eventlog(), don't skip straight to write() based
2545 : * on the applicable encodings. Unlike WriteConsoleW(), write() depends
2546 : * on the suitability of the console output code page. Since we put
2547 : * stderr into binary mode in SubPostmasterMain(), write() skips the
3574 noah 2548 : * necessary translation anyway.
2549 : *
2550 : * WriteConsoleW() will fail if stderr is redirected, so just fall through
4922 magnus 2551 : * to writing unconverted to the logfile in this case.
2552 : *
2553 : * Since we palloc the structure required for conversion, also fall
2554 : * through to writing unconverted if we have not yet set up
4382 bruce 2555 ECB : * CurrentMemoryContext.
4922 magnus 2556 : */
2557 : if (!in_error_recursion_trouble() &&
4391 2558 : !redirection_done &&
2559 : CurrentMemoryContext != NULL)
4922 2560 : {
2561 : WCHAR *utf16;
2562 : int utf16len;
2563 :
2564 : utf16 = pgwin32_message_to_UTF16(line, len, &utf16len);
2565 : if (utf16 != NULL)
2566 : {
2567 : HANDLE stdHandle;
2568 : DWORD written;
2569 :
2570 : stdHandle = GetStdHandle(STD_ERROR_HANDLE);
2571 : if (WriteConsoleW(stdHandle, utf16, utf16len, &written, NULL))
2572 : {
2573 : pfree(utf16);
2574 : return;
2575 : }
2576 :
2577 : /*
4790 bruce 2578 : * In case WriteConsoleW() failed, fall back to writing the
2579 : * message unconverted.
2580 : */
2581 : pfree(utf16);
2582 : }
2583 : }
2584 : #else
2585 :
2586 : /*
2587 : * Conversion on non-win32 platforms is not implemented yet. It requires
2588 : * non-throw version of pg_do_encoding_conversion(), that converts
2589 : * unconvertible characters to '?' without errors.
2590 : *
738 heikki.linnakangas 2591 : * XXX: We have a no-throw version now. It doesn't convert to '?' though.
2592 : */
4922 magnus 2593 : #endif
2594 :
4191 tgl 2595 EUB : /*
2596 : * We ignore any error from write() here. We have no useful way to report
2597 : * it ... certainly whining on stderr isn't likely to be productive.
4191 tgl 2598 ECB : */
4191 tgl 2599 CBC 187451 : rc = write(fileno(stderr), line, len);
2600 : (void) rc;
4922 magnus 2601 GIC 187451 : }
2602 :
2603 : /*
452 michael 2604 ECB : * get_formatted_log_time -- compute and get the log timestamp.
2605 : *
2606 : * The timestamp is computed if not set yet, so as it is kept consistent
2607 : * among all the log destinations that require it to be consistent. Note
2608 : * that the computed timestamp is returned in a static buffer, not
2609 : * palloc()'d.
5287 alvherre 2610 : */
2611 : char *
452 michael 2612 GIC 230494 : get_formatted_log_time(void)
2613 : {
2614 : pg_time_t stamp_time;
2615 : char msbuf[13];
5287 alvherre 2616 ECB :
2617 : /* leave if already computed */
452 michael 2618 GBC 230494 : if (formatted_log_time[0] != '\0')
452 michael 2619 GIC 40 : return formatted_log_time;
452 michael 2620 EUB :
2771 jdavis 2621 GBC 230454 : if (!saved_timeval_set)
2622 : {
2623 187471 : gettimeofday(&saved_timeval, NULL);
2771 jdavis 2624 GIC 187471 : saved_timeval_set = true;
2625 : }
2626 :
2771 jdavis 2627 CBC 230454 : stamp_time = (pg_time_t) saved_timeval.tv_sec;
2628 :
2629 : /*
2630 : * Note: we expect that guc.c will ensure that log_timezone is set up (at
2631 : * least with a minimal GMT value) before Log_line_prefix can become
2632 : * nonempty or CSV mode can be selected.
2633 : */
5287 alvherre 2634 GIC 230454 : pg_strftime(formatted_log_time, FORMATTED_TS_LEN,
5050 bruce 2635 EUB : /* leave room for milliseconds... */
2636 : "%Y-%m-%d %H:%M:%S %Z",
4230 tgl 2637 GIC 230454 : pg_localtime(&stamp_time, log_timezone));
2638 :
2639 : /* 'paste' milliseconds into place... */
2771 jdavis 2640 230454 : sprintf(msbuf, ".%03d", (int) (saved_timeval.tv_usec / 1000));
2997 tgl 2641 230454 : memcpy(formatted_log_time + 19, msbuf, 4);
2642 :
452 michael 2643 GBC 230454 : return formatted_log_time;
2644 : }
5287 alvherre 2645 EUB :
2646 : /*
2647 : * reset_formatted_start_time -- reset the start timestamp
2648 : */
2649 : void
452 michael 2650 GIC 10432 : reset_formatted_start_time(void)
2651 : {
2652 10432 : formatted_start_time[0] = '\0';
2653 10432 : }
2654 :
452 michael 2655 EUB : /*
2656 : * get_formatted_start_time -- compute and get the start timestamp.
2657 : *
2658 : * The timestamp is computed if not set yet. Note that the computed
2659 : * timestamp is returned in a static buffer, not palloc()'d.
2660 : */
2661 : char *
452 michael 2662 GIC 40 : get_formatted_start_time(void)
2663 : {
5287 alvherre 2664 40 : pg_time_t stamp_time = (pg_time_t) MyStartTime;
5287 alvherre 2665 EUB :
452 michael 2666 : /* leave if already computed */
452 michael 2667 GBC 40 : if (formatted_start_time[0] != '\0')
2668 18 : return formatted_start_time;
452 michael 2669 EUB :
2670 : /*
3955 bruce 2671 : * Note: we expect that guc.c will ensure that log_timezone is set up (at
2672 : * least with a minimal GMT value) before Log_line_prefix can become
2673 : * nonempty or CSV mode can be selected.
2674 : */
5287 alvherre 2675 GIC 22 : pg_strftime(formatted_start_time, FORMATTED_TS_LEN,
2676 : "%Y-%m-%d %H:%M:%S %Z",
4230 tgl 2677 22 : pg_localtime(&stamp_time, log_timezone));
452 michael 2678 EUB :
452 michael 2679 GIC 22 : return formatted_start_time;
452 michael 2680 EUB : }
2681 :
2682 : /*
2683 : * check_log_of_query -- check if a query can be logged
2684 : */
2685 : bool
452 michael 2686 GIC 187511 : check_log_of_query(ErrorData *edata)
2687 : {
452 michael 2688 EUB : /* log required? */
452 michael 2689 GBC 187511 : if (!is_log_level_output(edata->elevel, log_min_error_statement))
452 michael 2690 GIC 7547 : return false;
452 michael 2691 EUB :
2692 : /* query log wanted? */
452 michael 2693 GBC 179964 : if (edata->hide_stmt)
2694 147991 : return false;
2695 :
2696 : /* query string available? */
2697 31973 : if (debug_query_string == NULL)
2698 10559 : return false;
452 michael 2699 EUB :
452 michael 2700 GBC 21414 : return true;
2701 : }
2702 :
452 michael 2703 EUB : /*
2704 : * get_backend_type_for_log -- backend type for log entries
2705 : *
2706 : * Returns a pointer to a static buffer, not palloc()'d.
2707 : */
2708 : const char *
452 michael 2709 GBC 21367 : get_backend_type_for_log(void)
2710 : {
452 michael 2711 EUB : const char *backend_type_str;
2712 :
452 michael 2713 GBC 21367 : if (MyProcPid == PostmasterPid)
2714 600 : backend_type_str = "postmaster";
452 michael 2715 GIC 20767 : else if (MyBackendType == B_BG_WORKER)
2716 39 : backend_type_str = MyBgworkerEntry->bgw_type;
2717 : else
452 michael 2718 GBC 20728 : backend_type_str = GetBackendTypeDesc(MyBackendType);
2719 :
2720 21367 : return backend_type_str;
5287 alvherre 2721 EUB : }
2722 :
3482 rhaas 2723 : /*
2724 : * process_log_prefix_padding --- helper function for processing the format
2725 : * string in log_line_prefix
2726 : *
2727 : * Note: This function returns NULL if it finds something which
2728 : * it deems invalid in the format string.
2729 : */
2730 : static const char *
3482 rhaas 2731 UIC 0 : process_log_prefix_padding(const char *p, int *ppadding)
3482 rhaas 2732 EUB : {
3260 bruce 2733 UBC 0 : int paddingsign = 1;
3260 bruce 2734 UIC 0 : int padding = 0;
3482 rhaas 2735 EUB :
3482 rhaas 2736 UIC 0 : if (*p == '-')
2737 : {
2738 0 : p++;
2739 :
3260 bruce 2740 0 : if (*p == '\0') /* Did the buf end in %- ? */
3482 rhaas 2741 0 : return NULL;
2742 0 : paddingsign = -1;
2743 : }
2744 :
2745 : /* generate an int version of the numerical string */
2746 0 : while (*p >= '0' && *p <= '9')
2747 0 : padding = padding * 10 + (*p++ - '0');
2748 :
2749 : /* format is invalid if it ends with the padding number */
2750 0 : if (*p == '\0')
2751 0 : return NULL;
2752 :
2753 0 : padding *= paddingsign;
2754 0 : *ppadding = padding;
2755 0 : return p;
2756 : }
2757 :
2758 : /*
2759 : * Format log status information using Log_line_prefix.
2760 : */
2761 : static void
5028 peter_e 2762 GIC 230454 : log_line_prefix(StringInfo buf, ErrorData *edata)
2763 : {
272 jdavis 2764 GNC 230454 : log_status_format(buf, Log_line_prefix, edata);
2765 230454 : }
2766 :
2767 : /*
2768 : * Format log status info; append to the provided buffer.
2769 : */
2770 : void
2771 230454 : log_status_format(StringInfo buf, const char *format, ErrorData *edata)
2772 : {
2773 : /* static counter for line numbers */
2774 : static long log_line_number = 0;
2775 :
2776 : /* has counter been reset in current process? */
2777 : static int log_my_pid = 0;
2778 : int padding;
2779 : const char *p;
2780 :
2781 : /*
2782 : * This is one of the few places where we'd rather not inherit a static
2783 : * variable's value from the postmaster. But since we will, reset it when
2784 : * MyProcPid changes. MyStartTime also changes when MyProcPid does, so
2785 : * reset the formatted start timestamp too.
2786 : */
6960 tgl 2787 GIC 230454 : if (log_my_pid != MyProcPid)
2788 : {
2789 10410 : log_line_number = 0;
2790 10410 : log_my_pid = MyProcPid;
452 michael 2791 10410 : reset_formatted_start_time();
2792 : }
6960 tgl 2793 230454 : log_line_number++;
2794 :
272 jdavis 2795 GNC 230454 : if (format == NULL)
6960 tgl 2796 GIC 15890 : return; /* in case guc hasn't run yet */
2797 :
272 jdavis 2798 GNC 2276145 : for (p = format; *p != '\0'; p++)
2799 : {
3482 rhaas 2800 GIC 2061581 : if (*p != '%')
2801 : {
2802 : /* literal char, just copy */
2803 1135696 : appendStringInfoChar(buf, *p);
6960 tgl 2804 1135696 : continue;
2805 : }
2806 :
2807 : /* must be a '%', so skip to the next char */
3482 rhaas 2808 925885 : p++;
2809 925885 : if (*p == '\0')
6512 tgl 2810 UIC 0 : break; /* format error - ignore it */
3482 rhaas 2811 GIC 925885 : else if (*p == '%')
2812 : {
2813 : /* string contains %% */
3482 rhaas 2814 UIC 0 : appendStringInfoChar(buf, '%');
2815 0 : continue;
2816 : }
2817 :
2818 :
2819 : /*
2820 : * Process any formatting which may exist after the '%'. Note that
2821 : * process_log_prefix_padding moves p past the padding number if it
2822 : * exists.
2823 : *
2824 : * Note: Since only '-', '0' to '9' are valid formatting characters we
2825 : * can do a quick check here to pre-check for formatting. If the char
2826 : * is not formatting then we can skip a useless function call.
2827 : *
2828 : * Further note: At least on some platforms, passing %*s rather than
2829 : * %s to appendStringInfo() is substantially slower, so many of the
2830 : * cases below avoid doing that unless non-zero padding is in fact
2831 : * specified.
2832 : */
3482 rhaas 2833 GIC 925885 : if (*p > '9')
2834 925885 : padding = 0;
3482 rhaas 2835 UIC 0 : else if ((p = process_log_prefix_padding(p, &padding)) == NULL)
2836 0 : break;
2837 :
2838 : /* process the option */
3482 rhaas 2839 GIC 925885 : switch (*p)
2840 : {
4880 tgl 2841 213880 : case 'a':
2842 213880 : if (MyProcPort)
2843 : {
2844 213880 : const char *appname = application_name;
2845 :
2846 213880 : if (appname == NULL || *appname == '\0')
2847 923 : appname = _("[unknown]");
3482 rhaas 2848 213880 : if (padding != 0)
3482 rhaas 2849 UIC 0 : appendStringInfo(buf, "%*s", padding, appname);
2850 : else
3482 rhaas 2851 GIC 213880 : appendStringInfoString(buf, appname);
2852 : }
3482 rhaas 2853 UIC 0 : else if (padding != 0)
2854 0 : appendStringInfoSpaces(buf,
2855 : padding > 0 ? padding : -padding);
2856 :
4880 tgl 2857 GIC 213880 : break;
1120 peter 2858 21327 : case 'b':
2859 : {
452 michael 2860 CBC 21327 : const char *backend_type_str = get_backend_type_for_log();
2861 :
1120 peter 2862 GIC 21327 : if (padding != 0)
1120 peter 2863 UIC 0 : appendStringInfo(buf, "%*s", padding, backend_type_str);
2864 : else
1120 peter 2865 GIC 21327 : appendStringInfoString(buf, backend_type_str);
2866 21327 : break;
2867 : }
6960 tgl 2868 UIC 0 : case 'u':
2869 0 : if (MyProcPort)
2870 : {
2871 0 : const char *username = MyProcPort->user_name;
2872 :
2873 0 : if (username == NULL || *username == '\0')
6620 bruce 2874 0 : username = _("[unknown]");
3482 rhaas 2875 0 : if (padding != 0)
2876 0 : appendStringInfo(buf, "%*s", padding, username);
2877 : else
2878 0 : appendStringInfoString(buf, username);
2879 : }
2880 0 : else if (padding != 0)
2881 0 : appendStringInfoSpaces(buf,
2882 : padding > 0 ? padding : -padding);
6960 tgl 2883 0 : break;
6797 bruce 2884 0 : case 'd':
6960 tgl 2885 0 : if (MyProcPort)
2886 : {
2887 0 : const char *dbname = MyProcPort->database_name;
2888 :
2889 0 : if (dbname == NULL || *dbname == '\0')
6620 bruce 2890 0 : dbname = _("[unknown]");
3482 rhaas 2891 0 : if (padding != 0)
2892 0 : appendStringInfo(buf, "%*s", padding, dbname);
2893 : else
2894 0 : appendStringInfoString(buf, dbname);
2895 : }
2896 0 : else if (padding != 0)
2897 0 : appendStringInfoSpaces(buf,
2898 : padding > 0 ? padding : -padding);
6960 tgl 2899 0 : break;
2900 0 : case 'c':
3482 rhaas 2901 0 : if (padding != 0)
2902 : {
2903 : char strfbuf[128];
2904 :
3437 peter_e 2905 0 : snprintf(strfbuf, sizeof(strfbuf) - 1, "%lx.%x",
2906 : (long) (MyStartTime), MyProcPid);
3482 rhaas 2907 0 : appendStringInfo(buf, "%*s", padding, strfbuf);
2908 : }
2909 : else
2910 0 : appendStringInfo(buf, "%lx.%x", (long) (MyStartTime), MyProcPid);
6960 tgl 2911 0 : break;
6960 tgl 2912 GIC 230454 : case 'p':
3482 rhaas 2913 230454 : if (padding != 0)
3482 rhaas 2914 UIC 0 : appendStringInfo(buf, "%*d", padding, MyProcPid);
2915 : else
3482 rhaas 2916 GIC 230454 : appendStringInfo(buf, "%d", MyProcPid);
6960 tgl 2917 230454 : break;
2918 :
979 michael 2919 UIC 0 : case 'P':
2920 0 : if (MyProc)
2921 : {
2922 0 : PGPROC *leader = MyProc->lockGroupLeader;
2923 :
2924 : /*
979 michael 2925 ECB : * Show the leader only for active parallel workers. This
2926 : * leaves out the leader of a parallel group.
2927 : */
979 michael 2928 UIC 0 : if (leader == NULL || leader->pid == MyProcPid)
2929 0 : appendStringInfoSpaces(buf,
2930 : padding > 0 ? padding : -padding);
2931 0 : else if (padding != 0)
2932 0 : appendStringInfo(buf, "%*d", padding, leader->pid);
2933 : else
2934 0 : appendStringInfo(buf, "%d", leader->pid);
2935 : }
2936 0 : else if (padding != 0)
2937 0 : appendStringInfoSpaces(buf,
979 michael 2938 ECB : padding > 0 ? padding : -padding);
979 michael 2939 UIC 0 : break;
2940 :
6960 tgl 2941 0 : case 'l':
3482 rhaas 2942 0 : if (padding != 0)
2943 0 : appendStringInfo(buf, "%*ld", padding, log_line_number);
3482 rhaas 2944 ECB : else
3482 rhaas 2945 LBC 0 : appendStringInfo(buf, "%ld", log_line_number);
6960 tgl 2946 UIC 0 : break;
6513 bruce 2947 CBC 230454 : case 'm':
2948 : /* force a log timestamp reset */
452 michael 2949 230454 : formatted_log_time[0] = '\0';
2950 230454 : (void) get_formatted_log_time();
2951 :
3482 rhaas 2952 GIC 230454 : if (padding != 0)
3482 rhaas 2953 LBC 0 : appendStringInfo(buf, "%*s", padding, formatted_log_time);
2954 : else
3482 rhaas 2955 GIC 230454 : appendStringInfoString(buf, formatted_log_time);
6513 bruce 2956 230454 : break;
6960 tgl 2957 UIC 0 : case 't':
2958 : {
5727 2959 0 : pg_time_t stamp_time = (pg_time_t) time(NULL);
6797 bruce 2960 ECB : char strfbuf[128];
2961 :
5727 tgl 2962 UIC 0 : pg_strftime(strfbuf, sizeof(strfbuf),
5727 tgl 2963 ECB : "%Y-%m-%d %H:%M:%S %Z",
4230 tgl 2964 UIC 0 : pg_localtime(&stamp_time, log_timezone));
3482 rhaas 2965 0 : if (padding != 0)
3482 rhaas 2966 LBC 0 : appendStringInfo(buf, "%*s", padding, strfbuf);
3482 rhaas 2967 ECB : else
3482 rhaas 2968 UIC 0 : appendStringInfoString(buf, strfbuf);
6960 tgl 2969 ECB : }
6960 tgl 2970 UIC 0 : break;
2771 jdavis 2971 0 : case 'n':
2972 : {
2973 : char strfbuf[128];
2974 :
2975 0 : if (!saved_timeval_set)
2771 jdavis 2976 ECB : {
2771 jdavis 2977 UIC 0 : gettimeofday(&saved_timeval, NULL);
2771 jdavis 2978 LBC 0 : saved_timeval_set = true;
2771 jdavis 2979 ECB : }
2980 :
2315 tgl 2981 UIC 0 : snprintf(strfbuf, sizeof(strfbuf), "%ld.%03d",
2982 0 : (long) saved_timeval.tv_sec,
2983 0 : (int) (saved_timeval.tv_usec / 1000));
2984 :
2771 jdavis 2985 0 : if (padding != 0)
2986 0 : appendStringInfo(buf, "%*s", padding, strfbuf);
2987 : else
2771 jdavis 2988 LBC 0 : appendStringInfoString(buf, strfbuf);
2989 : }
2990 0 : break;
6960 tgl 2991 UIC 0 : case 's':
2992 : {
452 michael 2993 LBC 0 : char *start_time = get_formatted_start_time();
452 michael 2994 ECB :
452 michael 2995 UIC 0 : if (padding != 0)
2996 0 : appendStringInfo(buf, "%*s", padding, start_time);
2997 : else
2998 0 : appendStringInfoString(buf, start_time);
2999 : }
6960 tgl 3000 0 : break;
6960 tgl 3001 LBC 0 : case 'i':
6960 tgl 3002 UIC 0 : if (MyProcPort)
6364 tgl 3003 ECB : {
3004 : const char *psdisp;
6347 bruce 3005 : int displen;
3006 :
6364 tgl 3007 UIC 0 : psdisp = get_ps_display(&displen);
3482 rhaas 3008 0 : if (padding != 0)
3009 0 : appendStringInfo(buf, "%*s", padding, psdisp);
3010 : else
3011 0 : appendBinaryStringInfo(buf, psdisp, displen);
6364 tgl 3012 ECB : }
3482 rhaas 3013 UIC 0 : else if (padding != 0)
3014 0 : appendStringInfoSpaces(buf,
3482 rhaas 3015 ECB : padding > 0 ? padding : -padding);
6960 tgl 3016 LBC 0 : break;
6960 tgl 3017 UIC 0 : case 'r':
6364 3018 0 : if (MyProcPort && MyProcPort->remote_host)
6960 tgl 3019 ECB : {
3437 peter_e 3020 LBC 0 : if (padding != 0)
3021 : {
3482 rhaas 3022 UIC 0 : if (MyProcPort->remote_port && MyProcPort->remote_port[0] != '\0')
3482 rhaas 3023 LBC 0 : {
3437 peter_e 3024 ECB : /*
3025 : * This option is slightly special as the port
3260 bruce 3026 : * number may be appended onto the end. Here we
3027 : * need to build 1 string which contains the
3028 : * remote_host and optionally the remote_port (if
3029 : * set) so we can properly align the string.
3030 : */
3031 :
3032 : char *hostport;
3033 :
3456 peter_e 3034 UIC 0 : hostport = psprintf("%s(%s)", MyProcPort->remote_host, MyProcPort->remote_port);
3482 rhaas 3035 LBC 0 : appendStringInfo(buf, "%*s", padding, hostport);
3482 rhaas 3036 UIC 0 : pfree(hostport);
3037 : }
3038 : else
3482 rhaas 3039 LBC 0 : appendStringInfo(buf, "%*s", padding, MyProcPort->remote_host);
3482 rhaas 3040 ECB : }
3041 : else
3042 : {
3043 : /* padding is 0, so we don't need a temp buffer */
3482 rhaas 3044 LBC 0 : appendStringInfoString(buf, MyProcPort->remote_host);
3482 rhaas 3045 UIC 0 : if (MyProcPort->remote_port &&
3482 rhaas 3046 LBC 0 : MyProcPort->remote_port[0] != '\0')
3437 peter_e 3047 UIC 0 : appendStringInfo(buf, "(%s)",
3260 bruce 3048 0 : MyProcPort->remote_port);
3049 : }
3050 : }
3482 rhaas 3051 0 : else if (padding != 0)
3052 0 : appendStringInfoSpaces(buf,
3053 : padding > 0 ? padding : -padding);
6960 tgl 3054 0 : break;
6513 bruce 3055 0 : case 'h':
3437 peter_e 3056 0 : if (MyProcPort && MyProcPort->remote_host)
3482 rhaas 3057 EUB : {
3482 rhaas 3058 UIC 0 : if (padding != 0)
3482 rhaas 3059 UBC 0 : appendStringInfo(buf, "%*s", padding, MyProcPort->remote_host);
3482 rhaas 3060 EUB : else
3482 rhaas 3061 UIC 0 : appendStringInfoString(buf, MyProcPort->remote_host);
3482 rhaas 3062 EUB : }
3482 rhaas 3063 UIC 0 : else if (padding != 0)
3482 rhaas 3064 UBC 0 : appendStringInfoSpaces(buf,
3065 : padding > 0 ? padding : -padding);
6513 bruce 3066 0 : break;
6773 neilc 3067 GBC 229770 : case 'q':
6773 neilc 3068 EUB : /* in postmaster and friends, stop if %q is seen */
3069 : /* in a backend, just ignore */
6960 tgl 3070 GIC 229770 : if (MyProcPort == NULL)
3482 rhaas 3071 15890 : return;
6960 tgl 3072 GBC 213880 : break;
5695 tgl 3073 UBC 0 : case 'v':
3074 : /* keep VXID format in sync with lockfuncs.c */
5205 bruce 3075 UIC 0 : if (MyProc != NULL && MyProc->backendId != InvalidBackendId)
3482 rhaas 3076 EUB : {
3482 rhaas 3077 UBC 0 : if (padding != 0)
3078 : {
3260 bruce 3079 EUB : char strfbuf[128];
3080 :
3482 rhaas 3081 UBC 0 : snprintf(strfbuf, sizeof(strfbuf) - 1, "%d/%u",
3260 bruce 3082 UIC 0 : MyProc->backendId, MyProc->lxid);
3482 rhaas 3083 0 : appendStringInfo(buf, "%*s", padding, strfbuf);
3084 : }
3085 : else
3086 0 : appendStringInfo(buf, "%d/%u", MyProc->backendId, MyProc->lxid);
3087 : }
3482 rhaas 3088 LBC 0 : else if (padding != 0)
3482 rhaas 3089 UIC 0 : appendStringInfoSpaces(buf,
3482 rhaas 3090 ECB : padding > 0 ? padding : -padding);
5695 tgl 3091 LBC 0 : break;
6773 neilc 3092 UIC 0 : case 'x':
3482 rhaas 3093 0 : if (padding != 0)
3094 0 : appendStringInfo(buf, "%*u", padding, GetTopTransactionIdIfAny());
3095 : else
3096 0 : appendStringInfo(buf, "%u", GetTopTransactionIdIfAny());
6773 neilc 3097 LBC 0 : break;
5028 peter_e 3098 UIC 0 : case 'e':
3482 rhaas 3099 0 : if (padding != 0)
3100 0 : appendStringInfo(buf, "%*s", padding, unpack_sql_state(edata->sqlerrcode));
3101 : else
3102 0 : appendStringInfoString(buf, unpack_sql_state(edata->sqlerrcode));
6960 tgl 3103 0 : break;
732 bruce 3104 0 : case 'Q':
3105 0 : if (padding != 0)
3106 0 : appendStringInfo(buf, "%*lld", padding,
697 tgl 3107 0 : (long long) pgstat_get_my_query_id());
3108 : else
732 bruce 3109 0 : appendStringInfo(buf, "%lld",
697 tgl 3110 0 : (long long) pgstat_get_my_query_id());
732 bruce 3111 0 : break;
6960 tgl 3112 0 : default:
6960 tgl 3113 ECB : /* format error - ignore it */
6960 tgl 3114 UIC 0 : break;
6970 bruce 3115 ECB : }
3116 : }
3117 : }
3118 :
6512 neilc 3119 : /*
3120 : * Unpack MAKE_SQLSTATE code. Note that this returns a pointer to a
3121 : * static buffer.
3122 : */
3123 : char *
6512 neilc 3124 CBC 42102 : unpack_sql_state(int sql_state)
3125 : {
6385 bruce 3126 ECB : static char buf[12];
3127 : int i;
3128 :
6512 neilc 3129 CBC 252612 : for (i = 0; i < 5; i++)
6512 neilc 3130 ECB : {
6512 neilc 3131 GIC 210510 : buf[i] = PGUNSIXBIT(sql_state);
3132 210510 : sql_state >>= 6;
3133 : }
6512 neilc 3134 ECB :
6512 neilc 3135 CBC 42102 : buf[i] = '\0';
6512 neilc 3136 GBC 42102 : return buf;
6512 neilc 3137 ECB : }
3138 :
3139 :
7290 tgl 3140 EUB : /*
3141 : * Write error report to server's log
3142 : */
3143 : static void
7184 bruce 3144 GIC 187471 : send_message_to_server_log(ErrorData *edata)
3145 : {
3146 : StringInfoData buf;
548 michael 3147 187471 : bool fallback_to_stderr = false;
3148 :
7290 tgl 3149 187471 : initStringInfo(&buf);
3150 :
2771 jdavis 3151 187471 : saved_timeval_set = false;
5712 andrew 3152 187471 : formatted_log_time[0] = '\0';
3153 :
5028 peter_e 3154 187471 : log_line_prefix(&buf, edata);
2417 tgl 3155 187471 : appendStringInfo(&buf, "%s: ", _(error_severity(edata->elevel)));
3156 :
7223 3157 187471 : if (Log_error_verbosity >= PGERROR_VERBOSE)
6512 neilc 3158 4691 : appendStringInfo(&buf, "%s: ", unpack_sql_state(edata->sqlerrcode));
7223 tgl 3159 ECB :
7290 tgl 3160 CBC 187471 : if (edata->message)
7114 tgl 3161 GBC 187471 : append_with_tabs(&buf, edata->message);
7290 tgl 3162 EUB : else
6620 bruce 3163 UIC 0 : append_with_tabs(&buf, _("missing error text"));
3164 :
7223 tgl 3165 CBC 187471 : if (edata->cursorpos > 0)
6620 bruce 3166 GIC 4499 : appendStringInfo(&buf, _(" at character %d"),
6958 tgl 3167 ECB : edata->cursorpos);
6958 tgl 3168 CBC 182972 : else if (edata->internalpos > 0)
6620 bruce 3169 GIC 44 : appendStringInfo(&buf, _(" at character %d"),
6958 tgl 3170 ECB : edata->internalpos);
3171 :
7223 tgl 3172 CBC 187471 : appendStringInfoChar(&buf, '\n');
7223 tgl 3173 ECB :
7223 tgl 3174 CBC 187471 : if (Log_error_verbosity >= PGERROR_DEFAULT)
7223 tgl 3175 EUB : {
5494 tgl 3176 GIC 187471 : if (edata->detail_log)
5494 tgl 3177 ECB : {
5028 peter_e 3178 GIC 274 : log_line_prefix(&buf, edata);
5494 tgl 3179 GBC 274 : appendStringInfoString(&buf, _("DETAIL: "));
3180 274 : append_with_tabs(&buf, edata->detail_log);
5494 tgl 3181 GIC 274 : appendStringInfoChar(&buf, '\n');
3182 : }
5494 tgl 3183 CBC 187197 : else if (edata->detail)
7114 tgl 3184 ECB : {
5028 peter_e 3185 GIC 11929 : log_line_prefix(&buf, edata);
6620 bruce 3186 CBC 11929 : appendStringInfoString(&buf, _("DETAIL: "));
7114 tgl 3187 GIC 11929 : append_with_tabs(&buf, edata->detail);
7114 tgl 3188 CBC 11929 : appendStringInfoChar(&buf, '\n');
7114 tgl 3189 EUB : }
7223 tgl 3190 GIC 187471 : if (edata->hint)
7114 tgl 3191 ECB : {
5028 peter_e 3192 CBC 2199 : log_line_prefix(&buf, edata);
6620 bruce 3193 GIC 2199 : appendStringInfoString(&buf, _("HINT: "));
7114 tgl 3194 GBC 2199 : append_with_tabs(&buf, edata->hint);
3195 2199 : appendStringInfoChar(&buf, '\n');
3196 : }
6958 3197 187471 : if (edata->internalquery)
3198 : {
5028 peter_e 3199 44 : log_line_prefix(&buf, edata);
6620 bruce 3200 44 : appendStringInfoString(&buf, _("QUERY: "));
6958 tgl 3201 44 : append_with_tabs(&buf, edata->internalquery);
3202 44 : appendStringInfoChar(&buf, '\n');
3203 : }
3027 andres 3204 187471 : if (edata->context && !edata->hide_ctx)
3205 : {
5028 peter_e 3206 2436 : log_line_prefix(&buf, edata);
6620 bruce 3207 2436 : appendStringInfoString(&buf, _("CONTEXT: "));
7114 tgl 3208 GIC 2436 : append_with_tabs(&buf, edata->context);
7114 tgl 3209 GBC 2436 : appendStringInfoChar(&buf, '\n');
7114 tgl 3210 EUB : }
7223 tgl 3211 GBC 187471 : if (Log_error_verbosity >= PGERROR_VERBOSE)
3212 : {
7114 tgl 3213 EUB : /* assume no newlines in funcname or filename... */
7223 tgl 3214 GIC 4691 : if (edata->funcname && edata->filename)
6960 tgl 3215 EUB : {
5028 peter_e 3216 GBC 4691 : log_line_prefix(&buf, edata);
6620 bruce 3217 4691 : appendStringInfo(&buf, _("LOCATION: %s, %s:%d\n"),
7223 tgl 3218 EUB : edata->funcname, edata->filename,
3219 : edata->lineno);
6960 3220 : }
7223 tgl 3221 UIC 0 : else if (edata->filename)
6960 tgl 3222 EUB : {
5028 peter_e 3223 UBC 0 : log_line_prefix(&buf, edata);
6620 bruce 3224 UIC 0 : appendStringInfo(&buf, _("LOCATION: %s:%d\n"),
7223 tgl 3225 EUB : edata->filename, edata->lineno);
6960 3226 : }
7223 3227 : }
1003 peter 3228 GIC 187471 : if (edata->backtrace)
3229 : {
1003 peter 3230 UIC 0 : log_line_prefix(&buf, edata);
1003 peter 3231 UBC 0 : appendStringInfoString(&buf, _("BACKTRACE: "));
1003 peter 3232 UIC 0 : append_with_tabs(&buf, edata->backtrace);
1003 peter 3233 UBC 0 : appendStringInfoChar(&buf, '\n');
3234 : }
3235 : }
7290 tgl 3236 EUB :
3237 : /*
6385 bruce 3238 ECB : * If the user wants the query that generated this error logged, do it.
7290 tgl 3239 : */
452 michael 3240 GBC 187471 : if (check_log_of_query(edata))
3241 : {
5028 peter_e 3242 CBC 21410 : log_line_prefix(&buf, edata);
6620 bruce 3243 21410 : appendStringInfoString(&buf, _("STATEMENT: "));
7114 tgl 3244 GIC 21410 : append_with_tabs(&buf, debug_query_string);
7114 tgl 3245 GBC 21410 : appendStringInfoChar(&buf, '\n');
7114 tgl 3246 EUB : }
3247 :
7290 3248 : #ifdef HAVE_SYSLOG
3249 : /* Write to syslog, if enabled */
6943 bruce 3250 GIC 187471 : if (Log_destination & LOG_DESTINATION_SYSLOG)
3251 : {
3252 : int syslog_level;
3253 :
7290 tgl 3254 UBC 0 : switch (edata->elevel)
7290 tgl 3255 EUB : {
7290 tgl 3256 UIC 0 : case DEBUG5:
7290 tgl 3257 EUB : case DEBUG4:
3258 : case DEBUG3:
3259 : case DEBUG2:
3260 : case DEBUG1:
7290 tgl 3261 UIC 0 : syslog_level = LOG_DEBUG;
7290 tgl 3262 UBC 0 : break;
3263 0 : case LOG:
3264 : case LOG_SERVER_ONLY:
7290 tgl 3265 EUB : case INFO:
7290 tgl 3266 UIC 0 : syslog_level = LOG_INFO;
7290 tgl 3267 UBC 0 : break;
3268 0 : case NOTICE:
7290 tgl 3269 EUB : case WARNING:
3270 : case WARNING_CLIENT_ONLY:
7290 tgl 3271 UBC 0 : syslog_level = LOG_NOTICE;
3272 0 : break;
7290 tgl 3273 LBC 0 : case ERROR:
7290 tgl 3274 UIC 0 : syslog_level = LOG_WARNING;
7290 tgl 3275 LBC 0 : break;
3276 0 : case FATAL:
7290 tgl 3277 UIC 0 : syslog_level = LOG_ERR;
7290 tgl 3278 LBC 0 : break;
7290 tgl 3279 UBC 0 : case PANIC:
3280 : default:
7290 tgl 3281 LBC 0 : syslog_level = LOG_CRIT;
3282 0 : break;
7290 tgl 3283 EUB : }
3284 :
7290 tgl 3285 UBC 0 : write_syslog(syslog_level, buf.data);
3286 : }
3287 : #endif /* HAVE_SYSLOG */
6602 tgl 3288 EUB :
3289 : #ifdef WIN32
3290 : /* Write to eventlog, if enabled */
6943 bruce 3291 : if (Log_destination & LOG_DESTINATION_EVENTLOG)
3292 : {
3293 : write_eventlog(edata->elevel, buf.data, buf.len);
3294 : }
3295 : #endif /* WIN32 */
6602 tgl 3296 :
548 michael 3297 : /* Write to csvlog, if enabled */
548 michael 3298 GIC 187471 : if (Log_destination & LOG_DESTINATION_CSVLOG)
3299 : {
3300 : /*
548 michael 3301 EUB : * Send CSV data if it's safe to do so (syslogger doesn't need the
3302 : * pipe). If this is not possible, fallback to an entry written to
3303 : * stderr.
3304 : */
548 michael 3305 GIC 21 : if (redirection_done || MyBackendType == B_LOGGER)
3306 20 : write_csvlog(edata);
548 michael 3307 EUB : else
548 michael 3308 GBC 1 : fallback_to_stderr = true;
548 michael 3309 EUB : }
3310 :
447 3311 : /* Write to JSON log, if enabled */
447 michael 3312 GBC 187471 : if (Log_destination & LOG_DESTINATION_JSONLOG)
3313 : {
447 michael 3314 EUB : /*
3315 : * Send JSON data if it's safe to do so (syslogger doesn't need the
3316 : * pipe). If this is not possible, fallback to an entry written to
3317 : * stderr.
3318 : */
447 michael 3319 GBC 21 : if (redirection_done || MyBackendType == B_LOGGER)
3320 : {
3321 20 : write_jsonlog(edata);
447 michael 3322 EUB : }
3323 : else
447 michael 3324 GBC 1 : fallback_to_stderr = true;
3325 : }
447 michael 3326 EUB :
548 3327 : /*
3328 : * Write to stderr, if enabled or if required because of a previous
3329 : * limitation.
3330 : */
548 michael 3331 GIC 187471 : if ((Log_destination & LOG_DESTINATION_STDERR) ||
548 michael 3332 UIC 0 : whereToSendOutput == DestDebug ||
548 michael 3333 EUB : fallback_to_stderr)
6615 bruce 3334 : {
5743 tgl 3335 : /*
3336 : * Use the chunking protocol if we know the syslogger should be
5624 bruce 3337 : * catching stderr output, and we are not ourselves the syslogger.
3338 : * Otherwise, just do a vanilla write to stderr.
5743 tgl 3339 : */
1124 peter 3340 GBC 187471 : if (redirection_done && MyBackendType != B_LOGGER)
5712 andrew 3341 GIC 20 : write_pipe_chunks(buf.data, buf.len, LOG_DESTINATION_STDERR);
6615 bruce 3342 EUB : #ifdef WIN32
3260 3343 :
6602 tgl 3344 : /*
3345 : * In a win32 service environment, there is no usable stderr. Capture
3346 : * anything going there and write it to the eventlog instead.
3347 : *
5743 3348 : * If stderr redirection is active, it was OK to write to stderr above
3349 : * because that's really a pipe to the syslogger process.
3350 : */
3351 : else if (pgwin32_is_service())
3352 : write_eventlog(edata->elevel, buf.data, buf.len);
3353 : #endif
3354 : else
4922 magnus 3355 GIC 187451 : write_console(buf.data, buf.len);
3356 : }
3357 :
3358 : /* If in the syslogger process, try to write messages direct to file */
1124 peter 3359 187471 : if (MyBackendType == B_LOGGER)
5708 andrew 3360 UBC 0 : write_syslogger_file(buf.data, buf.len, LOG_DESTINATION_STDERR);
5708 andrew 3361 EUB :
548 michael 3362 : /* No more need of the message formatted for stderr */
548 michael 3363 GIC 187471 : pfree(buf.data);
7290 tgl 3364 187471 : }
7975 peter_e 3365 EUB :
3366 : /*
3367 : * Send data to the syslogger using the chunked protocol
3368 : *
3369 : * Note: when there are multiple backends writing into the syslogger pipe,
4191 tgl 3370 : * it's critical that each write go into the pipe indivisibly, and not
3260 bruce 3371 : * get interleaved with data from other processes. Fortunately, the POSIX
4191 tgl 3372 : * spec requires that writes to pipes be atomic so long as they are not
3373 : * more than PIPE_BUF bytes long. So we divide long messages into chunks
3374 : * that are no more than that length, and send one chunk per write() call.
3375 : * The collector process knows how to reassemble the chunks.
3376 : *
3377 : * Because of the atomic write requirement, there are only two possible
3378 : * results from write() here: -1 for failure, or the requested number of
3379 : * bytes. There is not really anything we can do about a failure; retry would
3380 : * probably be an infinite loop, and we can't even report the error usefully.
3381 : * (There is noplace else we could send it!) So we might as well just ignore
3382 : * the result from write(). However, on some platforms you get a compiler
3383 : * warning from ignoring write()'s result, so do a little dance with casting
3384 : * rc to void to shut up the compiler.
5778 andrew 3385 : */
3386 : void
5712 andrew 3387 GBC 60 : write_pipe_chunks(char *data, int len, int dest)
3388 : {
5778 andrew 3389 EUB : PipeProtoChunk p;
5624 bruce 3390 GBC 60 : int fd = fileno(stderr);
3391 : int rc;
5712 andrew 3392 EUB :
5778 andrew 3393 CBC 60 : Assert(len > 0);
3394 :
5778 andrew 3395 GIC 60 : p.proto.nuls[0] = p.proto.nuls[1] = '\0';
5778 andrew 3396 CBC 60 : p.proto.pid = MyProcPid;
573 michael 3397 60 : p.proto.flags = 0;
3398 60 : if (dest == LOG_DESTINATION_STDERR)
573 michael 3399 GBC 20 : p.proto.flags |= PIPE_PROTO_DEST_STDERR;
573 michael 3400 GIC 40 : else if (dest == LOG_DESTINATION_CSVLOG)
573 michael 3401 GBC 20 : p.proto.flags |= PIPE_PROTO_DEST_CSVLOG;
447 michael 3402 GIC 20 : else if (dest == LOG_DESTINATION_JSONLOG)
447 michael 3403 GBC 20 : p.proto.flags |= PIPE_PROTO_DEST_JSONLOG;
3404 :
3405 : /* write all but the last chunk */
5778 andrew 3406 GIC 60 : while (len > PIPE_MAX_PAYLOAD)
5778 andrew 3407 EUB : {
573 michael 3408 : /* no need to set PIPE_PROTO_IS_LAST yet */
5778 andrew 3409 UBC 0 : p.proto.len = PIPE_MAX_PAYLOAD;
5778 andrew 3410 UIC 0 : memcpy(p.proto.data, data, PIPE_MAX_PAYLOAD);
4191 tgl 3411 0 : rc = write(fd, &p, PIPE_HEADER_SIZE + PIPE_MAX_PAYLOAD);
4191 tgl 3412 EUB : (void) rc;
5778 andrew 3413 UIC 0 : data += PIPE_MAX_PAYLOAD;
5778 andrew 3414 UBC 0 : len -= PIPE_MAX_PAYLOAD;
5778 andrew 3415 EUB : }
3416 :
3417 : /* write the last chunk */
573 michael 3418 GBC 60 : p.proto.flags |= PIPE_PROTO_IS_LAST;
5778 andrew 3419 60 : p.proto.len = len;
3420 60 : memcpy(p.proto.data, data, len);
4191 tgl 3421 GIC 60 : rc = write(fd, &p, PIPE_HEADER_SIZE + len);
4191 tgl 3422 EUB : (void) rc;
5778 andrew 3423 GBC 60 : }
5778 andrew 3424 EUB :
7290 tgl 3425 :
5151 3426 : /*
3427 : * Append a text string to the error report being built for the client.
3428 : *
3429 : * This is ordinarily identical to pq_sendstring(), but if we are in
3430 : * error recursion trouble we skip encoding conversion, because of the
3431 : * possibility that the problem is a failure in the encoding conversion
3432 : * subsystem itself. Code elsewhere should ensure that the passed-in
3433 : * strings will be plain 7-bit ASCII, and thus not in need of conversion,
3434 : * in such cases. (In particular, we disable localization of error messages
3435 : * to help ensure that's true.)
3436 : */
3437 : static void
5151 tgl 3438 GBC 221817 : err_sendstring(StringInfo buf, const char *str)
3439 : {
3440 221817 : if (in_error_recursion_trouble())
5151 tgl 3441 UIC 0 : pq_send_ascii_string(buf, str);
3442 : else
5151 tgl 3443 GIC 221817 : pq_sendstring(buf, str);
3444 221817 : }
3445 :
3446 : /*
3447 : * Write error report to client
3448 : */
3449 : static void
7184 bruce 3450 CBC 28251 : send_message_to_frontend(ErrorData *edata)
3451 : {
3452 : StringInfoData msgbuf;
3453 :
3454 : /*
766 heikki.linnakangas 3455 ECB : * We no longer support pre-3.0 FE/BE protocol, except here. If a client
3456 : * tries to connect using an older protocol version, it's nice to send the
3457 : * "protocol version not supported" error in a format the client
3458 : * understands. If protocol hasn't been set yet, early in backend
3459 : * startup, assume modern protocol.
3460 : */
766 heikki.linnakangas 3461 CBC 28251 : if (PG_PROTOCOL_MAJOR(FrontendProtocol) >= 3 || FrontendProtocol == 0)
7290 tgl 3462 28251 : {
3463 : /* New style with separate fields */
3464 : const char *sev;
3465 : char tbuf[12];
3466 :
3467 : /* 'N' (Notice) is for nonfatal conditions, 'E' is for errors */
766 heikki.linnakangas 3468 GIC 28251 : pq_beginmessage(&msgbuf, (edata->elevel < ERROR) ? 'N' : 'E');
3469 :
2417 tgl 3470 CBC 28251 : sev = error_severity(edata->elevel);
7165 peter_e 3471 GIC 28251 : pq_sendbyte(&msgbuf, PG_DIAG_SEVERITY);
2417 tgl 3472 28251 : err_sendstring(&msgbuf, _(sev));
2417 tgl 3473 CBC 28251 : pq_sendbyte(&msgbuf, PG_DIAG_SEVERITY_NONLOCALIZED);
2417 tgl 3474 GIC 28251 : err_sendstring(&msgbuf, sev);
7290 tgl 3475 ECB :
7165 peter_e 3476 GIC 28251 : pq_sendbyte(&msgbuf, PG_DIAG_SQLSTATE);
585 michael 3477 CBC 28251 : err_sendstring(&msgbuf, unpack_sql_state(edata->sqlerrcode));
7290 tgl 3478 ECB :
3479 : /* M field is required per protocol, so always send something */
7165 peter_e 3480 CBC 28251 : pq_sendbyte(&msgbuf, PG_DIAG_MESSAGE_PRIMARY);
7290 tgl 3481 28251 : if (edata->message)
5151 tgl 3482 GIC 28251 : err_sendstring(&msgbuf, edata->message);
7290 tgl 3483 ECB : else
5151 tgl 3484 LBC 0 : err_sendstring(&msgbuf, _("missing error text"));
3485 :
7290 tgl 3486 CBC 28251 : if (edata->detail)
7290 tgl 3487 ECB : {
7165 peter_e 3488 GIC 4457 : pq_sendbyte(&msgbuf, PG_DIAG_MESSAGE_DETAIL);
5151 tgl 3489 GBC 4457 : err_sendstring(&msgbuf, edata->detail);
3490 : }
7290 tgl 3491 ECB :
5494 3492 : /* detail_log is intentionally not used here */
3493 :
7290 tgl 3494 CBC 28251 : if (edata->hint)
7290 tgl 3495 ECB : {
7165 peter_e 3496 GIC 2003 : pq_sendbyte(&msgbuf, PG_DIAG_MESSAGE_HINT);
5151 tgl 3497 2003 : err_sendstring(&msgbuf, edata->hint);
7290 tgl 3498 ECB : }
3499 :
7290 tgl 3500 CBC 28251 : if (edata->context)
3501 : {
7165 peter_e 3502 8097 : pq_sendbyte(&msgbuf, PG_DIAG_CONTEXT);
5151 tgl 3503 GIC 8097 : err_sendstring(&msgbuf, edata->context);
7290 tgl 3504 ECB : }
3505 :
3722 tgl 3506 CBC 28251 : if (edata->schema_name)
3722 tgl 3507 ECB : {
3722 tgl 3508 GIC 1742 : pq_sendbyte(&msgbuf, PG_DIAG_SCHEMA_NAME);
3722 tgl 3509 CBC 1742 : err_sendstring(&msgbuf, edata->schema_name);
3510 : }
3722 tgl 3511 ECB :
3722 tgl 3512 CBC 28251 : if (edata->table_name)
3722 tgl 3513 ECB : {
3722 tgl 3514 CBC 1425 : pq_sendbyte(&msgbuf, PG_DIAG_TABLE_NAME);
3722 tgl 3515 GIC 1425 : err_sendstring(&msgbuf, edata->table_name);
3722 tgl 3516 ECB : }
3517 :
3722 tgl 3518 CBC 28251 : if (edata->column_name)
3722 tgl 3519 ECB : {
3722 tgl 3520 CBC 171 : pq_sendbyte(&msgbuf, PG_DIAG_COLUMN_NAME);
3521 171 : err_sendstring(&msgbuf, edata->column_name);
3522 : }
3722 tgl 3523 ECB :
3722 tgl 3524 GIC 28251 : if (edata->datatype_name)
3722 tgl 3525 ECB : {
3722 tgl 3526 CBC 322 : pq_sendbyte(&msgbuf, PG_DIAG_DATATYPE_NAME);
3527 322 : err_sendstring(&msgbuf, edata->datatype_name);
3722 tgl 3528 ECB : }
3529 :
3722 tgl 3530 CBC 28251 : if (edata->constraint_name)
3531 : {
3532 1251 : pq_sendbyte(&msgbuf, PG_DIAG_CONSTRAINT_NAME);
3533 1251 : err_sendstring(&msgbuf, edata->constraint_name);
3722 tgl 3534 ECB : }
3535 :
7290 tgl 3536 GIC 28251 : if (edata->cursorpos > 0)
7290 tgl 3537 ECB : {
7290 tgl 3538 GIC 4504 : snprintf(tbuf, sizeof(tbuf), "%d", edata->cursorpos);
7165 peter_e 3539 4504 : pq_sendbyte(&msgbuf, PG_DIAG_STATEMENT_POSITION);
5151 tgl 3540 CBC 4504 : err_sendstring(&msgbuf, tbuf);
3541 : }
7290 tgl 3542 ECB :
6958 tgl 3543 CBC 28251 : if (edata->internalpos > 0)
3544 : {
6958 tgl 3545 GIC 44 : snprintf(tbuf, sizeof(tbuf), "%d", edata->internalpos);
3546 44 : pq_sendbyte(&msgbuf, PG_DIAG_INTERNAL_POSITION);
5151 tgl 3547 GBC 44 : err_sendstring(&msgbuf, tbuf);
3548 : }
6958 tgl 3549 EUB :
6958 tgl 3550 GBC 28251 : if (edata->internalquery)
3551 : {
6958 tgl 3552 GIC 44 : pq_sendbyte(&msgbuf, PG_DIAG_INTERNAL_QUERY);
5151 3553 44 : err_sendstring(&msgbuf, edata->internalquery);
6958 tgl 3554 ECB : }
3555 :
7290 tgl 3556 GBC 28251 : if (edata->filename)
7290 tgl 3557 EUB : {
7165 peter_e 3558 GBC 28251 : pq_sendbyte(&msgbuf, PG_DIAG_SOURCE_FILE);
5151 tgl 3559 28251 : err_sendstring(&msgbuf, edata->filename);
3560 : }
3561 :
7290 tgl 3562 GIC 28251 : if (edata->lineno > 0)
3563 : {
3564 28251 : snprintf(tbuf, sizeof(tbuf), "%d", edata->lineno);
7165 peter_e 3565 28251 : pq_sendbyte(&msgbuf, PG_DIAG_SOURCE_LINE);
5151 tgl 3566 CBC 28251 : err_sendstring(&msgbuf, tbuf);
3567 : }
7290 tgl 3568 ECB :
7290 tgl 3569 CBC 28251 : if (edata->funcname)
7290 tgl 3570 ECB : {
7165 peter_e 3571 CBC 28251 : pq_sendbyte(&msgbuf, PG_DIAG_SOURCE_FUNCTION);
5151 tgl 3572 GIC 28251 : err_sendstring(&msgbuf, edata->funcname);
3573 : }
3574 :
2118 3575 28251 : pq_sendbyte(&msgbuf, '\0'); /* terminator */
766 heikki.linnakangas 3576 ECB :
766 heikki.linnakangas 3577 GIC 28251 : pq_endmessage(&msgbuf);
3578 : }
3579 : else
7290 tgl 3580 EUB : {
3581 : /* Old style --- gin up a backwards-compatible message */
3582 : StringInfoData buf;
3583 :
7290 tgl 3584 UIC 0 : initStringInfo(&buf);
3585 :
2417 3586 0 : appendStringInfo(&buf, "%s: ", _(error_severity(edata->elevel)));
7290 tgl 3587 EUB :
7290 tgl 3588 UBC 0 : if (edata->message)
7114 3589 0 : appendStringInfoString(&buf, edata->message);
3590 : else
6620 bruce 3591 UIC 0 : appendStringInfoString(&buf, _("missing error text"));
7290 tgl 3592 EUB :
7290 tgl 3593 UBC 0 : appendStringInfoChar(&buf, '\n');
7290 tgl 3594 EUB :
3595 : /* 'N' (Notice) is for nonfatal conditions, 'E' is for errors */
766 heikki.linnakangas 3596 UIC 0 : pq_putmessage_v2((edata->elevel < ERROR) ? 'N' : 'E', buf.data, buf.len + 1);
7290 tgl 3597 EUB :
7290 tgl 3598 UBC 0 : pfree(buf.data);
7290 tgl 3599 EUB : }
3600 :
7975 peter_e 3601 : /*
6385 bruce 3602 : * This flush is normally not necessary, since postgres.c will flush out
3603 : * waiting data when control returns to the main loop. But it seems best
3604 : * to leave it here, so that the client has some clue what happened if the
3605 : * backend dies before getting back to the main loop ... error/notice
3606 : * messages should not be a performance-critical path anyway, so an extra
3607 : * flush won't hurt much ...
7975 peter_e 3608 : */
7975 peter_e 3609 GIC 28251 : pq_flush();
3610 28251 : }
7975 peter_e 3611 EUB :
3612 :
3613 : /*
3614 : * Support routines for formatting error messages.
3615 : */
3616 :
3617 :
3618 : /*
3619 : * error_severity --- get string representing elevel
3620 : *
3621 : * The string is not localized here, but we mark the strings for translation
3622 : * so that callers can invoke _() on the result.
3623 : */
452 michael 3624 ECB : const char *
7290 tgl 3625 GIC 215762 : error_severity(int elevel)
3626 : {
3627 : const char *prefix;
3628 :
3629 215762 : switch (elevel)
3630 : {
7708 bruce 3631 CBC 6177 : case DEBUG1:
7708 bruce 3632 ECB : case DEBUG2:
3633 : case DEBUG3:
3634 : case DEBUG4:
3635 : case DEBUG5:
2417 tgl 3636 GIC 6177 : prefix = gettext_noop("DEBUG");
7975 peter_e 3637 6177 : break;
7708 bruce 3638 CBC 161786 : case LOG:
3639 : case LOG_SERVER_ONLY:
2417 tgl 3640 GIC 161786 : prefix = gettext_noop("LOG");
7708 bruce 3641 161786 : break;
3642 269 : case INFO:
2417 tgl 3643 269 : prefix = gettext_noop("INFO");
7708 bruce 3644 269 : break;
7975 peter_e 3645 CBC 8790 : case NOTICE:
2417 tgl 3646 GIC 8790 : prefix = gettext_noop("NOTICE");
7975 peter_e 3647 CBC 8790 : break;
7704 bruce 3648 GIC 2652 : case WARNING:
3649 : case WARNING_CLIENT_ONLY:
2417 tgl 3650 CBC 2652 : prefix = gettext_noop("WARNING");
7704 bruce 3651 GIC 2652 : break;
7975 peter_e 3652 35574 : case ERROR:
2417 tgl 3653 35574 : prefix = gettext_noop("ERROR");
7975 peter_e 3654 35574 : break;
3655 514 : case FATAL:
2417 tgl 3656 514 : prefix = gettext_noop("FATAL");
7975 peter_e 3657 CBC 514 : break;
7708 bruce 3658 UBC 0 : case PANIC:
2417 tgl 3659 UIC 0 : prefix = gettext_noop("PANIC");
7290 3660 0 : break;
3661 0 : default:
3662 0 : prefix = "???";
7975 peter_e 3663 0 : break;
3664 : }
3665 :
7975 peter_e 3666 CBC 215762 : return prefix;
7975 peter_e 3667 ECB : }
3668 :
3669 :
3670 : /*
3671 : * append_with_tabs
3672 : *
3673 : * Append the string to the StringInfo buffer, inserting a tab after any
3674 : * newline.
3675 : */
3676 : static void
7114 tgl 3677 GIC 225763 : append_with_tabs(StringInfo buf, const char *str)
3678 : {
3679 : char ch;
3680 :
7114 tgl 3681 CBC 27123766 : while ((ch = *str++) != '\0')
3682 : {
7114 tgl 3683 GIC 26898003 : appendStringInfoCharMacro(buf, ch);
3684 26898003 : if (ch == '\n')
7114 tgl 3685 CBC 247645 : appendStringInfoCharMacro(buf, '\t');
7123 bruce 3686 EUB : }
7123 bruce 3687 GIC 225763 : }
3688 :
6863 tgl 3689 ECB :
6797 bruce 3690 : /*
3691 : * Write errors to stderr (or by equal means when stderr is
3692 : * not available). Used before ereport/elog can be used
3693 : * safely (memory context, GUC load etc)
3694 : */
3695 : void
6863 tgl 3696 UIC 0 : write_stderr(const char *fmt,...)
3697 : {
3698 : va_list ap;
3699 :
3700 : #ifdef WIN32
3701 : char errbuf[2048]; /* Arbitrary size? */
3702 : #endif
3703 :
6620 bruce 3704 0 : fmt = _(fmt);
3705 :
6863 tgl 3706 0 : va_start(ap, fmt);
3707 : #ifndef WIN32
3708 : /* On Unix, we just fprintf to stderr */
3709 0 : vfprintf(stderr, fmt, ap);
5778 andrew 3710 0 : fflush(stderr);
3711 : #else
3712 : vsnprintf(errbuf, sizeof(errbuf), fmt, ap);
6797 bruce 3713 ECB :
3714 : /*
3715 : * On Win32, we print to stderr if running on a console, or write to
3716 : * eventlog if running as a service
3717 : */
3718 : if (pgwin32_is_service()) /* Running as a service */
6863 tgl 3719 : {
3720 : write_eventlog(ERROR, errbuf, strlen(errbuf));
3721 : }
6797 bruce 3722 : else
5778 andrew 3723 : {
6758 bruce 3724 : /* Not running as service, write to stderr */
4922 magnus 3725 : write_console(errbuf, strlen(errbuf));
5778 andrew 3726 : fflush(stderr);
3727 : }
6863 tgl 3728 : #endif
6863 tgl 3729 LBC 0 : va_end(ap);
6863 tgl 3730 UIC 0 : }
3731 :
5882 tgl 3732 ECB :
3733 : /*
3734 : * Adjust the level of a recovery-related message per trace_recovery_messages.
4616 tgl 3735 EUB : *
3736 : * The argument is the default log level of the message, eg, DEBUG2. (This
3737 : * should only be applied to DEBUGn log messages, otherwise it's a no-op.)
3738 : * If the level is >= trace_recovery_messages, we return LOG, causing the
3739 : * message to be logged unconditionally (for most settings of
3740 : * log_min_messages). Otherwise, we return the argument unchanged.
3741 : * The message will then be shown based on the setting of log_min_messages.
3742 : *
3743 : * Intention is to keep this for at least the whole of the 9.0 production
4859 simon 3744 ECB : * release, so we can more easily diagnose production problems in the field.
4616 tgl 3745 : * It should go away eventually, though, because it's an ugly and
3746 : * hard-to-explain kluge.
4859 simon 3747 : */
3748 : int
4859 simon 3749 CBC 2335181 : trace_recovery(int trace_level)
3750 : {
4859 simon 3751 GIC 2335181 : if (trace_level < LOG &&
3752 2335181 : trace_level >= trace_recovery_messages)
4790 bruce 3753 UIC 0 : return LOG;
3754 :
4859 simon 3755 GIC 2335181 : return trace_level;
3756 : }
|