From: =?UTF-8?q?=C3=81lvaro=20Herrera?= Date: Mon, 9 Feb 2026 17:51:51 +0100 Subject: [PATCH v7 2/2] fixups --- src/backend/meson.build | 10 +++--- src/backend/utils/error/elog.c | 57 ++++++++++++++++++---------------- 2 files changed, 37 insertions(+), 30 deletions(-) diff --git a/src/backend/meson.build b/src/backend/meson.build index 2e7f2be2c78..1ee2c079390 100644 --- a/src/backend/meson.build +++ b/src/backend/meson.build @@ -2,10 +2,6 @@ backend_build_deps = [backend_code] -if host_system == 'windows' and cc.get_id() == 'msvc' - backend_build_deps += cc.find_library('dbghelp') -endif - backend_sources = [] backend_link_with = [pgport_srv, common_srv] @@ -46,6 +42,12 @@ backend_link_args = [] backend_link_depends = [] +# On Windows also make the backend depend on dbghelp, for backtrace support +if host_system == 'windows' and cc.get_id() == 'msvc' + backend_build_deps += cc.find_library('dbghelp') +endif + + # On windows when compiling with msvc we need to make postgres export all its # symbols so that extension libraries can use them. For that we need to scan # the constituting objects and generate a file specifying all the functions as diff --git a/src/backend/utils/error/elog.c b/src/backend/utils/error/elog.c index 60f95a58f7a..6b80e44fb5d 100644 --- a/src/backend/utils/error/elog.c +++ b/src/backend/utils/error/elog.c @@ -74,6 +74,7 @@ #include "common/ip.h" #include "libpq/libpq.h" #include "libpq/pqformat.h" +#include "mb/pg_wchar.h" #include "miscadmin.h" #include "nodes/miscnodes.h" #include "pgstat.h" @@ -188,6 +189,7 @@ static void set_stack_entry_location(ErrorData *edata, const char *funcname); static bool matches_backtrace_functions(const char *funcname); static pg_noinline void set_backtrace(ErrorData *edata, int num_skip); +static void backtrace_cleanup(int code, Datum arg); static void set_errdata_field(MemoryContextData *cxt, char **ptr, const char *str); static void FreeErrorDataContents(ErrorData *edata); static int log_min_messages_cmp(const ListCell *a, const ListCell *b); @@ -1125,30 +1127,17 @@ errbacktrace(void) return 0; } -#ifdef _MSC_VER -/* - * Cleanup function for DbgHelp resources. - * Called via on_proc_exit() to release resources allocated by SymInitialize(). - */ -static void -backtrace_cleanup(int code, Datum arg) -{ - SymCleanup(backtrace_process); -} -#endif - /* * Compute backtrace data and add it to the supplied ErrorData. num_skip * specifies how many inner frames to skip. Use this to avoid showing the * internal backtrace support functions in the backtrace. This requires that * this and related functions are not inlined. * - * Platform-specific implementations: - * - Unix/Linux: Uses backtrace() and backtrace_symbols() + * The implementation is, unsurprisingly, platform-specific: + * - Linux, Unix: Uses backtrace() and backtrace_symbols() * - Windows: Uses CaptureStackBackTrace() with DbgHelp for symbol resolution * (requires PDB files; falls back to exported functions/raw addresses if * unavailable) - * - Other: Returns unsupported message */ static void set_backtrace(ErrorData *edata, int num_skip) @@ -1159,12 +1148,12 @@ set_backtrace(ErrorData *edata, int num_skip) #ifdef HAVE_BACKTRACE_SYMBOLS { - void *buf[100]; + void *frames[100]; int nframes; char **strfrms; - nframes = backtrace(buf, lengthof(buf)); - strfrms = backtrace_symbols(buf, nframes); + nframes = backtrace(frames, lengthof(frames)); + strfrms = backtrace_symbols(frames, nframes); if (strfrms != NULL) { for (int i = num_skip; i < nframes; i++) @@ -1177,7 +1166,7 @@ set_backtrace(ErrorData *edata, int num_skip) } #elif defined(_MSC_VER) { - void *buf[100]; + void *frames[100]; int nframes; char buffer[sizeof(SYMBOL_INFOW) + MAX_SYM_NAME * sizeof(wchar_t)]; PSYMBOL_INFOW psymbol; @@ -1198,18 +1187,19 @@ set_backtrace(ErrorData *edata, int num_skip) } else { - elog(WARNING, "could not initialize the symbol handler: error code %lu", - GetLastError()); + appendStringInfo(&errtrace, + "could not initialize symbol handler: error code %lu", + GetLastError()); edata->backtrace = errtrace.data; return; } } - nframes = CaptureStackBackTrace(num_skip, lengthof(buf), buf, NULL); + nframes = CaptureStackBackTrace(num_skip, lengthof(frames), frames, NULL); if (nframes == 0) { - appendStringInfoString(&errtrace, "\nNo stack frames captured"); + appendStringInfoString(&errtrace, "zero stack frames captured"); edata->backtrace = errtrace.data; return; } @@ -1220,7 +1210,7 @@ set_backtrace(ErrorData *edata, int num_skip) for (int i = 0; i < nframes; i++) { - DWORD64 address = (DWORD64) buf[i]; + DWORD64 address = (DWORD64) frames[i]; DWORD64 displacement = 0; BOOL sym_result; @@ -1284,8 +1274,10 @@ set_backtrace(ErrorData *edata, int num_skip) } else { - elog(WARNING, "symbol lookup failed: error code %lu", - GetLastError()); + appendStringInfo(&errtrace, + "\n[0x%llx] (symbol lookup failed: error code %lu)", + (unsigned long long) address, + GetLastError()); } } } @@ -1297,6 +1289,19 @@ set_backtrace(ErrorData *edata, int num_skip) edata->backtrace = errtrace.data; } +/* + * Cleanup function for DbgHelp resources. + * Called via on_proc_exit() to release resources allocated by SymInitialize(). + */ +pg_attribute_unused() +static void +backtrace_cleanup(int code, Datum arg) +{ +#ifdef _MSC_VER + SymCleanup(backtrace_process); +#endif +} + /* * errmsg_internal --- add a primary error message text to the current error * -- 2.47.3 --66lzhokyymna6c2w--