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