Skip to content

Commit 7651fd3

Browse files
committed
Allow "make check"-style testing to work with musl C library.
The musl dynamic linker saves a pointer to the process' environment value of LD_LIBRARY_PATH very early in startup. When we move/clobber the environment to make more room for ps status strings, we clobber that value and thereby prevent libraries from being found via LD_LIBRARY_PATH, which breaks the use of a temporary installation for testing purposes. To fix, stop collecting usable space for ps status if we notice that the variable we are about to clobber is LD_LIBRARY_PATH. This will result in some reduction in how long the ps status can be, but it's only likely to occur in temporary test contexts, so it doesn't seem like a big problem. In any case, we don't have to do it if we see we are on glibc, which surely is where the majority of our Linux testing is done. Thomas Munro, Bruce Momjian, and Tom Lane, per report from Wolfgang Walther. Back-patch to all supported branches, with the hope that we'll set up a buildfarm animal to test on this platform. Discussion: https://postgr.es/m/fddd1cd6-dc16-40a2-9eb5-d7fef2101488@technowledgy.de
1 parent 408209d commit 7651fd3

File tree

1 file changed

+31
-4
lines changed

1 file changed

+31
-4
lines changed

src/backend/utils/misc/ps_status.c

Lines changed: 31 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -109,7 +109,8 @@ static char **save_argv;
109109
* (The original argv[] will not be overwritten by this routine, but may be
110110
* overwritten during init_ps_display. Also, the physical location of the
111111
* environment strings may be moved, so this should be called before any code
112-
* that might try to hang onto a getenv() result.)
112+
* that might try to hang onto a getenv() result. But see hack for musl
113+
* within.)
113114
*
114115
* Note that in case of failure this cannot call elog() as that is not
115116
* initialized yet. We rely on write_stderr() instead.
@@ -124,7 +125,7 @@ save_ps_display_args(int argc, char **argv)
124125

125126
/*
126127
* If we're going to overwrite the argv area, count the available space.
127-
* Also move the environment to make additional room.
128+
* Also move the environment strings to make additional room.
128129
*/
129130
{
130131
char *end_of_area = NULL;
@@ -153,7 +154,33 @@ save_ps_display_args(int argc, char **argv)
153154
for (i = 0; environ[i] != NULL; i++)
154155
{
155156
if (end_of_area + 1 == environ[i])
156-
end_of_area = environ[i] + strlen(environ[i]);
157+
{
158+
/*
159+
* The musl dynamic linker keeps a static pointer to the
160+
* initial value of LD_LIBRARY_PATH, if that is defined in the
161+
* process's environment. Therefore, we must not overwrite the
162+
* value of that setting and thus cannot advance end_of_area
163+
* beyond it. Musl does not define any identifying compiler
164+
* symbol, so we have to do this unless we see a symbol
165+
* identifying a Linux libc we know is safe.
166+
*/
167+
#if defined(__linux__) && (!defined(__GLIBC__) && !defined(__UCLIBC__))
168+
if (strncmp(environ[i], "LD_LIBRARY_PATH=", 16) == 0)
169+
{
170+
/*
171+
* We can overwrite the name, but stop at the equals sign.
172+
* Future loop iterations will not find any more
173+
* contiguous space, but we don't break early because we
174+
* need to count the total number of environ[] entries.
175+
*/
176+
end_of_area = environ[i] + 15;
177+
}
178+
else
179+
#endif
180+
{
181+
end_of_area = environ[i] + strlen(environ[i]);
182+
}
183+
}
157184
}
158185

159186
ps_buffer = argv[0];
@@ -185,7 +212,7 @@ save_ps_display_args(int argc, char **argv)
185212
* If we're going to change the original argv[] then make a copy for
186213
* argument parsing purposes.
187214
*
188-
* (NB: do NOT think to remove the copying of argv[], even though
215+
* NB: do NOT think to remove the copying of argv[], even though
189216
* postmaster.c finishes looking at argv[] long before we ever consider
190217
* changing the ps display. On some platforms, getopt() keeps pointers
191218
* into the argv array, and will get horribly confused when it is

0 commit comments

Comments
 (0)