From: Wolfgang Walther <walther@technowledgy.de>
To: Thomas Munro <thomas.munro@gmail.com>
To: peter@eisentraut.org
Cc: Bruce Momjian <bruce@momjian.us>
Cc: Christophe Pettus <xof@thebuild.com>
Cc: Andrew Dunstan <andrew@dunslane.net>
Cc: PostgreSQL Bugs <pgsql-bugs@lists.postgresql.org>
Cc: Tom Lane <tgl@sss.pgh.pa.us>
Subject: Re: Regression tests fail with musl libc because libpq.so can't be loaded
Date: Wed, 20 Mar 2024 10:39:20 +0100
Message-ID: <477fa513-6bf0-456d-8d24-1e22a19df671@technowledgy.de> (raw)
In-Reply-To: <CA+hUKGK2cSx3dveMqBD+E9N=zJ0WawBcbk_jnPqmdWBM0DT_3Q@mail.gmail.com>
References: <855a1b16-0dc0-42b2-8f90-79eb49cf2893@technowledgy.de>
<F5A214FF-1BED-4935-B4FF-4679CCF463D6@thebuild.com>
<CAD5tBcLWM+QT0+VKWUHiBX2Ey5eCc8jVL5APb1U5iaePV_eAvg@mail.gmail.com>
<A9F65857-A286-4EB8-96CE-EA5C1636A05C@thebuild.com>
<CA+hUKG+H80zJTmNnRbAQb+py2xpzNUtmoacbfnyAi2c5d1imGg@mail.gmail.com>
<E5D4E3AE-C926-48C5-84DC-57E3E9357675@thebuild.com>
<CA+hUKGJW_ht0VYsr7bzF8-FLZW_o3Ys6Xm5w10GU5WBHtfv+zg@mail.gmail.com>
<3561573.1710771812@sss.pgh.pa.us>
<CA+hUKG+Tq3GK7bPd03N0Eox3YY4-Hjd7qQjo_QZFjdbhTqQGQA@mail.gmail.com>
<CA+hUKGK9LUq=uygBRFt3vFO1RL+_scsT4+hMkvea_zTttHZ59Q@mail.gmail.com>
<ZfolyUQw9z1zxX58@momjian.us>
<CA+hUKG+Y1D2Bv9v0GbYrhiQ+mhf=6Xj2_viiATnBVFShkfO4VQ@mail.gmail.com>
<4093813.1710899588@sss.pgh.pa.us>
<CA+hUKGKNK5V8XwwJJZm36s3EUy8V51xu4XiE8=26n=Wq3OGd4A@mail.gmail.com>
<4095435.1710900216@sss.pgh.pa.us>
<CA+hUKGK2cSx3dveMqBD+E9N=zJ0WawBcbk_jnPqmdWBM0DT_3Q@mail.gmail.com>
Thomas Munro:
> On Wed, Mar 20, 2024 at 3:03 PM Tom Lane <tgl@sss.pgh.pa.us> wrote:
>> +1 for stopping only at one of those two names.
>
> Here's one like that for Wolfgang to test on musl.
Works fine.
Peter Eisentraut:
> We could turn it around and do
>
> #if defined(__linux__)
> #if defined(__GLIBC__) || defined(__UCLIBC__ )
> #define PS_USE_CLOBBER_ARGV
> #else
> #define PS_USE_NONE
> #endif
> #endif
This works as well.
I also put together a PoC of what was mentioned in musl's mailing list:
Instead of clobbering environ at all, exec yourself again with padded
argv0. This works, too. Attached.
Best,
Wolfgang
Attachments:0001-ps-status-exec.patch (text/x-patch, 3.3K) downloaddiff --git a/src/backend/utils/misc/ps_status.c b/src/backend/utils/misc/ps_status.cindex 5d829e6e483..f8035c15df8 100644--- a/src/backend/utils/misc/ps_status.c+++ b/src/backend/utils/misc/ps_status.c@@ -23,8 +23,6 @@
#include "utils/guc.h"
#include "utils/ps_status.h"
-extern char **environ;-
/* GUC variable */
bool update_process_title = DEFAULT_UPDATE_PROCESS_TITLE;
@@ -38,7 +36,7 @@ bool update_process_title = DEFAULT_UPDATE_PROCESS_TITLE;
* use the function setproctitle(const char *, ...)
* (other BSDs)
* PS_USE_CLOBBER_ARGV
- * write over the argv and environment area+ * write over the argv area
* (Linux and most SysV-like systems)
* PS_USE_WIN32
* push the string out as the name of a Windows event
@@ -69,9 +67,9 @@ bool update_process_title = DEFAULT_UPDATE_PROCESS_TITLE;
#ifndef PS_USE_NONE
-#ifndef PS_USE_CLOBBER_ARGV
/* all but one option need a buffer to write their ps line in */
#define PS_BUFFER_SIZE 256
+#ifndef PS_USE_CLOBBER_ARGV
static char ps_buffer[PS_BUFFER_SIZE];
static const size_t ps_buffer_size = PS_BUFFER_SIZE;
#else /* PS_USE_CLOBBER_ARGV */
@@ -105,9 +103,7 @@ static char **save_argv;
* from being clobbered by subsequent ps_display actions.
*
* (The original argv[] will not be overwritten by this routine, but may be
- * overwritten during init_ps_display. Also, the physical location of the- * environment strings may be moved, so this should be called before any code- * that might try to hang onto a getenv() result.)+ * overwritten during init_ps_display.)
*
* Note that in case of failure this cannot call elog() as that is not
* initialized yet. We rely on write_stderr() instead.
@@ -126,7 +122,6 @@ save_ps_display_args(int argc, char **argv)
*/
{
char *end_of_area = NULL;
- char **new_environ;
int i;
/*
@@ -145,38 +140,32 @@ save_ps_display_args(int argc, char **argv)
return argv;
}
- /*- * check for contiguous environ strings following argv- */- for (i = 0; environ[i] != NULL; i++)- {- if (end_of_area + 1 == environ[i])- end_of_area = environ[i] + strlen(environ[i]);- }-
ps_buffer = argv[0];
last_status_len = ps_buffer_size = end_of_area - argv[0];
- /*- * move the environment out of the way- */- new_environ = (char **) malloc((i + 1) * sizeof(char *));- if (!new_environ)+ if (ps_buffer_size < PS_BUFFER_SIZE)
{
- write_stderr("out of memory\n");+ char *argv0_padded;+ int len = strlen(argv[0]);+ char *self = argv[0];++ /* right pad argv[0] with slashes up to PS_BUFFER_SIZE */+ argv0_padded = (char *) malloc(len + PS_BUFFER_SIZE - ps_buffer_size);+ memcpy(argv0_padded, argv[0], len);+ MemSet(argv0_padded + len, '/', PS_BUFFER_SIZE - len - 1);+ argv[0] = argv0_padded;++ execvp(self, argv);+ write_stderr("exec failed: %s\n%s", strerror(errno), self);
exit(1);
}
- for (i = 0; environ[i] != NULL; i++)+ else
{
- new_environ[i] = strdup(environ[i]);- if (!new_environ[i])- {- write_stderr("out of memory\n");- exit(1);- }+ /* We might have already padded argv[0], so we must strip+ * it again to make get_program_name work. */+ int len = strlen(argv[0]);+ while (len > 0 && argv[0][len - 1] == '/') argv[0][--len] = '\0';
}
- new_environ[i] = NULL;- environ = new_environ;
}
/*
--
2.44.0
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Reply to all the recipients using the --to and --cc options:
reply via email
To: pgsql-bugs@postgresql.org
Cc: walther@technowledgy.de, thomas.munro@gmail.com, peter@eisentraut.org, bruce@momjian.us, xof@thebuild.com, andrew@dunslane.net, pgsql-bugs@lists.postgresql.org, tgl@sss.pgh.pa.us
Subject: Re: Regression tests fail with musl libc because libpq.so can't be loaded
In-Reply-To: <477fa513-6bf0-456d-8d24-1e22a19df671@technowledgy.de>
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
This inbox is served by DDX for PostgreSQL; see mirroring instructions
for how to clone and mirror all data and code used for this inbox