diff --git a/lldb/packages/Python/lldbsuite/test/commands/target/set-exec/Makefile b/lldb/packages/Python/lldbsuite/test/commands/target/set-exec/Makefile new file mode 100644 --- /dev/null +++ b/lldb/packages/Python/lldbsuite/test/commands/target/set-exec/Makefile @@ -0,0 +1,3 @@ +C_SOURCES := main.c + +include Makefile.rules diff --git a/lldb/packages/Python/lldbsuite/test/commands/target/set-exec/TestSetExecutable.py b/lldb/packages/Python/lldbsuite/test/commands/target/set-exec/TestSetExecutable.py new file mode 100644 --- /dev/null +++ b/lldb/packages/Python/lldbsuite/test/commands/target/set-exec/TestSetExecutable.py @@ -0,0 +1,26 @@ +""" +Test that the first module of the target is set as an executable. +""" + +from __future__ import print_function + +from lldbsuite.test.lldbtest import * + + +class SetExecutableTestCase(TestBase): + + mydir = TestBase.compute_mydir(__file__) + + def test(self): + """Test adding images to the target.""" + self.build() + + # Create an empty target - it will have an empty triplet. + target = self.dbg.CreateTarget(None) + self.assertTrue(target, VALID_TARGET) + self.assertEqual(len(target.GetTriple()), 0) + + # Add a first module, which is treated as an executuble, so it's + # architecture will change the architecture of the target. + target.AddModule(self.getBuildArtifact("a.out"), None, None) + self.assertNotEqual(len(target.GetTriple()), 0) diff --git a/lldb/packages/Python/lldbsuite/test/commands/target/set-exec/main.c b/lldb/packages/Python/lldbsuite/test/commands/target/set-exec/main.c new file mode 100644 --- /dev/null +++ b/lldb/packages/Python/lldbsuite/test/commands/target/set-exec/main.c @@ -0,0 +1,3 @@ +int main() { + return 0; +} diff --git a/lldb/source/Target/Target.cpp b/lldb/source/Target/Target.cpp --- a/lldb/source/Target/Target.cpp +++ b/lldb/source/Target/Target.cpp @@ -2016,12 +2016,15 @@ // there wasn't an equivalent module in the list already, and if there was, // let's remove it. if (module_sp) { + bool isExecutable = false; ObjectFile *objfile = module_sp->GetObjectFile(); if (objfile) { switch (objfile->GetType()) { + case ObjectFile::eTypeExecutable: /// A normal executable + isExecutable = true; + LLVM_FALLTHROUGH; case ObjectFile::eTypeCoreFile: /// A core file that has a checkpoint of /// a program's execution state - case ObjectFile::eTypeExecutable: /// A normal executable case ObjectFile::eTypeDynamicLinker: /// The platform's dynamic linker /// executable case ObjectFile::eTypeObjectFile: /// An intermediate object file @@ -2084,6 +2087,16 @@ } else { m_images.Append(module_sp, notify); } + + // Ensure that architecture of the Target matches that of the + // executable file. Otherwise Target might use a "default" platform + // that can't actually debug the executable. For example, if the Target + // is created and by default assumes that it should use "gdb-remote" + // process, however executable has an architecture that requires a + // different Process class - without explicitly set executable module + // Target would attempt to use "gdb-remote" created initially. + if (isExecutable) + SetExecutableModule(module_sp, eLoadDependentsNo); } else module_sp.reset(); }