Skip to content

Commit

Permalink
tests: linux_kernel: test built-in ORC unwinding
Browse files Browse the repository at this point in the history
Unwinding through a kernel module with no DWARF info would have been
impossible without support of built-in ORC. Further, the tests here
would not pass without 329bd5d ("Make StackFrame.name fall back to
symbol/PC and add StackFrame.function_name").

Signed-off-by: Stephen Brennan <stephen.s.brennan@oracle.com>
  • Loading branch information
brenns10 committed Dec 20, 2024
1 parent 2026435 commit 58de01c
Showing 1 changed file with 52 additions and 1 deletion.
53 changes: 52 additions & 1 deletion tests/linux_kernel/test_stack_trace.py
Original file line number Diff line number Diff line change
@@ -1,11 +1,14 @@
# Copyright (c) Meta Platforms, Inc. and affiliates.
# SPDX-License-Identifier: LGPL-2.1-or-later

import logging
import os
import re
import unittest

from _drgn_util.platform import NORMALIZED_MACHINE_NAME
from drgn import Object, Program, reinterpret
from drgn import MissingDebugInfoError, Object, Program, reinterpret
from drgn.helpers.linux import load_module_kallsyms
from tests import assertReprPrettyEqualsStr, modifyenv
from tests.linux_kernel import (
LinuxKernelTestCase,
Expand Down Expand Up @@ -59,6 +62,54 @@ def test_by_pid_dwarf(self):
def test_by_pid_orc(self):
self._test_by_pid(True)

@unittest.skipUnless(
NORMALIZED_MACHINE_NAME == "x86_64",
f"{NORMALIZED_MACHINE_NAME} does not use ORC",
)
@skip_unless_have_test_kmod
def test_by_pid_builtin_orc(self):
# ORC was introduced in kernel 4.14. Detect the presence of ORC or skip
# the test.
try:
self.prog.symbol("__start_orc_unwind")
except LookupError:
ver = self.prog["UTS_RELEASE"].string_().decode()
self.skipTest(f"ORC is not available for {ver}")

# Create a program with the core kernel debuginfo loaded,
# but without module debuginfo. Load a symbol finder using
# kallsyms so that the module's stack traces can still have
# usable frame names.
prog = Program()
prog.set_kernel()
try:
prog.load_default_debug_info()
except MissingDebugInfoError:
pass
kallsyms = load_module_kallsyms(prog)
prog.register_symbol_finder("module_kallsyms", kallsyms, enable_index=1)
for thread in prog.threads():
if b"drgn_test_kthread".startswith(thread.object.comm.string_()):
pid = thread.tid
break
else:
self.fail("couldn't find drgn_test_kthread")
with self.assertLogs("drgn", logging.DEBUG) as log:
self._test_drgn_test_kthread_trace(prog.stack_trace(pid))

# To be sure that we actually used ORC to unwind through the drgn_test
# stack frames, search for the log output. We don't know which ORC
# version is used, so just ensure that we have a log line that mentions
# loading ORC.
expr = re.compile(
r"DEBUG:drgn:Loaded built-in ORC \(v\d+\) for module drgn_test"
)
for line in log.output:
if expr.fullmatch(line):
break
else:
self.fail("Did not load built-in ORC for drgn_test")

@skip_unless_have_test_kmod
def test_by_pt_regs(self):
pt_regs = self.prog["drgn_test_kthread_pt_regs"]
Expand Down

0 comments on commit 58de01c

Please sign in to comment.