[lldb-dev] VMRange merging in ProcessElfCore and DoReadMemory

Piotr Rak piotr.rak at gmail.com
Sat Feb 22 05:06:27 PST 2014


2014-02-22 12:46 GMT+01:00 Piotr Rak <piotr.rak at gmail.com>:

> Hi Ed
>
> Sorry for late reply and thanks for looking into it.
>
> Your example fails same way as mine for all combinations static/dynamic
> gcc/clang.
> Wonder if FreeBSD adds .text section to core files.
>
> What would be result of disassembly for you?
>
> For me it always looks like that:
>
> dis -b -f
> libc.so.6`__GI_raise:
>    0x7f72a9b11330:  00 00  addb   %al, (%rax)
>    0x7f72a9b11332:  00 00  addb   %al, (%rax)
>    0x7f72a9b11334:  00 00  addb   %al, (%rax)
>    0x7f72a9b11336:  00 00  addb   %al, (%rax)
>    0x7f72a9b11338:  00 00  addb   %al, (%rax)
>    0x7f72a9b1133a:  00 00  addb   %al, (%rax)
>    0x7f72a9b1133c:  00 00  addb   %al, (%rax)
>    0x7f72a9b1133e:  00 00  addb   %al, (%rax)
>    0x7f72a9b11340:  00 00  addb   %al, (%rax)
>    0x7f72a9b11342:  00 00  addb   %al, (%rax)
>    0x7f72a9b11344:  00 00  addb   %al, (%rax)
>    0x7f72a9b11346:  00 00  addb   %al, (%rax)
>    0x7f72a9b11348:  00 00  addb   %al, (%rax)
> ...
>
> Could you please compare output of readelf/eu-readelf with mine?
>
> For me it is:
> eu-readelf -l core_lnx.1125
>
> Program Headers:
>   Type           Offset   VirtAddr           PhysAddr           FileSiz
>  MemSiz   Flg Align
>   NOTE           0x000388 0x0000000000000000 0x0000000000000000 0x001940
> 0x000000     0x0
>   LOAD           0x002000 0x0000000000400000 0x0000000000000000 0x000000
> 0x0c2000 R E 0x1000
>   LOAD           0x002000 0x00000000004c2000 0x0000000000000000 0x003000
> 0x003000 RW  0x1000
>   LOAD           0x005000 0x00000000004c5000 0x0000000000000000 0x006000
> 0x006000 RW  0x1000
>   LOAD           0x00b000 0x0000000001906000 0x0000000000000000 0x002000
> 0x002000 RW  0x1000
>   LOAD           0x00d000 0x0000000001908000 0x0000000000000000 0x000000
> 0x021000 RW  0x1000
>   LOAD           0x00d000 0x00007f6e4be02000 0x0000000000000000 0x001000
> 0x001000     0x1000
>   LOAD           0x00e000 0x00007f6e4be03000 0x0000000000000000 0x800000
> 0x800000 RW  0x1000
>   LOAD           0x80e000 0x00007f6e4c603000 0x0000000000000000 0x001000
> 0x001000     0x1000
>   LOAD           0x80f000 0x00007f6e4c604000 0x0000000000000000 0x800000
> 0x800000 RW  0x1000
>   LOAD           0x100f000 0x00007f6e4ce04000 0x0000000000000000 0x001000
> 0x001000     0x1000
>   LOAD           0x1010000 0x00007f6e4ce05000 0x0000000000000000 0x800000
> 0x800000 RW  0x1000
>   LOAD           0x1810000 0x00007fffcef2b000 0x0000000000000000 0x022000
> 0x022000 RW  0x1000
>   LOAD           0x1832000 0x00007fffceffe000 0x0000000000000000 0x002000
> 0x002000 R E 0x1000
>   LOAD           0x1834000 0xffffffffff600000 0x0000000000000000 0x001000
> 0x001000 R E 0x1000
>
> I am mostly interested if your core contain for .text sections is non-zero
> length for phdrs in loaded segments:
>
> For me program .text is not clearly there:
> LOAD           0x002000 0x0000000000400000 0x0000000000000000 0x000000
> 0x0c2000 R E 0x1000
>
>                                     ~~~~~~
> That would explain the difference for what I and you see.
>
> IIRC Target::ReadMemory seems to be using m_images at first, but after
> DynamicLoader kicks in it uses:
>
> bytes_read = m_process_sp->ReadMemory(load_addr, dst, dst_len, error);
>
>
> which obviously returns only zeros for me since core did not contain any data for .text sections.
>
>
> I wonder if:
>
>
>
> section_load_list.ResolveLoadAddress (load_addr, resolved_addr);
>
>
> is doing right thing for me, but I clearly do not understand yet how it
> works and how should it work.
>
>
>
I am probably onto something because adding such hack fixes things for me:

diff --git a/source/Target/Target.cpp b/source/Target/Target.cpp
index e781626..21cb29a 100644
--- a/source/Target/Target.cpp
+++ b/source/Target/Target.cpp
@@ -1311,7 +1311,7 @@ Target::ReadMemory (const Address& addr,
     if (!addr.IsSectionOffset())
     {
         SectionLoadList &section_load_list = GetSectionLoadList();
-        if (section_load_list.IsEmpty())
+        if (true || section_load_list.IsEmpty())
         {
             // No sections are loaded, so we must assume we are not running
             // yet and anything we are given is a file address.
@@ -1332,7 +1332,7 @@ Target::ReadMemory (const Address& addr,
         resolved_addr = addr;


-    if (prefer_file_cache)
+    if (true || prefer_file_cache)
     {
         bytes_read = ReadMemoryFromFileCache (resolved_addr, dst, dst_len,
error);
         if (bytes_read > 0)


This basically forces Target to totally ignore SectionLoadList and with
this change applied it starts to work as expected:

Core file
'/home/prak/tmp/userland-cores/Linux/3.12.8-1-ARCH/x86_64/clang/3.4/core_lnx.1112'
(x86_64) was loaded.
Process 0 stopped
* thread #1: tid = 0, 0x00007f72a9b11369 libc.so.6`__GI_raise + 57, name =
'gen-core-v1', stop reason = signal SIGABRT
    frame #0: 0x00007f72a9b11369 libc.so.6`__GI_raise + 57
