[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