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

Commit 7124e7d

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 d603e67 commit 7124e7d

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
@@ -117,7 +117,8 @@ static char **save_argv;
117117
* (The original argv[] will not be overwritten by this routine, but may be
118118
* overwritten during init_ps_display. Also, the physical location of the
119119
* environment strings may be moved, so this should be called before any code
120-
* that might try to hang onto a getenv() result.)
120+
* that might try to hang onto a getenv() result. But see hack for musl
121+
* within.)
121122
*
122123
* Note that in case of failure this cannot call elog() as that is not
123124
* initialized yet. We rely on write_stderr() instead.
@@ -132,7 +133,7 @@ save_ps_display_args(int argc, char **argv)
132133

133134
/*
134135
* If we're going to overwrite the argv area, count the available space.
135-
* Also move the environment to make additional room.
136+
* Also move the environment strings to make additional room.
136137
*/
137138
{
138139
char *end_of_area = NULL;
@@ -161,7 +162,33 @@ save_ps_display_args(int argc, char **argv)
161162
for (i = 0; environ[i] != NULL; i++)
162163
{
163164
if (end_of_area + 1 == environ[i])
164-
end_of_area = environ[i] + strlen(environ[i]);
165+
{
166+
/*
167+
* The musl dynamic linker keeps a static pointer to the
168+
* initial value of LD_LIBRARY_PATH, if that is defined in the
169+
* process's environment. Therefore, we must not overwrite the
170+
* value of that setting and thus cannot advance end_of_area
171+
* beyond it. Musl does not define any identifying compiler
172+
* symbol, so we have to do this unless we see a symbol
173+
* identifying a Linux libc we know is safe.
174+
*/
175+
#if defined(__linux__) && (!defined(__GLIBC__) && !defined(__UCLIBC__))
176+
if (strncmp(environ[i], "LD_LIBRARY_PATH=", 16) == 0)
177+
{
178+
/*
179+
* We can overwrite the name, but stop at the equals sign.
180+
* Future loop iterations will not find any more
181+
* contiguous space, but we don't break early because we
182+
* need to count the total number of environ[] entries.
183+
*/
184+
end_of_area = environ[i] + 15;
185+
}
186+
else
187+
#endif
188+
{
189+
end_of_area = environ[i] + strlen(environ[i]);
190+
}
191+
}
165192
}
166193

167194
ps_buffer = argv[0];
@@ -196,7 +223,7 @@ save_ps_display_args(int argc, char **argv)
196223
* If we're going to change the original argv[] then make a copy for
197224
* argument parsing purposes.
198225
*
199-
* (NB: do NOT think to remove the copying of argv[], even though
226+
* NB: do NOT think to remove the copying of argv[], even though
200227
* postmaster.c finishes looking at argv[] long before we ever consider
201228
* changing the ps display. On some platforms, getopt() keeps pointers
202229
* into the argv array, and will get horribly confused when it is

0 commit comments

Comments
 (0)