libc.so.6`__GI_raise + 57:
-> 0x7f72a9b11369:  cmpq   $-0x1000, %rax
   0x7f72a9b1136f:  ja     0x3538a                   ; __GI_raise + 90
   0x7f72a9b11371:  rep
   0x7f72a9b11372:  retq
  thread #2: tid = 1, 0x00007f72a9b92aad libc.so.6, stop reason = signal
SIGABRT
    frame #0: 0x00007f72a9b92aad libc.so.6
libc.so.6`??? + 45:
-> 0x7f72a9b92aad:  movq   (%rsp), %rdi

libc.so.6`??? + 49:
   0x7f72a9b92ab1:  movq   %rax, %rdx

libc.so.6`??? + 52:
   0x7f72a9b92ab4:  callq  0xf1930                   ;
__libc_disable_asynccancel

libc.so.6`??? + 57:
   0x7f72a9b92ab9:  movq   %rdx, %rax
  thread #3: tid = 2, 0x00007f72a9b92aad libc.so.6, stop reason = signal
SIGABRT
    frame #0: 0x00007f72a9b92aad libc.so.6
libc.so.6`??? + 45:
-> 0x7f72a9b92aad:  movq   (%rsp), %rdi

libc.so.6`??? + 49:
   0x7f72a9b92ab1:  movq   %rax, %rdx

libc.so.6`??? + 52:
   0x7f72a9b92ab4:  callq  0xf1930                   ;
__libc_disable_asynccancel

libc.so.6`??? + 57:
   0x7f72a9b92ab9:  movq   %rdx, %rax
  thread #4: tid = 3, 0x00007f72a9b92aad libc.so.6, stop reason = signal
SIGABRT
    frame #0: 0x00007f72a9b92aad libc.so.6
libc.so.6`??? + 45:
-> 0x7f72a9b92aad:  movq   (%rsp), %rdi

libc.so.6`??? + 49:
   0x7f72a9b92ab1:  movq   %rax, %rdx

libc.so.6`??? + 52:
   0x7f72a9b92ab4:  callq  0xf1930                   ;
__libc_disable_asynccancel

libc.so.6`??? + 57:
   0x7f72a9b92ab9:  movq   %rdx, %rax

Also, I expect it might have been failing pretty long time without being
noticed, since for live debugging it wouldn't matter if we load those
values using SectionLoadList or Process::DoReadMemory, because this
information is same and correct in both places.

Hints more than welcome :)

Will dig bit more...

Cheers,
/Piotr
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.llvm.org/pipermail/lldb-dev/attachments/20140222/91cc3b3b/attachment.html>


More information about the lldb-dev mailing list