Inspect /proc/sys/debug Without Guessing at Kernel Knobs
You will finish with a read-only inventory of the debug controls exposed by this kernel, plus a safe way to read their values and record the result. The central fact is easy to miss: the /proc/sys/debug/ directory may be empty. An empty directory is documented behaviour, not automatically a fault.
The route
Jump straight to the step you need, or tick off Done means at the end.
Allow about ten minutes. You need a shell on Linux with /proc mounted. The examples use the local manpages package version 6.7-2, whose proc_sys_debug(5) page is dated 30 September 2023, and a Linux 6.8.0-139-generic kernel. Your directory can differ because these entries are supplied by the running kernel, not by a fixed user-space configuration file.
1. Confirm that procfs is available
Start with a read-only check of the directory and its filesystem. This does not need elevated privileges:
$ ls -ld /proc/sys/debug
$ findmnt -T /proc/sys/debug -o TARGET,FSTYPE,OPTIONS
On the example host, the directory is present and findmnt reports a proc filesystem. The directory permissions are normally displayed as a root-owned, read-only directory for ordinary users. Do not infer that every file below it is read-only from that directory mode: procfs exposes individual kernel variables, and some can be writable.
Checkpoint: if ls reports that the path does not exist, check /proc itself before trying to create anything. This path is a kernel interface. Creating a normal directory with the same name would hide the real problem and would not create debug controls.
2. List the controls this kernel exposes
List only the immediate entries, sorted for easier comparison with a later check:
$ find /proc/sys/debug -mindepth 1 -maxdepth 1 -printf '%f\n' | sort
The local host prints:
exception-trace
kprobes-optimization
Your output may be empty or may contain different names. The installed manual says that /proc/sys/debug/ may be empty; it does not promise these two names, or any other particular list. That distinction matters when moving a check between kernel versions, distributions, containers and restricted environments.
Do not turn a name seen on one host into a deployment prerequisite without checking the target host. A missing entry is not evidence that a package needs reinstalling. It may simply mean that the running kernel does not expose that control.
3. Read values without changing them
Read each discovered file directly. This is an ordinary, non-destructive command:
$ for file in /proc/sys/debug/*; do
[ -f "$file" ] || continue
printf '%s = ' "${file#/proc/sys/}"
cat "$file"
done
On the example machine, the result is:
debug/exception-trace = 1
debug/kprobes-optimization = 1
The glob can remain unmatched on an empty directory, which is why the file test is included. It also avoids treating a subdirectory or an unusual procfs entry as a scalar value. Keep the path quoted in scripts: although these kernel-generated names normally contain no whitespace, quoting makes the shell behaviour explicit.
If you prefer the sysctl interface, query a specific discovered name:
$ sysctl debug.exception-trace
debug.exception-trace = 1
sysctl is a user-space interface to kernel variables. It does not make a missing variable appear, and its output is not a substitute for checking which files exist. Use sysctl -n when a script needs only the value, and check its exit status before using that value.
4. Decide whether a change is actually required
This guide has not changed kernel state. Keep it that way until you have identified a specific control, understood its kernel documentation, and decided how the setting should persist. Some proc sys files accept writes, but a write can alter debugging or performance behaviour immediately. Treat a write as a security-sensitive or service-impacting action, not as a harmless test.
Do not run a command such as echo 0 > /proc/sys/debug/example with a guessed name. The example name is intentionally invalid and demonstrates the boundary: names and accepted values must come from documentation for the exact kernel interface you are operating. A failed write may still indicate that the chosen interface is absent, read-only or rejecting the value; it is not a reason to try random alternatives.
If you do have a documented change to make, save the current value first, use the smallest possible scope, and arrange an explicit rollback. For a real file called CONTROL_NAME, the shape is:
$ old_value=$(cat /proc/sys/debug/CONTROL_NAME) || exit $?
$ printf 'old value: %s\n' "$old_value"
$ sudo sysctl -w debug.CONTROL_NAME=DOCUMENTED_VALUE
$ sysctl debug.CONTROL_NAME
$ sudo sysctl -w debug.CONTROL_NAME="$old_value"
Replace both placeholders only after consulting the exact kernel documentation. The sudo command is the elevated step. The final command restores the captured value, but it is not a universal undo mechanism for changes that affect running components, failed writes or a host that reboots between commands. Never paste a placeholder as though it were a real setting.
5. Diagnose an unexpected result
Separate four cases: the directory is absent, it exists but is empty, a named file is absent, or a named file exists but cannot be read. Record the kernel and mount context alongside the listing:
$ uname -r
$ findmnt -T /proc/sys/debug -o TARGET,FSTYPE,OPTIONS
$ ls -la /proc/sys/debug
$ sysctl -a 2>/dev/null | grep '^debug\.'
The last command may produce no lines. That is consistent with an empty directory, and it is safer than assuming a missing line means the value is zero. If a container or hardened environment gives a different view, compare its procfs mount and permissions with the host before changing either.
Do not use elevated privileges merely because a read failed. First inspect the error and mount state. If a documented control genuinely requires privilege, run only the specific read or write that needs it, and keep the command's status in your notes.
Done means
/proc/sys/debugwas checked without creating or modifying files.- The actual entries and values on this kernel were recorded.
- An empty directory would be treated as documented behaviour.
- No control name or value was guessed from another machine.
- Any future write has a documented target, an explicit rollback and a clearly marked elevated command.