[PATCH v3 2/2] feat(rtld): Allow LD_DEBUG category exclusion

Frédéric Bérat fberat@redhat.com
Tue Jan 27 22:17:14 GMT 2026


From: Frédéric Bérat <berat.fred@gmail.com>

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.
---
 elf/Makefile                | 11 +++++++++
 elf/rtld.c                  | 14 +++++++++++-
 elf/tst-dl-debug-exclude.sh | 45 +++++++++++++++++++++++++++++++++++++
 3 files changed, 69 insertions(+), 1 deletion(-)
 create mode 100644 elf/tst-dl-debug-exclude.sh

diff --git a/elf/Makefile b/elf/Makefile
index fe1d1847d1..03ecf6fee4 100644
--- a/elf/Makefile
+++ b/elf/Makefile
@@ -3548,4 +3548,15 @@ $(objpfx)tst-tls-debug-recursive.out: tst-tls-debug-recursive.sh \
 		 '$(rtld-prefix)' '$(run_program_env)' \
 		 $(objpfx)tst-recursive-tls > $@; \
 	$(evaluate-test)
+
+tests-special += $(objpfx)tst-dl-debug-exclude.out
+$(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 457aa9c452..26f2180364 100644
--- a/elf/rtld.c
+++ b/elf/rtld.c
@@ -2470,6 +2470,17 @@ process_dl_debug (struct dl_main_state *state, const char *dl_debug)
 		break;
 	      }
 
+	  if (cnt == ndebopts && dl_debug[0] == '-')
+	    {
+	      for (cnt = 0; cnt < ndebopts; ++cnt)
+		if (debopts[cnt].len == len - 1
+		    && memcmp (dl_debug + 1, debopts[cnt].name, len - 1) == 0)
+		  {
+		    GLRO(dl_debug_mask) &= ~debopts[cnt].mask;
+		    break;
+		  }
+	    }
+
 	  if (cnt == ndebopts)
 	    {
 	      /* Display a warning and skip everything until next
@@ -2508,7 +2519,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 0000000000..d0bda8c9ff
--- /dev/null
+++ b/elf/tst-dl-debug-exclude.sh
@@ -0,0 +1,45 @@
+#!/bin/sh
+# Test for LD_DEBUG category exclusion.
+# Copyright (C) 2026 Free Software Foundation, Inc.
+# This file is part of the GNU C Library.
+
+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 'initial modid limit set to' "${debug_output}".*; then
+  echo "FAIL: 'initial modid limit' message found (exclusion of -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
-- 
2.52.0



More information about the Libc-alpha mailing list