Skip to content

Commit

Permalink
Make sure to use kallsyms as fallback
Browse files Browse the repository at this point in the history
The kernel image file, even if present, is limited in which addresses it
is able to resolve. Kernel addresses belonging to modules, for example,
can't be symbolized this way. While we may eventually add better support
for kernel modules, for now the best course of action seems to be to
fall back to usage of kallsyms.

Signed-off-by: Daniel Müller <[email protected]>
  • Loading branch information
d-e-s-o committed Jan 30, 2025
1 parent f56500e commit fbc709e
Show file tree
Hide file tree
Showing 5 changed files with 74 additions and 21 deletions.
8 changes: 8 additions & 0 deletions capi/include/blazesym.h
Original file line number Diff line number Diff line change
Expand Up @@ -812,6 +812,10 @@ typedef struct blaze_symbolize_src_kernel {
* When `NULL`, this will refer to `kallsyms` of the running kernel.
* If set to `'\0'` (`""`) usage of `kallsyms` will be disabled.
* Otherwise the copy at the given path will be used.
*
* If both a kernel image as well as a `kallsyms` file are found,
* the kernel image will generally be given preference and
* `kallsyms` acts as a fallback.
*/
const char *kallsyms;
/**
Expand All @@ -822,6 +826,10 @@ typedef struct blaze_symbolize_src_kernel {
* kernel version. If set to `'\0'` (`""`) usage of a kernel image
* will be disabled. Otherwise the copy at the given path will be
* used.
*
* If both a kernel image as well as a `kallsyms` file are found,
* the kernel image will generally be given preference and
* `kallsyms` acts as a fallback.
*/
const char *kernel_image;
/**
Expand Down
8 changes: 8 additions & 0 deletions capi/src/symbolize.rs
Original file line number Diff line number Diff line change
Expand Up @@ -108,6 +108,10 @@ pub struct blaze_symbolize_src_kernel {
/// When `NULL`, this will refer to `kallsyms` of the running kernel.
/// If set to `'\0'` (`""`) usage of `kallsyms` will be disabled.
/// Otherwise the copy at the given path will be used.
///
/// If both a kernel image as well as a `kallsyms` file are found,
/// the kernel image will generally be given preference and
/// `kallsyms` acts as a fallback.
pub kallsyms: *const c_char,
/// The path of the kernel image to use.
///
Expand All @@ -116,6 +120,10 @@ pub struct blaze_symbolize_src_kernel {
/// kernel version. If set to `'\0'` (`""`) usage of a kernel image
/// will be disabled. Otherwise the copy at the given path will be
/// used.
///
/// If both a kernel image as well as a `kallsyms` file are found,
/// the kernel image will generally be given preference and
/// `kallsyms` acts as a fallback.
pub kernel_image: *const c_char,
/// Whether or not to consult debug symbols from `kernel_image`
/// to satisfy the request (if present).
Expand Down
23 changes: 19 additions & 4 deletions src/kernel/resolver.rs
Original file line number Diff line number Diff line change
Expand Up @@ -41,10 +41,25 @@ impl KernelResolver {

impl Symbolize for KernelResolver {
fn find_sym(&self, addr: Addr, opts: &FindSymOpts) -> Result<Result<ResolvedSym<'_>, Reason>> {
if let Some(elf_resolver) = self.elf_resolver.as_ref() {
elf_resolver.find_sym(addr, opts)
} else {
self.ksym_resolver.as_ref().unwrap().find_sym(addr, opts)
match (self.elf_resolver.as_ref(), self.ksym_resolver.as_ref()) {
(Some(elf_resolver), None) => elf_resolver.find_sym(addr, opts),
(None, Some(ksym_resolver)) => ksym_resolver.find_sym(addr, opts),
(Some(elf_resolver), Some(ksym_resolver)) => {
// We give preference to the kernel image resolver, because it
// is likely to report more information. If it could not find
// an address, though, we fall back to kallsyms. This is
// helpful for example for kernel modules, which naturally are
// not captured by the core kernel image.
let result = elf_resolver.find_sym(addr, opts)?;
if result.is_ok() {
Ok(result)
} else {
ksym_resolver.find_sym(addr, opts)
}
}
// SANITY: We ensure that at least one resolver is present at
// construction time.
(None, None) => unreachable!(),
}
}
}
Expand Down
8 changes: 8 additions & 0 deletions src/symbolize/source.rs
Original file line number Diff line number Diff line change
Expand Up @@ -173,6 +173,10 @@ pub struct Kernel {
/// By default, this will refer to `kallsyms` of the running kernel.
/// If set to [`None`][MaybeDefault::None] usage of `kallsyms` will
/// be disabled. Otherwise the copy at the given path will be used.
///
/// If both a kernel image as well as a `kallsyms` file are found,
/// the kernel image will generally be given preference and
/// `kallsyms` acts as a fallback.
pub kallsyms: MaybeDefault<PathBuf>,
/// The path of the kernel image to use.
///
Expand All @@ -181,6 +185,10 @@ pub struct Kernel {
/// kernel version. If set to [`None`][MaybeDefault::None] usage of
/// a kernel image will be disabled. Otherwise the copy at the given
/// path will be used.
///
/// If both a kernel image as well as a `kallsyms` file are found,
/// the kernel image will generally be given preference and
/// `kallsyms` acts as a fallback.
pub kernel_image: MaybeDefault<PathBuf>,
/// Whether or not to consult debug symbols from `kernel_image`
/// to satisfy the request (if present).
Expand Down
48 changes: 31 additions & 17 deletions tests/suite/symbolize.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ use std::io;
use std::io::Read as _;
use std::io::Write as _;
use std::path::Path;
use std::path::PathBuf;
use std::process::Command;
use std::process::Stdio;
use std::str;
Expand Down Expand Up @@ -1041,23 +1042,36 @@ fn symbolize_kernel_no_valid_source() {
/// Test symbolization of a kernel address present in a kallsyms style
/// file.
#[test]
fn symbolize_kernel() {
let kernel = Kernel {
kallsyms: MaybeDefault::from(
Path::new(&env!("CARGO_MANIFEST_DIR"))
.join("data")
.join("kallsyms"),
),
..Default::default()
};
let src = Source::Kernel(kernel);
let symbolizer = Symbolizer::new();
let symbolized = symbolizer
.symbolize_single(&src, Input::AbsAddr(0xc080a470))
.unwrap();
let init_task_sym = symbolized.into_sym().unwrap();
assert_eq!(init_task_sym.name, "init_task");
assert_eq!(init_task_sym.code_info, None);
fn symbolize_kernel_kallsyms() {
fn test(kernel_image: MaybeDefault<PathBuf>) {
let kernel = Kernel {
kallsyms: MaybeDefault::from(
Path::new(&env!("CARGO_MANIFEST_DIR"))
.join("data")
.join("kallsyms"),
),
kernel_image,
..Default::default()
};
let src = Source::Kernel(kernel);
let symbolizer = Symbolizer::new();
let symbolized = symbolizer
.symbolize_single(&src, Input::AbsAddr(0xc080a470))
.unwrap();
let init_task_sym = symbolized.into_sym().unwrap();
assert_eq!(init_task_sym.name, "init_task");
assert_eq!(init_task_sym.code_info, None);
}

test(MaybeDefault::None);
// Provide a valid "kernel" image file, but given that it does not
// contain the address we attempt to symbolize we should end up
// falling back to using kallsyms.
test(MaybeDefault::Some(
Path::new(&env!("CARGO_MANIFEST_DIR"))
.join("data")
.join("test-stable-addrs.bin"),
));
}

/// Test symbolization of a "kernel" address in an ELF file.
Expand Down

0 comments on commit fbc709e

Please sign in to comment.