Files
clang-p2996/lldb/test/API/functionalities/dyld-exec-linux/TestDyldExecLinux.py
Greg Clayton 879a47a55f Add the ability to debug through an exec into ld
A previous commit enabled LLDB to be able to debug a program launched via ld: https://reviews.llvm.org/D108061.

This commit adds the ability to debug a program launched via ld when it happens during an exec into the dynamic loader. There was an issue where after the exec we would locate the rendezvous structure right away but it didn't contain any valid values and we would try to set the dyanamic loader breakpoint at address zero. This patch fixes that and adds a test.

Differential Revision: https://reviews.llvm.org/D125253
2022-05-09 16:07:40 -07:00

62 lines
2.2 KiB
Python

"""
Test that LLDB can launch a linux executable and then execs into the dynamic
loader into this program again.
"""
import lldb
import os
from lldbsuite.test.decorators import *
from lldbsuite.test.lldbtest import *
from lldbsuite.test import lldbutil
class TestLinux64ExecViaDynamicLoader(TestBase):
mydir = TestBase.compute_mydir(__file__)
@skipIf(oslist=no_match(['linux']))
@no_debug_info_test
@skipIf(oslist=["linux"], archs=["arm"])
def test(self):
self.build()
# Extracts path of the interpreter.
exe = self.getBuildArtifact("a.out")
spec = lldb.SBModuleSpec()
spec.SetFileSpec(lldb.SBFileSpec(exe))
interp_section = lldb.SBModule(spec).FindSection(".interp")
if not interp_section:
return
section_data = interp_section.GetSectionData()
error = lldb.SBError()
dyld_path = section_data.GetString(error,0)
if error.Fail():
return
target = self.dbg.CreateTarget(exe)
self.assertTrue(target, VALID_TARGET)
# Set a breakpoint in the main function that will get hit after the
# program exec's via the dynamic loader. The breakpoint will only get
# hit if we can successfully read the shared library lists in the
# DynamicLoaderPOSIXDYLD.cpp when we exec into the dynamic loader.
breakpoint_main = target.BreakpointCreateBySourceRegex("// Break here", lldb.SBFileSpec("main.cpp"))
# Setup our launch info to supply the dynamic loader path to the
# program so it gets two args:
# - path to a.out
# - path to dynamic loader
launch_info = lldb.SBLaunchInfo([dyld_path])
error = lldb.SBError()
process = target.Launch(launch_info, error)
self.assertSuccess(error)
threads = lldbutil.get_stopped_threads(process, lldb.eStopReasonExec)
self.assertEqual(len(threads), 1, "We got a thread stopped for exec.")
process.Continue();
# Stopped on main here.
self.assertEqual(process.GetState(), lldb.eStateStopped)
thread = process.GetSelectedThread()
self.assertIn("main", thread.GetFrameAtIndex(0).GetDisplayFunctionName())