labath created this revision.
labath added reviewers: clayborg, zturner.
labath added a subscriber: lldb-commits.

There was a bug in linux core file handling, where if there was a running 
process with the same
process id as the id in the core file, the core file debugging would fail, as 
we would pull some
pieces of information (ProcessInfo structure) from the running process instead 
of the core file.
I fix this by routing the ProcessInfo requests through the Process class and 
overriding it in
ProcessElfCore to return correct data.

A (slightly convoluted) test is included.

http://reviews.llvm.org/D18697

Files:
  include/lldb/Target/Process.h
  
packages/Python/lldbsuite/test/functionalities/postmortem/linux-core/TestLinuxCore.py
  source/Plugins/DynamicLoader/POSIX-DYLD/DynamicLoaderPOSIXDYLD.cpp
  source/Plugins/Process/elf-core/ProcessElfCore.cpp
  source/Plugins/Process/elf-core/ProcessElfCore.h
  source/Target/Process.cpp

Index: source/Target/Process.cpp
===================================================================
--- source/Target/Process.cpp
+++ source/Target/Process.cpp
@@ -3422,7 +3422,7 @@
         else if (!process_arch.IsValid())
         {
             ProcessInstanceInfo process_info;
-            platform_sp->GetProcessInfo (GetID(), process_info);
+            GetProcessInfo(process_info);
             const ArchSpec &process_arch = process_info.GetArchitecture();
             if (process_arch.IsValid() && !GetTarget().GetArchitecture().IsExactMatch(process_arch))
             {
@@ -6481,6 +6481,12 @@
     }
 }
 
+bool
+Process::GetProcessInfo(ProcessInstanceInfo &info)
+{
+    return GetTarget().GetPlatform()->GetProcessInfo(GetID(), info);
+}
+
 ThreadCollectionSP
 Process::GetHistoryThreads(lldb::addr_t addr)
 {
Index: source/Plugins/Process/elf-core/ProcessElfCore.h
===================================================================
--- source/Plugins/Process/elf-core/ProcessElfCore.h
+++ source/Plugins/Process/elf-core/ProcessElfCore.h
@@ -111,6 +111,9 @@
     const lldb::DataBufferSP
     GetAuxvData() override;
 
+    bool
+    GetProcessInfo(lldb_private::ProcessInstanceInfo &info) override;
+
 protected:
     void
     Clear ( );
Index: source/Plugins/Process/elf-core/ProcessElfCore.cpp
===================================================================
--- source/Plugins/Process/elf-core/ProcessElfCore.cpp
+++ source/Plugins/Process/elf-core/ProcessElfCore.cpp
@@ -637,3 +637,12 @@
     lldb::DataBufferSP buffer(new lldb_private::DataBufferHeap(start, len));
     return buffer;
 }
+
+bool
+ProcessElfCore::GetProcessInfo(ProcessInstanceInfo &info)
+{
+    info.Clear();
+    info.SetProcessID(GetID());
+    info.SetArchitecture(GetArchitecture());
+    return true;
+}
Index: source/Plugins/DynamicLoader/POSIX-DYLD/DynamicLoaderPOSIXDYLD.cpp
===================================================================
--- source/Plugins/DynamicLoader/POSIX-DYLD/DynamicLoaderPOSIXDYLD.cpp
+++ source/Plugins/DynamicLoader/POSIX-DYLD/DynamicLoaderPOSIXDYLD.cpp
@@ -656,7 +656,7 @@
     const auto platform_sp = target.GetPlatform ();
 
     ProcessInstanceInfo process_info;
-    if (!platform_sp->GetProcessInfo (m_process->GetID (), process_info))
+    if (!m_process->GetProcessInfo(process_info))
     {
         if (log)
             log->Printf ("DynamicLoaderPOSIXDYLD::%s - failed to get process info for pid %" PRIu64,
Index: packages/Python/lldbsuite/test/functionalities/postmortem/linux-core/TestLinuxCore.py
===================================================================
--- packages/Python/lldbsuite/test/functionalities/postmortem/linux-core/TestLinuxCore.py
+++ packages/Python/lldbsuite/test/functionalities/postmortem/linux-core/TestLinuxCore.py
@@ -4,29 +4,56 @@
 
 from __future__ import print_function
 
+import shutil
+import struct
+
 import lldb
 from lldbsuite.test.decorators import *
 from lldbsuite.test.lldbtest import *
 from lldbsuite.test import lldbutil
 
 class LinuxCoreTestCase(TestBase):
+    NO_DEBUG_INFO_TESTCASE = True
 
     mydir = TestBase.compute_mydir(__file__)
 
+    _i386_pid   = 32306
+    _x86_64_pid = 32259
+
     @skipIf(bugnumber="llvm.org/pr26947")
-    @no_debug_info_test
     def test_i386(self):
         """Test that lldb can read the process information from an i386 linux core file."""
-        self.do_test("i386", 32306)
+        self.do_test("i386", self._i386_pid)
 
-    @no_debug_info_test
     def test_x86_64(self):
         """Test that lldb can read the process information from an x86_64 linux core file."""
-        self.do_test("x86_64", 32259)
+        self.do_test("x86_64", self._x86_64_pid)
+
+    def test_x86_64_same_pid(self):
+        """Test that we read the information from the core correctly even if we have a running
+        process with the same PID around"""
+        try:
+            shutil.copyfile("x86_64.out",  "x86_64-pid.out")
+            shutil.copyfile("x86_64.core", "x86_64-pid.core")
+            with open("x86_64-pid.core", "r+b") as f:
+                # These are offsets into the NT_PRSTATUS and NT_PRPSINFO structures in the note
+                # segment of the core file. If you update the file, these offsets may need updating
+                # as well. (Notes can be viewed with readelf --notes.)
+                for pid_offset in [0x1c4, 0x320]:
+                    f.seek(pid_offset)
+                    self.assertEqual(struct.unpack("<I", f.read(4))[0], self._x86_64_pid)
+
+                    # We insert our own pid, and make sure the test still works.
+                    f.seek(pid_offset)
+                    f.write(struct.pack("<I", os.getpid()))
+            self.do_test("x86_64-pid", os.getpid())
+        finally:
+            self.RemoveTempFile("x86_64-pid.out")
+            self.RemoveTempFile("x86_64-pid.core")
 
-    def do_test(self, arch, pid):
-        target = self.dbg.CreateTarget(arch + ".out")
-        process = target.LoadCore(arch + ".core")
+    def do_test(self, filename, pid):
+        target = self.dbg.CreateTarget(filename + ".out")
+        process = target.LoadCore(filename + ".core")
         self.assertTrue(process, PROCESS_IS_VALID)
         self.assertEqual(process.GetNumThreads(), 1)
         self.assertEqual(process.GetProcessID(), pid)
Index: include/lldb/Target/Process.h
===================================================================
--- include/lldb/Target/Process.h
+++ include/lldb/Target/Process.h
@@ -1961,6 +1961,9 @@
     void
     PrintWarningOptimization (const SymbolContext &sc);
 
+    virtual bool
+    GetProcessInfo(ProcessInstanceInfo &info);
+
 public:
     //------------------------------------------------------------------
     /// Get the exit status for a process.
_______________________________________________
lldb-commits mailing list
lldb-commits@lists.llvm.org
http://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits

Reply via email to