Home / Alt manpages / proc_sys_debug(5)

  • proc_sys_debug(5)
  • File format
  • linux

Inspect /proc/sys/debug Without Guessing at Kernel Knobs

You expect a folder full of debug switches, then /proc/sys/debug/ turns out empty, and that catches people out every time. An empty directory is documented behaviour, not a fault. Allow about ten minutes and 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, against a Linux 6.8.0-139-generic kernel. Your own directory can differ, because these entries come from the running kernel, not a fixed user-space config file.

1. Confirm that procfs is available

Start with a read-only check of the directory and its filesystem. This needs no 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 normally show as a root-owned, read-only directory for ordinary users, but do not assume every file beneath it is read-only just from that: procfs exposes individual kernel variables, and some can be writable.

Checkpoint

If ls says the path does not exist, check /proc itself before trying to create anything. This is a kernel interface; a plain 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 an easier later comparison:

$ 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 list different names. The manual only says /proc/sys/debug/ may be empty; it never promises these two names, or any particular list. That distinction matters when you move a check between kernel versions, distributions, containers and restricted environments: a missing entry is not evidence a package needs reinstalling, and a name seen on one host is not a deployment prerequisite for another.

3. Read values without changing them

Read each discovered file directly. This is ordinary, non-destructive:

$ 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 go unmatched on an empty directory, which is why the file test is included; it also stops a subdirectory or unusual procfs entry from being treated as a scalar value. Quote the path in scripts anyway: these kernel-generated names normally hold no whitespace, but 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 yet. Keep it that way until you have identified a specific control, read 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 it as security-sensitive or service-impacting, not a harmless test.

Warning

Do not run something like echo 0 > /proc/sys/debug/example with a guessed name. That example name is intentionally invalid: names and accepted values must come from documentation for the exact kernel interface you are operating, and a failed write 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; never paste a placeholder as though it were a real setting. The sudo command is the elevated step, and the final line restores the captured value, though it is not a universal undo for changes that affect running components, failed writes, or a host that reboots between commands.

5. Diagnose an unexpected result

Separate four cases before you act:

  • Directory absent.
  • Directory present but empty.
  • A named file is absent.
  • 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 fits an empty directory, and it is safer than assuming a missing line means the value is zero. If a container or hardened environment shows a different view, compare its procfs mount and permissions with the host before changing either.

Do not reach for elevated privileges just because a read failed. Check the error and mount state first. If a documented control genuinely needs privilege, run only the specific read or write that requires it, and note the command's status.

Done means

  • Checked, not created: /proc/sys/debug was inspected without creating or modifying files.
  • Recorded the actual entries and values present on this kernel.
  • Treated an empty directory as documented behaviour, not a fault.
  • Guessed nothing: no control name or value was borrowed from another machine.
  • Planned any future write with a documented target, an explicit rollback, and a clearly marked elevated command.