Home / Alt manpages / proc_kallsyms(5)

  • proc_kallsyms(5)
  • File format
  • linux

Read /proc/kallsyms and Find a Kernel Symbol

A stack trace full of raw hex is useless until something turns those addresses back into names, and /proc/kallsyms is that something. This is a read-only investigation: none of the commands below changes the kernel or loads a module. In a few minutes you will be able to inspect the running kernel's exported symbol table, find a named symbol, and tell a readable symbol list apart from a deliberately hidden address.

Before you start

You need a Linux system with /proc mounted and a shell, no root required. The examples were checked on Linux 6.8.0-139-generic with the locally installed manpages package version 6.7-2. The initial read can take a moment on a busy system because the file holds many thousands of lines.

Checkpoint

If /proc/kallsyms does not exist, stop here and check that /proc is mounted. Do not create a regular file at that path: it would hide the real diagnostic rather than fix the kernel interface.

1. Confirm the interface is present

The manpage describes /proc/kallsyms as the kernel's exported symbol definitions, used by the module tools to dynamically link and bind loadable modules. It has existed since Linux 2.5.71. The older /proc/ksyms name belongs to Linux 1.1.23 through 2.5.47; do not substitute it in a current script.

test -r /proc/kallsyms && echo "readable" || echo "missing or unreadable"
stat -c '%A %U:%G %s %n' /proc/kallsyms

On the checked machine, the result is a world-readable procfs entry owned by root:root, with a reported size of zero. That zero size is normal for a procfs pseudo-file, not evidence the table is empty. Test the content by reading it, not by trusting stat.

2. Read a small, useful sample

Each normal line has three whitespace-separated fields: an address, a symbol type, and a symbol name. Use head for a bounded sample so a terminal or log does not fill unexpectedly.

head -n 20 /proc/kallsyms

A typical line resembles this shape:

ffffffff81000000 T example_symbol
  • Address. The kernel's symbol address as exposed by this interface. It varies by boot, so never treat a captured address as stable across reboots.
  • Type. A single letter drawn from the kernel symbol table.
  • Name. The symbol name itself, the field you will usually search on.

Checkpoint

You have verified the file can be read and that its output has the expected three-column shape. If the command prints nothing, record the kernel version and investigate the procfs and kernel configuration before writing tooling around the result.

3. Search for a symbol safely

Search the stream instead of copying the whole file. The expression below looks for an exact symbol name in the final column, so a name such as printk is not confused with a longer name that merely contains that text.

awk '$3 == "printk" { print }' /proc/kallsyms

On some kernels there will be no exact match, and that is a valid result: the symbol may not be exported, may have been renamed, or may not exist in this particular build. To inspect several related names while keeping the output bounded:

awk '$3 ~ /^(printk|vprintk)/ { print }' /proc/kallsyms | head -n 20

Use fixed strings when the name comes from a script argument, or validate that argument before placing it in an awk program. Avoid treating symbol names as shell commands. Reading this file is passive; it does not resolve a symbol for a program and it does not load a module.

4. Explain zero addresses before debugging further

A common, security-conscious result is a table full of addresses such as 0000000000000000, with the symbol names still present. On the checked host, the first lines had this form, so the interface was working even though the addresses were concealed. Check the kernel's pointer exposure setting without changing it:

printf 'kptr_restrict='; cat /proc/sys/kernel/kptr_restrict

The kernel documentation defines kptr_restrict as a control on exposing kernel addresses through procfs and related interfaces.

  • 0. The less restrictive hashed representation described by the kernel documentation.
  • 1. An additional privilege and identity check applies.
  • 2. Addresses protected by this mechanism are replaced with zeroes regardless of privilege.

Other kernel configuration and security controls can also affect what you see.

Security boundary

Do not "fix" a zeroed table by writing a new value to /proc/sys/kernel/kptr_restrict. That is a system-wide security change and requires elevated privileges. It can expose kernel address information that an administrator intentionally chose to conceal. For ordinary symbol-name inspection, zero addresses are sufficient.

5. Use the result in a diagnostic

Capture only the evidence needed for the incident: the kernel release, the pointer restriction value, and a bounded symbol match. This avoids creating a large, sensitive dump in a ticket or log.

uname -r
cat /proc/sys/kernel/kptr_restrict
awk '$3 == "printk" { print }' /proc/kallsyms | head -n 5

Keep the output tied to the same boot. A module may be loaded or unloaded, addresses may be hidden or hashed, and kernel builds do not promise the same symbol set. If a diagnostic tool needs a symbol address, check its documentation for the required privileges and kernel-specific assumptions rather than parsing this file as if it were a stable API.

Done means

  • File is readable. /proc/kallsyms exists and can be read without elevated privileges.
  • Shape is recognised. You can pick out the address, type and name columns in a sample line.
  • Search is precise. You can perform an exact symbol-name search without copying the whole table.
  • Zeroes are explained. You checked kptr_restrict before treating zero addresses as a fault.
  • Nothing was weakened. You kept the investigation read-only and did not touch kernel pointer protections.