Files
derek.holloway 7502bf64a4
CodeQL / Analyze (actions) (push) Canceled after 0s
CodeQL / Analyze (python) (push) Canceled after 0s
pre-commit / pre-commit (push) Canceled after 0s
Multi-Arch CI / setup (push) Canceled after 0s
Publish build_manylinux_x86_64 images / publish_build_manylinux_x86_64 (push) Canceled after 0s
Setup (Multi-Arch) / setup (push) Canceled after 0s
Multi-Arch CI / Linux::${{ fromJSON(needs.setup.outputs.linux_build_config || '{}').build_variant_label || 'skip' }} (push) Canceled after 0s
Publish TheRock Docker image / build-and-push-image (push) Canceled after 0s
Publish no_rocm_image_ubi10 image / publish_no_rocm_image_ubi10 (push) Canceled after 0s
Multi-Arch CI / Windows::${{ fromJSON(needs.setup.outputs.windows_build_config || '{}').build_variant_label || 'skip' }} (push) Canceled after 0s
Publish TheRock Docker image / build-and-push-image (push) Canceled after 0s
Multi-Arch CI / Manifest Diff (push) Canceled after 0s
TheRock Manifest Diff Report / Generate Manifest Diff Report (push) Canceled after 0s
Multi-Arch CI / CI Summary (push) Canceled after 0s
Publish no_rocm_image_ubuntu24_04 images / publish_no_rocm_image_ubuntu24_04 (push) Canceled after 0s
Publish no_rocm_image_ubuntu24_04_ocl_rt images / publish_no_rocm_image_ubuntu24_04_ocl_rt (push) Canceled after 0s
Publish TheRock Docker image / build-and-push-image (push) Canceled after 0s
Publish TheRock Docker image / build-and-push-image (push) Canceled after 0s
Publish no_rocm_image_ubuntu24_04 images / publish_no_rocm_image_ubuntu24_04_rocgdb (push) Canceled after 0s
Publish no_rocm_image_ubuntu24_04_rocgdb images / publish_no_rocm_image_ubuntu24_04_rocgdb (push) Canceled after 0s
Publish no_rocm_image_ubuntu24_04 images / publish_no_rocm_image_ubuntu24_04_ocl_rt (push) Canceled after 0s
Publish TheRock Docker image / build-and-push-image (push) Canceled after 0s
Unit Tests / Unit Tests :: ubuntu-24.04 (push) Canceled after 0s
Unit Tests / Unit Tests :: windows-2022 (push) Canceled after 0s
Publish no_rocm_image_ubuntu24_04 images / publish_no_rocm_image_ubuntu24_04_media (push) Canceled after 0s
Unit Tests / Unit Tests Summary (push) Canceled after 0s
Publish no_rocm_image_ubuntu24_04 images / publish_no_rocm_image_ubuntu24_04_openmpi (push) Canceled after 0s
Flatten subprojects into a single base monorepo
2026-09-02 16:34:47 -07:00

251 lines
10 KiB
Python

