glibc/glibc-RHEL-49785-6.patch
2026-03-25 12:30:41 +00:00

178 lines
6.3 KiB
Diff

commit 9181dc6eb6084da95d8c14d9defe96189fd0360d
Author: Frédéric Bérat <berat.fred@gmail.com>
Date: Tue Jan 27 23:07:17 2026 +0100
feat(rtld): Allow LD_DEBUG category exclusion
Adds support for excluding specific categories from `LD_DEBUG` output.
The `LD_DEBUG` environment variable now accepts category names prefixed
with a dash (`-`) to disable their debugging output. This allows users
to enable broad categories (e.g., `all`) while suppressing verbose or
irrelevant information from specific sub-categories (e.g., `-tls`).
The `process_dl_debug` function in `rtld.c` has been updated to parse
these exclusion options and unset the corresponding bits in
`GLRO(dl_debug_mask)`. The `LD_DEBUG=help` output has also been updated
to document this new functionality. A new test `tst-dl-debug-exclude.sh`
is added to verify the correct behavior of category exclusion.
Reviewed-by: Adhemerval Zanella <adhemerval.zanella@linaro.org>
diff --git a/elf/Makefile b/elf/Makefile
index 2431e7032c44beb8..ec87811c61565511 100644
--- a/elf/Makefile
+++ b/elf/Makefile
@@ -1253,6 +1253,7 @@ $(objpfx)tst-glibcelf.out: tst-glibcelf.py elf.h $(..)/scripts/glibcelf.py \
ifeq ($(run-built-tests),yes)
tests-special += $(objpfx)tst-tls-allocation-failure-static-patched.out
tests-special += $(objpfx)tst-tls-debug-recursive.out
+tests-special += $(objpfx)tst-dl-debug-exclude.out
endif
# The test requires shared _and_ PIE because the executable
@@ -3064,4 +3065,14 @@ $(objpfx)tst-tls-debug-recursive.out: tst-tls-debug-recursive.sh \
'$(rtld-prefix)' '$(run_program_env)' \
$(objpfx)tst-recursive-tls > $@; \
$(evaluate-test)
+
+$(objpfx)tst-dl-debug-exclude.out: tst-dl-debug-exclude.sh \
+ $(objpfx)tst-recursive-tls \
+ $(objpfx)tst-recursive-tlsmallocmod.so \
+ $(patsubst %,$(objpfx)tst-recursive-tlsmod%.so, \
+ 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15)
+ $(SHELL) $< $(common-objpfx) '$(test-wrapper-env)' \
+ '$(rtld-prefix)' '$(run_program_env)' \
+ $(objpfx)tst-recursive-tls > $@; \
+ $(evaluate-test)
endif
diff --git a/elf/rtld.c b/elf/rtld.c
index 3221bc8520996097..a4290890d6bca263 100644
--- a/elf/rtld.c
+++ b/elf/rtld.c
@@ -2708,11 +2708,18 @@ process_dl_debug (struct dl_main_state *state, const char *dl_debug)
&& dl_debug[len] != ',' && dl_debug[len] != ':')
++len;
+ bool exclude = *dl_debug == '-';
+ const char *name = exclude ? dl_debug + 1 : dl_debug;
+ size_t name_len = exclude ? len - 1 : len;
+
for (cnt = 0; cnt < ndebopts; ++cnt)
- if (debopts[cnt].len == len
- && memcmp (dl_debug, debopts[cnt].name, len) == 0)
+ if (debopts[cnt].len == name_len
+ && memcmp (name, debopts[cnt].name, name_len) == 0)
{
- GLRO(dl_debug_mask) |= debopts[cnt].mask;
+ if (exclude)
+ GLRO(dl_debug_mask) &= ~debopts[cnt].mask;
+ else
+ GLRO(dl_debug_mask) |= debopts[cnt].mask;
break;
}
@@ -2754,7 +2761,8 @@ Valid options for the LD_DEBUG environment variable are:\n\n");
_dl_printf ("\n\
To direct the debugging output into a file instead of standard output\n\
-a filename can be specified using the LD_DEBUG_OUTPUT environment variable.\n");
+a filename can be specified using the LD_DEBUG_OUTPUT environment variable.\n\
+Categories can be excluded by prefixing them with a dash (-).\n");
_exit (0);
}
}
diff --git a/elf/tst-dl-debug-exclude.sh b/elf/tst-dl-debug-exclude.sh
new file mode 100644
index 0000000000000000..9837ffcea8e07933
--- /dev/null
+++ b/elf/tst-dl-debug-exclude.sh
@@ -0,0 +1,87 @@
+#!/bin/sh
+# Test for LD_DEBUG category exclusion.
+# Copyright (C) 2026 Free Software Foundation, Inc.
+# This file is part of the GNU C Library.
+#
+# The GNU C Library is free software; you can redistribute it and/or
+# modify it under the terms of the GNU Lesser General Public
+# License as published by the Free Software Foundation; either
+# version 2.1 of the License, or (at your option) any later version.
+#
+# The GNU C Library is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+# Lesser General Public License for more details.
+#
+# You should have received a copy of the GNU Lesser General Public
+# License along with the GNU C Library; if not, see
+# <https://www.gnu.org/licenses/>.
+
+# This script verifies the LD_DEBUG category exclusion functionality.
+# It checks that:
+# 1. Categories can be excluded using the '-' prefix.
+# 2. Options are processed sequentially, meaning the last specified
+# option for a category (enable or exclude) takes precedence.
+
+set -e
+
+common_objpfx="$1"
+test_wrapper_env="$2"
+rtld_prefix="$3"
+run_program_env="$4"
+test_program="$5"
+
+debug_output="${common_objpfx}elf/tst-dl-debug-exclude.debug"
+rm -f "${debug_output}".*
+
+# Run the test program with LD_DEBUG=all,-tls.
+# We expect general logs but no TLS logs.
+eval "${test_wrapper_env}" LD_DEBUG=all,-tls LD_DEBUG_OUTPUT="${debug_output}" \
+ "${rtld_prefix}" "${test_program}"
+
+fail=0
+
+# 1. Check that general logs are present (e.g., file loading)
+if ! grep -q 'file=' "${debug_output}".*; then
+ echo "FAIL: 'file=' message not found (LD_DEBUG=all failed)"
+ fail=1
+fi
+
+# 2. Check that TLS logs are NOT present
+if grep -q 'tls: ' "${debug_output}".*; then
+ echo "FAIL: TLS message found (exclusion of -tls failed)"
+ fail=1
+fi
+
+rm -f "${debug_output}".*
+# 3. Check for LD_DEBUG=all,-tls,tls (ordering verification)
+# We expect TLS logs to BE present
+eval "${test_wrapper_env}" LD_DEBUG=all,-tls,tls LD_DEBUG_OUTPUT="${debug_output}" \
+ "${rtld_prefix}" "${test_program}"
+
+if ! grep -q 'tls: ' "${debug_output}".*; then
+ echo "FAIL: TLS message not found (ordering -tls,tls failed)"
+ fail=1
+fi
+
+rm -f "${debug_output}".*
+# 4. Check for LD_DEBUG=tls,-tls
+# We expect TLS logs to NOT be present
+eval "${test_wrapper_env}" LD_DEBUG=tls,-tls LD_DEBUG_OUTPUT="${debug_output}" \
+ "${rtld_prefix}" "${test_program}"
+
+if grep -q 'tls: ' "${debug_output}".*; then
+ echo "FAIL: TLS message found (ordering tls,-tls failed)"
+ fail=1
+fi
+
+if [ $fail -ne 0 ]; then
+ echo "Test FAILED"
+ cat "${debug_output}".*
+ rm -f "${debug_output}".*
+ exit 1
+fi
+
+echo "Test PASSED"
+rm -f "${debug_output}".*
+exit 0