[Lldb-commits] [lldb] r265391 - Fix a bug in linux core file handling

Pavel Labath via lldb-commits lldb-commits at lists.llvm.org
Tue Apr 5 06:07:17 PDT 2016


Author: labath
Date: Tue Apr  5 08:07:16 2016
New Revision: 265391

URL: http://llvm.org/viewvc/llvm-project?rev=265391&view=rev
Log:
Fix a bug in linux core file handling

Summary:
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.

Reviewers: clayborg, zturner

Subscribers: lldb-commits

Differential Revision: http://reviews.llvm.org/D18697

Added:
    lldb/trunk/packages/Python/lldbsuite/test/functionalities/postmortem/linux-core/altmain.c
    lldb/trunk/packages/Python/lldbsuite/test/functionalities/postmortem/linux-core/altmain.core
    lldb/trunk/packages/Python/lldbsuite/test/functionalities/postmortem/linux-core/altmain.out   (with props)
Modified:
    lldb/trunk/include/lldb/Target/Process.h
    lldb/trunk/packages/Python/lldbsuite/test/functionalities/postmortem/linux-core/TestLinuxCore.py
    lldb/trunk/packages/Python/lldbsuite/test/functionalities/postmortem/linux-core/make-core.sh
    lldb/trunk/source/Plugins/DynamicLoader/POSIX-DYLD/DynamicLoaderPOSIXDYLD.cpp
    lldb/trunk/source/Plugins/Process/elf-core/ProcessElfCore.cpp
    lldb/trunk/source/Plugins/Process/elf-core/ProcessElfCore.h
    lldb/trunk/source/Target/Process.cpp

Modified: lldb/trunk/include/lldb/Target/Process.h
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/include/lldb/Target/Process.h?rev=265391&r1=265390&r2=265391&view=diff
==============================================================================
--- lldb/trunk/include/lldb/Target/Process.h (original)
+++ lldb/trunk/include/lldb/Target/Process.h Tue Apr  5 08:07:16 2016
@@ -1961,6 +1961,9 @@ public:
     void
     PrintWarningOptimization (const SymbolContext &sc);
 
+    virtual bool
+    GetProcessInfo(ProcessInstanceInfo &info);
+
 public:
     //------------------------------------------------------------------
     /// Get the exit status for a process.

Modified: lldb/trunk/packages/Python/lldbsuite/test/functionalities/postmortem/linux-core/TestLinuxCore.py
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/packages/Python/lldbsuite/test/functionalities/postmortem/linux-core/TestLinuxCore.py?rev=265391&r1=265390&r2=265391&view=diff
==============================================================================
--- lldb/trunk/packages/Python/lldbsuite/test/functionalities/postmortem/linux-core/TestLinuxCore.py (original)
+++ lldb/trunk/packages/Python/lldbsuite/test/functionalities/postmortem/linux-core/TestLinuxCore.py Tue Apr  5 08:07:16 2016
@@ -4,29 +4,78 @@ Test basics of linux core file debugging
 
 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 do_test(self, arch, pid):
-        target = self.dbg.CreateTarget(arch + ".out")
-        process = target.LoadCore(arch + ".core")
+    def test_same_pid_running(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 test_two_cores_same_pid(self):
+        """Test that we handle the situation if we have two core files with the same PID
+        around"""
+        alttarget = self.dbg.CreateTarget("altmain.out")
+        altprocess = alttarget.LoadCore("altmain.core")
+        self.assertTrue(altprocess, PROCESS_IS_VALID)
+        self.assertEqual(altprocess.GetNumThreads(), 1)
+        self.assertEqual(altprocess.GetProcessID(), self._x86_64_pid)
+
+        altframe = altprocess.GetSelectedThread().GetFrameAtIndex(0)
+        self.assertEqual(altframe.GetFunctionName(), "_start")
+        self.assertEqual(altframe.GetLineEntry().GetLine(), line_number("altmain.c", "Frame _start"))
+
+        error = lldb.SBError()
+        F = altprocess.ReadCStringFromMemory(altframe.FindVariable("F").GetValueAsUnsigned(), 256, error)
+        self.assertTrue(error.Success())
+        self.assertEqual(F, "_start")
+
+        # without destroying this process, run the test which opens another core file with the
+        # same pid
+        self.do_test("x86_64", self._x86_64_pid)
+
+    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)

Added: lldb/trunk/packages/Python/lldbsuite/test/functionalities/postmortem/linux-core/altmain.c
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/packages/Python/lldbsuite/test/functionalities/postmortem/linux-core/altmain.c?rev=265391&view=auto
==============================================================================
--- lldb/trunk/packages/Python/lldbsuite/test/functionalities/postmortem/linux-core/altmain.c (added)
+++ lldb/trunk/packages/Python/lldbsuite/test/functionalities/postmortem/linux-core/altmain.c Tue Apr  5 08:07:16 2016
@@ -0,0 +1,6 @@
+void _start(void)
+{
+    const char *F = "_start";
+    char *boom = (char *)0;
+    *boom = 47; // Frame _start
+}

Added: lldb/trunk/packages/Python/lldbsuite/test/functionalities/postmortem/linux-core/altmain.core
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/packages/Python/lldbsuite/test/functionalities/postmortem/linux-core/altmain.core?rev=265391&view=auto
==============================================================================
Binary files lldb/trunk/packages/Python/lldbsuite/test/functionalities/postmortem/linux-core/altmain.core (added) and lldb/trunk/packages/Python/lldbsuite/test/functionalities/postmortem/linux-core/altmain.core Tue Apr  5 08:07:16 2016 differ