"""
Make sure the frame variable -g, -a, and -l flags work.
"""
import lldb
import lldbsuite.test.lldbutil as lldbutil
from lldbsuite.test.decorators import *
from lldbsuite.test.lldbtest import *
import os
import shutil
import time
class TestFrameVar(TestBase):
# If your test case doesn't stress debug info, then
# set this to true. That way it won't be run once for
# each debug info format.
NO_DEBUG_INFO_TESTCASE = True
SHARED_BUILD_TESTCASE = False
def test_frame_var(self):
self.build()
self.do_test()
def do_test(self):
_, _, thread, _ = lldbutil.run_to_source_breakpoint(
self, "Set a breakpoint here", lldb.SBFileSpec("main.c")
)
command_result = lldb.SBCommandReturnObject()
interp = self.dbg.GetCommandInterpreter()
# Ensure --regex can find globals if it is the very first frame var command.
self.expect("frame var --regex g_", substrs=["g_var"])
# Ensure the requested scope is respected:
self.expect(
"frame var --regex argc --no-args",
error=True,
substrs=["no variables matched the regular expression 'argc'"],
)
# Just get args:
result = interp.HandleCommand("frame var -l", command_result)
self.assertEqual(
result, lldb.eReturnStatusSuccessFinishResult, "frame var -a didn't succeed"
)
output = command_result.GetOutput()
self.assertIn("argc", output, "Args didn't find argc")
self.assertIn("argv", output, "Args didn't find argv")
self.assertNotIn("test_var", output, "Args found a local")
self.assertNotIn("g_var", output, "Args found a global")
value_list = command_result.GetValues(lldb.eNoDynamicValues)
self.assertGreaterEqual(value_list.GetSize(), 2)
value_names = []
for value in value_list:
value_names.append(value.GetName())
self.assertIn("argc", value_names)
self.assertIn("argv", value_names)
# Just get locals:
result = interp.HandleCommand("frame var -a", command_result)
self.assertEqual(
result, lldb.eReturnStatusSuccessFinishResult, "frame var -a didn't succeed"
)
output = command_result.GetOutput()
self.assertNotIn("argc", output, "Locals found argc")
self.assertNotIn("argv", output, "Locals found argv")
self.assertIn("test_var", output, "Locals didn't find test_var")
self.assertNotIn("g_var", output, "Locals found a global")
# Get the file statics:
result = interp.HandleCommand("frame var -l -a -g", command_result)
self.assertEqual(
result, lldb.eReturnStatusSuccessFinishResult, "frame var -a didn't succeed"
)
output = command_result.GetOutput()
self.assertNotIn("argc", output, "Globals found argc")
self.assertNotIn("argv", output, "Globals found argv")
self.assertNotIn("test_var", output, "Globals found test_var")
self.assertIn("g_var", output, "Globals didn't find g_var")
def check_frame_variable_errors(self, thread, error_strings):
command_result = lldb.SBCommandReturnObject()
interp = self.dbg.GetCommandInterpreter()
result = interp.HandleCommand("frame variable", command_result)
self.assertEqual(
result, lldb.eReturnStatusFailed, "frame var succeeded unexpectedly"
)
command_error = command_result.GetError()
frame = thread.GetFrameAtIndex(0)
var_list = frame.GetVariables(True, True, False, True)
self.assertEqual(var_list.GetSize(), 0)
api_error = var_list.GetError()
api_error_str = api_error.GetCString()
for s in error_strings:
self.assertIn(s, command_error)
for s in error_strings:
self.assertIn(s, api_error_str)
# Check the structured error data.
data = api_error.GetErrorData()
version = data.GetValueForKey("version")
self.assertEqual(version.GetIntegerValue(), 1)
err_ty = data.GetValueForKey("type")
self.assertEqual(err_ty.GetIntegerValue(), lldb.eErrorTypeGeneric)
message = str(data.GetValueForKey("errors").GetItemAtIndex(0))
for s in error_strings:
self.assertIn(s, message)
@skipIfRemote
@skipUnlessDarwin
def test_darwin_dwarf_missing_obj(self):
"""
Test that if we build a binary with DWARF in .o files and we remove
the .o file for main.cpp, that we get an appropriate error when we
do 'frame variable' that explains why we aren't seeing variables.
"""
self.build(debug_info="dwarf")
exe = self.getBuildArtifact("a.out")
main_obj = self.getBuildArtifact("main.o")
# Delete the main.o file that contains the debug info so we force an
# error when we run to main and try to get variables
os.unlink(main_obj)
# We have to set a named breakpoint because we don't have any debug info
# because we deleted the main.o file.
(target, process, thread, bkpt) = lldbutil.run_to_name_breakpoint(self, "main")
error_strings = [
'debug map object file "',
'main.o" containing debug info does not exist, debug info will not be loaded',
]
self.check_frame_variable_errors(thread, error_strings)
@skipIfRemote
@skipUnlessDarwin
def test_darwin_dwarf_obj_mod_time_mismatch(self):
"""
Test that if we build a binary with DWARF in .o files and we update
the mod time of the .o file for main.cpp, that we get an appropriate
error when we do 'frame variable' that explains why we aren't seeing
variables.
"""
self.build(debug_info="dwarf")
exe = self.getBuildArtifact("a.out")
main_obj = self.getBuildArtifact("main.o")
# Set the modification time for main.o file to the current time after
# sleeping for 2 seconds. This ensures the modification time will have
# changed and will not match the modification time in the debug map and
# force an error when we run to main and try to get variables
time.sleep(2)
os.utime(main_obj, None)
# We have to set a named breakpoint because we don't have any debug info
# because we deleted the main.o file since the mod times don't match
# and debug info won't be loaded
(target, process, thread, bkpt) = lldbutil.run_to_name_breakpoint(self, "main")
error_strings = [
'debug map object file "',
'main.o" changed (actual: 0x',
", debug map: 0x",
") since this executable was linked, debug info will not be loaded",
]
self.check_frame_variable_errors(thread, error_strings)
@skipIfRemote
@skipIfWindows # Windows can't set breakpoints by name 'main' in this case.
def test_gline_tables_only(self):
"""
Test that if we build a binary with "-gline-tables-only" that we can
set a file and line breakpoint successfully, and get an error
letting us know that this build option was enabled when trying to
read variables.
"""
self.build(dictionary={"CFLAGS_EXTRAS": "-gline-tables-only"})
exe = self.getBuildArtifact("a.out")
# We have to set a named breakpoint because we don't have any debug info
# because we deleted the main.o file since the mod times don't match
# and debug info won't be loaded
(target, process, thread, bkpt) = lldbutil.run_to_name_breakpoint(self, "main")
error_strings = [
"no variable information is available in debug info for this compile unit"
]
self.check_frame_variable_errors(thread, error_strings)
@skipUnlessPlatform(["linux", "freebsd"])
@add_test_categories(["dwo"])
def test_fission_missing_dwo(self):
"""
Test that if we build a binary with "-gsplit-dwarf" that we can
set a file and line breakpoint successfully, and get an error
letting us know we were unable to load the .dwo file.
"""
self.build(dictionary={"CFLAGS_EXTRAS": "-gsplit-dwarf"})
exe = self.getBuildArtifact("a.out")
main_dwo = self.getBuildArtifact("main.dwo")
self.assertTrue(
os.path.exists(main_dwo), 'Make sure "%s" file exists' % (main_dwo)
)
# Delete the main.dwo file that contains the debug info so we force an
# error when we run to main and try to get variables.
os.unlink(main_dwo)
# We have to set a named breakpoint because we don't have any debug info
# because we deleted the main.o file since the mod times don't match
# and debug info won't be loaded
(target, process, thread, bkpt) = lldbutil.run_to_name_breakpoint(self, "main")
error_strings = [
'unable to locate .dwo debug file "',
'main.dwo" for skeleton DIE 0x',
]
self.check_frame_variable_errors(thread, error_strings)
@skipUnlessPlatform(["linux", "freebsd"])
@add_test_categories(["dwo"])
def test_fission_invalid_dwo_objectfile(self):
"""
Test that if we build a binary with "-gsplit-dwarf" that we can
set a file and line breakpoint successfully, and get an error
letting us know we were unable to load the .dwo file because it
existed, but it wasn't a valid object file.
"""
self.build(dictionary={"CFLAGS_EXTRAS": "-gsplit-dwarf"})
exe = self.getBuildArtifact("a.out")
main_dwo = self.getBuildArtifact("main.dwo")
self.assertTrue(
os.path.exists(main_dwo), 'Make sure "%s" file exists' % (main_dwo)
)
# Overwrite the main.dwo with the main.c source file so that the .dwo
# file exists, but it isn't a valid object file as there is an error
# for this case.
shutil.copyfile(self.getSourcePath("main.c"), main_dwo)
# We have to set a named breakpoint because we don't have any debug info
# because we deleted the main.o file since the mod times don't match
# and debug info won't be loaded
(target, process, thread, bkpt) = lldbutil.run_to_name_breakpoint(self, "main")
error_strings = [
'unable to load object file for .dwo debug file "'
'main.dwo" for unit DIE 0x',
]
self.check_frame_variable_errors(thread, error_strings)