[Lldb-commits] [lldb] r186516 - Re-introduces ELF core file support for Linux x86-64

Ed Maste emaste at freebsd.org
Thu Jul 18 05:24:53 PDT 2013


On 17 July 2013 12:06, Ashok Thirumurthi <ashok.thirumurthi at intel.com> wrote:
> Author: athirumu
> Date: Wed Jul 17 11:06:12 2013
> New Revision: 186516
...
> +/// 5) If a core file contains multiple thread contexts then there is two data forms
> +///    a) Each thread context(2 or more NOTE entries) contained in its own segment (PT_NOTE)
> +///    b) All thread context is stored in a single segment(PT_NOTE).
> +///        This case is little tricker since while parsing we have to find where the
> +///        new thread starts. The current implementation marks begining of
> +///        new thread when it finds NT_PRSTATUS or NT_PRPSINFO NOTE entry.

For FreeBSD we follow case (b), with the additional caveat that
there's only one NT_PRPSINFO for all threads.

feynman% readelf -n tdcnt.core

Notes at offset 0x00000318 with length 0x00000d5c:
  Owner         Data size       Description
  FreeBSD               0x00000078      NT_PRPSINFO (prpsinfo structure)
  FreeBSD               0x000000e0      NT_PRSTATUS (prstatus structure)
  FreeBSD               0x00000200      NT_FPREGSET (floating point registers)
  FreeBSD               0x00000018      NT_THRMISC (thrmisc structure)
  FreeBSD               0x000000e0      NT_PRSTATUS (prstatus structure)
  FreeBSD               0x00000200      NT_FPREGSET (floating point registers)
  FreeBSD               0x00000018      NT_THRMISC (thrmisc structure)

The current logic for case (b) finds the type for the first instance
of NT_PRPSINFO or NT_PRSTATUS, and considers each subsequent note of
the same type to be the start of a new thread.  This of course doesn't
work for FreeBSD, because there is no second NT_PRPSINFO.

What do you think about this approach instead:

diff --git a/source/Plugins/Process/elf-core/ProcessElfCore.cpp
b/source/Plugins/Process/elf-core/ProcessElfCore.cpp
index 5ff3aaa..d24283a 100644
--- a/source/Plugins/Process/elf-core/ProcessElfCore.cpp
+++ b/source/Plugins/Process/elf-core/ProcessElfCore.cpp
@@ -436,27 +436,27 @@
ProcessElfCore::ParseThreadContextsFromNoteSegment(const
elf::ELFProgramHeader *
     assert(segment_header && segment_header->p_type == llvm::ELF::PT_NOTE);

     lldb::offset_t offset = 0;
-    ThreadData *thread_data = NULL;
+    ThreadData *thread_data = new ThreadData();
+    bool have_prstatus = false;
+    bool have_prpsinfo = false;

     // Loop through the NOTE entires in the segment
     while (offset < segment_header->p_filesz)
     {
-        static unsigned lead_n_type = -1;
         ELFNote note = ELFNote();
         note.Parse(segment_data, &offset);

-        if ((lead_n_type == (unsigned)-1) &&
-           ((note.n_type == NT_PRSTATUS) || (note.n_type == NT_PRPSINFO)))
-            lead_n_type = note.n_type;
-
         // Begining of new thread
-        if (note.n_type == lead_n_type)
+        if ((note.n_type == NT_PRSTATUS && have_prstatus) ||
+            (note.n_type == NT_PRPSINFO && have_prpsinfo))
         {
             if (thread_data)
             {
                 assert(thread_data->prstatus.GetByteSize() > 0);
                 // Add the new thread to thread list
                 m_thread_data.push_back(*thread_data);
+                have_prstatus = false;
+                have_prpsinfo = false;
             }
             thread_data = new ThreadData();
         }
@@ -470,12 +470,14 @@
ProcessElfCore::ParseThreadContextsFromNoteSegment(const
elf::ELFProgramHeader *
         switch (note.n_type)
         {
             case NT_PRSTATUS:
+                have_prstatus = true;
                 thread_data->prstatus = note_data;
                 break;
             case NT_FPREGSET:
                 thread_data->fpregset = note_data;
                 break;
             case NT_PRPSINFO:
+                have_prpsinfo = true;
                 thread_data->prpsinfo = note_data;
                 break;
             case NT_AUXV:



More information about the lldb-commits mailing list