Added: lldb/trunk/packages/Python/lldbsuite/test/functionalities/postmortem/linux-core/altmain.out
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/packages/Python/lldbsuite/test/functionalities/postmortem/linux-core/altmain.out?rev=265391&view=auto
==============================================================================
Binary files lldb/trunk/packages/Python/lldbsuite/test/functionalities/postmortem/linux-core/altmain.out (added) and lldb/trunk/packages/Python/lldbsuite/test/functionalities/postmortem/linux-core/altmain.out Tue Apr  5 08:07:16 2016 differ

Propchange: lldb/trunk/packages/Python/lldbsuite/test/functionalities/postmortem/linux-core/altmain.out
------------------------------------------------------------------------------
    svn:executable = *

Modified: lldb/trunk/packages/Python/lldbsuite/test/functionalities/postmortem/linux-core/make-core.sh
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/packages/Python/lldbsuite/test/functionalities/postmortem/linux-core/make-core.sh?rev=265391&r1=265390&r2=265391&view=diff
==============================================================================
--- lldb/trunk/packages/Python/lldbsuite/test/functionalities/postmortem/linux-core/make-core.sh (original)
+++ lldb/trunk/packages/Python/lldbsuite/test/functionalities/postmortem/linux-core/make-core.sh Tue Apr  5 08:07:16 2016
@@ -2,6 +2,14 @@
 
 set -e -x
 
+file=$1
+if [ -z "$file" ]; then
+    cat <<EOF
+Please supply the main source file as the first argument.
+EOF
+    exit 1
+fi
+
 if grep -q '^|' </proc/sys/kernel/core_pattern; then
     cat <<EOF
 Your system uses a crash report tool ($(cat /proc/sys/kernel/core_pattern)). Core files
@@ -21,7 +29,7 @@ privileges.
 EOF
 fi
 
-${CC:-cc} -nostdlib -static -g $CFLAGS main.c -o a.out
+${CC:-cc} -nostdlib -static -g $CFLAGS "$file" -o a.out
 
 cat <<EOF
 Executable file is in a.out.

Modified: lldb/trunk/source/Plugins/DynamicLoader/POSIX-DYLD/DynamicLoaderPOSIXDYLD.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Plugins/DynamicLoader/POSIX-DYLD/DynamicLoaderPOSIXDYLD.cpp?rev=265391&r1=265390&r2=265391&view=diff
==============================================================================
--- lldb/trunk/source/Plugins/DynamicLoader/POSIX-DYLD/DynamicLoaderPOSIXDYLD.cpp (original)
+++ lldb/trunk/source/Plugins/DynamicLoader/POSIX-DYLD/DynamicLoaderPOSIXDYLD.cpp Tue Apr  5 08:07:16 2016
@@ -656,7 +656,7 @@ DynamicLoaderPOSIXDYLD::ResolveExecutabl
     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,

Modified: lldb/trunk/source/Plugins/Process/elf-core/ProcessElfCore.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Plugins/Process/elf-core/ProcessElfCore.cpp?rev=265391&r1=265390&r2=265391&view=diff
==============================================================================
--- lldb/trunk/source/Plugins/Process/elf-core/ProcessElfCore.cpp (original)
+++ lldb/trunk/source/Plugins/Process/elf-core/ProcessElfCore.cpp Tue Apr  5 08:07:16 2016
@@ -637,3 +637,18 @@ ProcessElfCore::GetAuxvData()
     lldb::DataBufferSP buffer(new lldb_private::DataBufferHeap(start, len));
     return buffer;
 }
+
+bool
+ProcessElfCore::GetProcessInfo(ProcessInstanceInfo &info)
+{
+    info.Clear();
+    info.SetProcessID(GetID());
+    info.SetArchitecture(GetArchitecture());
+    lldb::ModuleSP module_sp = GetTarget().GetExecutableModule();
+    if (module_sp)
+    {
+        const bool add_exe_file_as_first_arg = false;
+        info.SetExecutableFile(GetTarget().GetExecutableModule()->GetFileSpec(), add_exe_file_as_first_arg);
+    }
+    return true;
+}

Modified: lldb/trunk/source/Plugins/Process/elf-core/ProcessElfCore.h
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Plugins/Process/elf-core/ProcessElfCore.h?rev=265391&r1=265390&r2=265391&view=diff
==============================================================================
--- lldb/trunk/source/Plugins/Process/elf-core/ProcessElfCore.h (original)
+++ lldb/trunk/source/Plugins/Process/elf-core/ProcessElfCore.h Tue Apr  5 08:07:16 2016
@@ -111,6 +111,9 @@ public:
     const lldb::DataBufferSP
     GetAuxvData() override;
 
+    bool
+    GetProcessInfo(lldb_private::ProcessInstanceInfo &info) override;
+
 protected:
     void
     Clear ( );

Modified: lldb/trunk/source/Target/Process.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Target/Process.cpp?rev=265391&r1=265390&r2=265391&view=diff
==============================================================================
--- lldb/trunk/source/Target/Process.cpp (original)
+++ lldb/trunk/source/Target/Process.cpp Tue Apr  5 08:07:16 2016
@@ -3422,7 +3422,7 @@ Process::CompleteAttach ()
         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,18 @@ Process::PrintWarningOptimization (const
     }
 }
 
+bool
+Process::GetProcessInfo(ProcessInstanceInfo &info)
+{
+    info.Clear();
+
+    PlatformSP platform_sp = GetTarget().GetPlatform();
+    if (! platform_sp)
+        return false;
+
+    return platform_sp->GetProcessInfo(GetID(), info);
+}
+
 ThreadCollectionSP
 Process::GetHistoryThreads(lldb::addr_t addr)
 {




More information about the lldb-commits mailing list