diff --git a/src/backend/utils/error/assert.c b/src/backend/utils/error/assert.c index 2da512a2f1..caebaf23b2 100644 --- a/src/backend/utils/error/assert.c +++ b/src/backend/utils/error/assert.c @@ -43,20 +43,30 @@ ExceptionalCondition(const char *conditionName, errorType, conditionName, fileName, lineNumber, (int) getpid()); - /* Usually this shouldn't be needed, but make sure the msg went out */ - fflush(stderr); - /* If we have support for it, dump a simple backtrace */ #ifdef HAVE_BACKTRACE_SYMBOLS { void *buf[100]; int nframes; + char **strfrms; nframes = backtrace(buf, lengthof(buf)); - backtrace_symbols_fd(buf, nframes, fileno(stderr)); + strfrms = backtrace_symbols(buf, nframes); + if (strfrms != NULL) + { + for (int i = 0; i < nframes; i++) + write_stderr("%s\n", strfrms[i]); + if (nframes >= lengthof(buf)) + write_stderr("(backtrace limited to %zu frames)\n", + lengthof(buf)); + free(strfrms); + } } #endif + /* Usually this shouldn't be needed, but make sure the msg went out */ + fflush(stderr); + /* * If configured to do so, sleep indefinitely to allow user to attach a * debugger. It would be nice to use pg_usleep() here, but that can sleep diff --git a/src/backend/utils/error/elog.c b/src/backend/utils/error/elog.c index 7402696986..9933386959 100644 --- a/src/backend/utils/error/elog.c +++ b/src/backend/utils/error/elog.c @@ -966,6 +966,9 @@ set_backtrace(ErrorData *edata, int num_skip) for (int i = num_skip; i < nframes; i++) appendStringInfo(&errtrace, "\n%s", strfrms[i]); + if (nframes >= lengthof(buf)) + appendStringInfo(&errtrace, "\n(backtrace limited to %zu frames)", + lengthof(buf)); free(strfrms); } #else