Location via proxy:   [ UP ]  
[Report a bug]   [Manage cookies]                
Skip to content

Commit 8a92b70

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 89e5ef7 commit 8a92b70

File tree

1 file changed

+31
-4
lines changed

1 file changed

+31
-4
lines changed

src/backend/utils/misc/ps_status.c

+31-4
Original file line numberDiff line numberDiff line change
@@ -107,7 +107,8 @@ static char **save_argv;
107107
* (The original argv[] will not be overwritten by this routine, but may be
108108
* overwritten during init_ps_display. Also, the physical location of the
109109
* environment strings may be moved, so this should be called before any code
110-
* that might try to hang onto a getenv() result.)
110+
* that might try to hang onto a getenv() result. But see hack for musl
111+
* within.)
111112
*
112113
* Note that in case of failure this cannot call elog() as that is not
113114
* initialized yet. We rely on write_stderr() instead.
@@ -122,7 +123,7 @@ save_ps_display_args(int argc, char **argv)
122123

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

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

0 commit comments

Comments
 (0)