From 002be0e6ed8cc4d00505cec5c3d9097571d93cfa Mon Sep 17 00:00:00 2001 From: Justin Pryzby Date: Wed, 2 Feb 2022 20:54:49 -0600 Subject: [PATCH v8 4/4] show the GUC source in errcontext //-os-only: freebsd --- src/backend/utils/fmgr/dfmgr.c | 14 +++++++++++--- src/backend/utils/misc/guc_funcs.c | 26 ++++++++++++++++++++++++++ src/include/utils/guc.h | 1 + 3 files changed, 38 insertions(+), 3 deletions(-) diff --git a/src/backend/utils/fmgr/dfmgr.c b/src/backend/utils/fmgr/dfmgr.c index 28082890bf0..acbcaef7957 100644 --- a/src/backend/utils/fmgr/dfmgr.c +++ b/src/backend/utils/fmgr/dfmgr.c @@ -34,6 +34,7 @@ #include "lib/stringinfo.h" #include "miscadmin.h" #include "storage/shmem.h" +#include "utils/guc_tables.h" #include "utils/hsearch.h" @@ -214,11 +215,18 @@ internal_load_library(const char *libname, const char *gucname) * Check for same files - different paths (ie, symlink or link) */ if (stat(libname, &stat_buf) == -1) + { + char *errstr = strerror(errno); + int linenum; + char *sourcefile = gucname ? GetConfigSourceFile(gucname, &linenum) : NULL; + ereport(ERROR, (errcode_for_file_access(), gucname ? errcontext("while loading shared libraries for setting \"%s\"", gucname) : 0, - errmsg("could not access file \"%s\": %m", - libname))); + sourcefile ? errcontext("from %s:%d", sourcefile, linenum) : 0, + errmsg("could not access file \"%s\": %s", + libname, errstr))); + } for (file_scanner = file_list; file_scanner != NULL && @@ -282,7 +290,7 @@ internal_load_library(const char *libname, const char *gucname) } else { - /* try to close library */ + /* try to close library */ // Not needed due to ERROR ? // dlclose(file_scanner->handle); free(file_scanner); /* complain */ diff --git a/src/backend/utils/misc/guc_funcs.c b/src/backend/utils/misc/guc_funcs.c index 0ad7e6cf1f1..4229eb3a794 100644 --- a/src/backend/utils/misc/guc_funcs.c +++ b/src/backend/utils/misc/guc_funcs.c @@ -177,6 +177,32 @@ ExtractSetVariableArgs(VariableSetStmt *stmt) } } + +/* + * Get the source file and line associated with the given option, if it was set + * by a file. + * + * If the option doesn't exist, throw an ereport and don't return. + */ +char * +GetConfigSourceFile(const char *name, int *linenum) +{ + struct config_generic *record; + + record = find_option(name, false, false, ERROR); + + /* Should not happen */ + if (record == NULL) + return NULL; + + if (record->source != PGC_S_FILE) + return NULL; + + *linenum = record->sourceline; + return record->sourcefile; +} + + /* * flatten_set_variable_args * Given a parsenode List as emitted by the grammar for SET, diff --git a/src/include/utils/guc.h b/src/include/utils/guc.h index d0ac2fd4944..2bab6baadf0 100644 --- a/src/include/utils/guc.h +++ b/src/include/utils/guc.h @@ -367,6 +367,7 @@ extern const char *GetConfigOption(const char *name, bool missing_ok, bool restrict_privileged); extern const char *GetConfigOptionResetString(const char *name); extern int GetConfigOptionFlags(const char *name, bool missing_ok); +extern char *GetConfigSourceFile(const char *name, int *linenum); extern void ProcessConfigFile(GucContext context); extern char *convert_GUC_name_for_parameter_acl(const char *name); extern void check_GUC_name_for_parameter_acl(const char *name); -- 2.42.0