blob: 5e74f0c3f8bfa6bbb6d9ed17ee426b49e4423f33 [file] [log] [blame]
"""Test corefiles with "main bin spec"/"load binary" with only addrs work."""
import os
import re
import subprocess
import lldb
from lldbsuite.test.decorators import *
from lldbsuite.test.lldbtest import *
from lldbsuite.test import lldbutil
class TestMultipleBinaryCorefile(TestBase):
def initial_setup(self):
self.build()
self.aout_exe_basename = "a.out"
self.libone_exe_basename = "libone.dylib"
self.libtwo_exe_basename = "libtwo.dylib"
self.aout_exe = self.getBuildArtifact(self.aout_exe_basename)
self.aout_slide = 0x5000
self.libone_exe = self.getBuildArtifact(self.libone_exe_basename)
self.libone_slide = 0x100840000
self.libtwo_exe = self.getBuildArtifact(self.libtwo_exe_basename)
self.libtwo_slide = 0
self.corefile = self.getBuildArtifact("multiple-binaries.core")
self.create_corefile = self.getBuildArtifact("create-multibin-corefile")
cmd="%s %s %s@%x %s@%x %s@%x" % (self.create_corefile, self.corefile,
self.aout_exe, self.aout_slide,
self.libone_exe, self.libone_slide,
self.libtwo_exe, self.libtwo_slide)
call(cmd, shell=True)
def load_corefile_and_test(self):
target = self.dbg.CreateTarget('')
err = lldb.SBError()
if self.TraceOn():
self.runCmd("script print('loading corefile %s')" % self.corefile)
process = target.LoadCore(self.corefile)
self.assertEqual(process.IsValid(), True)
if self.TraceOn():
self.runCmd("script print('image list after loading corefile:')")
self.runCmd("image list")
self.assertEqual(target.GetNumModules(), 3)
fspec = target.GetModuleAtIndex(0).GetFileSpec()
self.assertEqual(fspec.GetFilename(), self.aout_exe_basename)
# libone.dylib was never loaded into lldb, see that we added a memory module.
fspec = target.GetModuleAtIndex(1).GetFileSpec()
self.assertIn('memory-image', fspec.GetFilename())
dwarfdump_uuid_regex = re.compile(
'UUID: ([-0-9a-fA-F]+) \(([^\(]+)\) .*')
dwarfdump_cmd_output = subprocess.check_output(
('/usr/bin/dwarfdump --uuid "%s"' % self.libone_exe), shell=True).decode("utf-8")
libone_uuid = None
for line in dwarfdump_cmd_output.splitlines():
match = dwarfdump_uuid_regex.search(line)
if match:
libone_uuid = match.group(1)
memory_image_uuid = target.GetModuleAtIndex(1).GetUUIDString()
self.assertEqual(libone_uuid, memory_image_uuid)
fspec = target.GetModuleAtIndex(2).GetFileSpec()
self.assertEqual(fspec.GetFilename(), self.libtwo_exe_basename)
# Executables "always" have this base address
aout_load = target.GetModuleAtIndex(0).GetObjectFileHeaderAddress().GetLoadAddress(target)
self.assertEqual(aout_load, 0x100000000 + self.aout_slide)
# Value from Makefile
libone_load = target.GetModuleAtIndex(1).GetObjectFileHeaderAddress().GetLoadAddress(target)
self.assertEqual(libone_load, self.libone_slide)
# Value from Makefile
libtwo_load = target.GetModuleAtIndex(2).GetObjectFileHeaderAddress().GetLoadAddress(target)
self.assertEqual(libtwo_load, self.libtwo_slide)
self.dbg.DeleteTarget(target)
self.dbg.Clear()
NO_DEBUG_INFO_TESTCASE = True
@skipIf(archs=no_match(['x86_64', 'arm64', 'arm64e', 'aarch64']))
@skipIfRemote
@skipUnlessDarwin
def test_corefile_binaries_dsymforuuid(self):
self.initial_setup()
if self.TraceOn():
self.runCmd("log enable lldb dyld host")
self.addTearDownHook(lambda: self.runCmd("log disable lldb dyld host"))
## We can hook in our dsym-for-uuid shell script to lldb with this env
## var instead of requiring a defaults write.
dsym_for_uuid = self.getBuildArtifact("dsym-for-uuid.sh")
os.environ['LLDB_APPLE_DSYMFORUUID_EXECUTABLE'] = dsym_for_uuid
if self.TraceOn():
print("Setting env var LLDB_APPLE_DSYMFORUUID_EXECUTABLE=" + dsym_for_uuid)
self.addTearDownHook(lambda: os.environ.pop('LLDB_APPLE_DSYMFORUUID_EXECUTABLE', None))
self.runCmd("settings set target.load-script-from-symbol-file true")
self.addTearDownHook(lambda: self.runCmd("settings set target.load-script-from-symbol-file false"))
dwarfdump_uuid_regex = re.compile(
'UUID: ([-0-9a-fA-F]+) \(([^\(]+)\) .*')
dwarfdump_cmd_output = subprocess.check_output(
('/usr/bin/dwarfdump --uuid "%s"' % self.libtwo_exe), shell=True).decode("utf-8")
libtwo_uuid = None
for line in dwarfdump_cmd_output.splitlines():
match = dwarfdump_uuid_regex.search(line)
if match:
libtwo_uuid = match.group(1)
self.assertNotEqual(libtwo_uuid, None, "Could not get uuid of built libtwo.dylib")
### Create our dsym-for-uuid shell script which returns aout_exe
shell_cmds = [
'#! /bin/sh',
'# the last argument is the uuid',
'while [ $# -gt 1 ]',
'do',
' shift',
'done',
'ret=0',
'echo "<?xml version=\\"1.0\\" encoding=\\"UTF-8\\"?>"',
'echo "<!DOCTYPE plist PUBLIC \\"-//Apple//DTD PLIST 1.0//EN\\" \\"http://www.apple.com/DTDs/PropertyList-1.0.dtd\\">"',
'echo "<plist version=\\"1.0\\">"',
'',
'if [ "$1" != "%s" ]' % (libtwo_uuid),
'then',
' echo "<key>DBGError</key><string>not found</string>"',
' echo "</plist>"',
' exit 1',
'fi',
' uuid=%s' % libtwo_uuid,
' bin=%s' % self.libtwo_exe,
' dsym=%s.dSYM/Contents/Resources/DWARF/%s' % (self.libtwo_exe, os.path.basename(self.libtwo_exe)),
'echo "<dict><key>$uuid</key><dict>"',
'',
'echo "<key>DBGDSYMPath</key><string>$dsym</string>"',
'echo "<key>DBGSymbolRichExecutable</key><string>$bin</string>"',
'echo "</dict></dict></plist>"',
'exit $ret'
]
with open(dsym_for_uuid, "w") as writer:
for l in shell_cmds:
writer.write(l + '\n')
os.chmod(dsym_for_uuid, 0o755)
# Register TWO of our binaries, but require dsymForUUID to find the third.
target = self.dbg.CreateTarget(self.aout_exe, '', '', False, lldb.SBError())
self.dbg.DeleteTarget(target)
if self.TraceOn():
self.runCmd("script print('Global image list, before loading corefile:')")
self.runCmd("image list -g")
self.load_corefile_and_test()
@skipIf(archs=no_match(['x86_64', 'arm64', 'arm64e', 'aarch64']))
@skipIfRemote
@skipUnlessDarwin
def test_corefile_binaries_preloaded(self):
self.initial_setup()
if self.TraceOn():
self.runCmd("log enable lldb dyld host")
self.addTearDownHook(lambda: self.runCmd("log disable lldb dyld host"))
# Register all three binaries in lldb's global module
# cache, then throw the Targets away.
target = self.dbg.CreateTarget(self.aout_exe, '', '', False, lldb.SBError())
self.dbg.DeleteTarget(target)
target = self.dbg.CreateTarget(self.libtwo_exe, '', '', False, lldb.SBError())
self.dbg.DeleteTarget(target)
if self.TraceOn():
self.runCmd("script print('Global image list, before loading corefile:')")
self.runCmd("image list -g")
self.load_corefile_and_test()