Home / Alt manpages / perf-kallsyms(1)

  • perf-kallsyms(1)
  • User command
  • linux

Search Kernel Symbols Safely with perf kallsyms

You will finish with a read-only way to look up one or more symbols in the running kernel and understand what the result says about the kernel image or a loaded module. The examples follow the installed perf-kallsyms(1) manual from linux-tools-common version 6.8.0-142.142. The command itself is provided by the matching kernel-specific perf tools package, so the dispatcher and the tool version can differ on another host.

Allow about ten minutes. You need a shell, perf, and permission to read the running kernel's kallsyms information. These commands inspect live kernel state only. They do not load a module, change a trace setting, write to disk or restart a service. Do not add sudo automatically: use elevated privileges only if your system's access policy requires them.

1. Check which perf you are using

Start by checking the dispatcher and package metadata. This is an ordinary, read-only step:

$ command -v perf
/usr/bin/perf
$ perf --version
perf version X.Y

The version line is host-specific. On Debian and Ubuntu systems, check the common package as well as any kernel-specific package that is installed:

$ dpkg-query -W -f='${Package} ${Version}\n' linux-tools-common linux-tools-$(uname -r) 2>/dev/null
linux-tools-common 6.8.0-142.142

A warning that matching tools for uname -r are missing is a tooling problem, not evidence that the kernel has no symbols. Stop at this checkpoint and install the matching package through your normal system-management process. Do not work around a version mismatch by copying a random perf binary into /usr/local/bin.

2. Choose a symbol that exists on this host

perf kallsyms searches the running kernel's kallsyms file. Symbol names vary with the kernel version, configuration, architecture and loaded modules, so do not assume that an example name from another machine is present. Select a name from the local file:

$ awk 'NF >= 3 { print $3; exit }' /proc/kallsyms
__per_cpu_start

The printed name is only an example. On a restricted system, addresses may appear as zeroes while names remain visible. If the file cannot be read, record the error and check the host's permissions and kernel security policy. Reading this file is not a reason to disable access controls.

Set the result as a shell variable so that you do not mistype it. Quote the variable even though normal kernel symbol names do not contain spaces:

$ SYMBOL=$(awk 'NF >= 3 { print $3; exit }' /proc/kallsyms)
$ test -n "$SYMBOL" && printf 'looking up: %s\n' "$SYMBOL"
looking up: __per_cpu_start

Checkpoint: if the final command printed nothing, you have not selected a symbol. Choose another entry or investigate access to /proc/kallsyms before calling perf.

3. Run the basic lookup

Pass the symbol as the positional argument after the command name:

$ perf kallsyms "$SYMBOL"

The exact formatting depends on the installed perf build and the symbol. A successful lookup prints information about the matching symbol, including its DSO, the kallsyms start and end addresses, and the corresponding ELF kallsyms addresses when the symbol belongs to a module. Treat the output as diagnostic data, not as a stable machine-readable interface.

If the command returns a non-zero status or reports that the symbol was not found, first compare the argument with the exact name printed from /proc/kallsyms. A symbol may have disappeared between the two reads if a module was unloaded. Do not reload a module merely to make a diagnostic example pass.

4. Search for several symbols

The documented syntax accepts a comma-separated list. There must be no shell space between names unless you deliberately quote the whole list:

$ perf kallsyms 'SYMBOL_A,SYMBOL_B'

Replace both placeholders with exact names from your own /proc/kallsyms output. For a repeatable lookup, build the list from names you have checked rather than guessing common kernel function names:

$ FIRST=$(awk 'NF >= 3 { print $3; exit }' /proc/kallsyms)
$ SECOND=$(awk -v first="$FIRST" 'NF >= 3 && $3 != first { print $3; exit }' /proc/kallsyms)
$ perf kallsyms "$FIRST,$SECOND"

This is still a snapshot-based diagnostic. A module or kernel state can change while you are investigating, so preserve the command and timestamp if another person needs to reproduce the result.

5. Turn on verbose diagnostics when the match is unclear

Use --verbose, or its short form -v, when you need details about symbol-table loading:

$ perf kallsyms --verbose "$SYMBOL"

Verbose output is for a human investigation. Its detail level and wording are not promised by the manual as a scripting format. Keep the normal lookup in automation, and enable verbosity only when collecting a diagnostic report.

Do not confuse a zero or missing address with a failed lookup without checking the security context. Kernel symbol addresses can be hidden by configured restrictions. A successful name match therefore does not automatically mean that every address is available to an unprivileged reader.

6. Handle missing tools and permissions

If perf says that it cannot find tools for the running kernel, compare uname -r with the package name the dispatcher requests. Install the matching distribution package using your normal change process, then rerun the version check. That package installation is a system change and may require elevated privileges; it is not part of the read-only lookup.

If /proc/kallsyms or the perf command reports an access error, do not weaken kernel protection settings as a quick fix. Ask the system owner which read permission is appropriate. If policy permits a privileged diagnostic, run only the single lookup with sudo perf kallsyms "$SYMBOL", review the command before pressing Enter, and do not place untrusted text in the variable. There is nothing to undo after a lookup itself, but keep any captured output secure because kernel symbol information can help an attacker understand the host.

Done means

  • You confirmed the perf dispatcher and relevant package version.
  • You selected a symbol from the running host instead of assuming it exists.
  • A basic lookup returned the symbol's diagnostic information.
  • You know that multiple names are passed as one comma-separated argument.
  • You used --verbose only for investigation, not as a parsing contract.
  • You kept the lookup read-only and did not weaken kernel security settings to obtain addresses.