public inbox for elfutils@sourceware.org
 help / color / mirror / Atom feed
From: "liuxu (AJ)" <liuxu156@huawei.com>
To: "elfutils-devel@sourceware.org" <elfutils-devel@sourceware.org>
Cc: "Wangqiangdong(Frank,IAS)" <wangqiangdong@huawei.com>,
	"zhangjianwei (D)" <zhangjianwei8@huawei.com>,
	dingzhuang <dingzhuang1@huawei.com>
Subject: A scenario where Perf cannot unwind the user stack by dwarf with libdw.so
Date: Mon, 13 Feb 2023 01:44:39 +0000	[thread overview]
Message-ID: <88c25e0709834e1a816630c944377640@huawei.com> (raw)

[-- Attachment #1: Type: text/plain, Size: 6333 bytes --]

Hi all,

I am failing to unwind the user stack with libdw on Ubuntu 18.04 arm64  environment, the toolchain used is clang 12.0.1.  form the unwinding process, I found that the pc value passing to handle_cfi is 0x760, which is 0x10000 offset from the corresponding cfi address 0x10760.

Futher analysis show that the bias calculated in __libdwfl_elf_address_range for ET_DYN type pick the first PT_LOAD segment,  not the segment corresponds to code segment. So the bias result is wrong in current situation.

My temporary repair plan is shown in the bottom of the email.I'm not sure if this is the correct way to solve this problem, any advice?

Many thanks again!
--
Liu Xu

PS:
Diff.patch:
diff --git a/libdwfl/dwfl_report_elf.c b/libdwfl/dwfl_report_elf.c
index 3fc9384..e75fef1 100644
--- a/libdwfl/dwfl_report_elf.c
+++ b/libdwfl/dwfl_report_elf.c
@@ -185,9 +185,9 @@ __libdwfl_elf_address_range (Elf *elf, GElf_Addr base, bool add_p_vaddr,
      GElf_Phdr phdr_mem, *ph = gelf_getphdr (elf, i, &phdr_mem);
      if (unlikely (ph == NULL))
        goto elf_error;
-     if (ph->p_type == PT_LOAD)
+     if (ph->p_type == PT_LOAD && (ph->p_flags & PF_X))
        {
-         vaddr = ph->p_vaddr & -ph->p_align;
+         vaddr = (ph->p_vaddr - ph->p_offset) & -ph->p_align;
          address_sync = ph->p_vaddr + ph->p_memsz;
          break;
        }


Source code:
#define _GNU_SOURCE
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/time.h>
#define PER_RUNNING_TIME 500

void test_005()
{
    int i = 0;
    i++;
    while (1) {};
}

void test_004()
{
    for (int i = 10;i > 0; i--) {
        test_005();
    }
}

void test_003()
{
        test_004();
}

void test_002()
{
        test_003();
}

void test_001()
{
    test_002();
}

int main()
{
    test_001();
    return 0;
}

Compile command: clang main_dwarf.c -fomit-frame-pointer -o test_dwarf_nofp.

Sampling command: perf record --call-graph dwarf

Report command: perf report -v

The Program Headers of elf file :
Program Headers:
  Type           Offset             VirtAddr           PhysAddr
                 FileSiz            MemSiz              Flags  Align
  PHDR           0x0000000000000040 0x0000000000000040 0x0000000000000040
                 0x0000000000000230 0x0000000000000230  R      0x8
  INTERP         0x0000000000000270 0x0000000000000270 0x0000000000000270
                 0x000000000000001a 0x000000000000001a  R      0x1
      [Requesting program interpreter: /lib/ld-musl-aarch64.so.1]
  LOAD           0x0000000000000000 0x0000000000000000 0x0000000000000000
                 0x000000000000065c 0x000000000000065c  R      0x10000
  LOAD           0x000000000000065c 0x000000000001065c 0x000000000001065c
                 0x0000000000000234 0x0000000000000234  R E    0x10000
  LOAD           0x0000000000000890 0x0000000000020890 0x0000000000020890
                 0x00000000000001b0 0x00000000000001b0  RW     0x10000
  LOAD           0x0000000000000a40 0x0000000000030a40 0x0000000000030a40
                 0x0000000000000040 0x0000000000000089  RW     0x10000
  DYNAMIC        0x00000000000008a0 0x00000000000208a0 0x00000000000208a0
                 0x0000000000000170 0x0000000000000170  RW     0x8
  GNU_RELRO      0x0000000000000890 0x0000000000020890 0x0000000000020890
                 0x00000000000001b0 0x0000000000000770  R      0x1
  GNU_EH_FRAME   0x00000000000004f8 0x00000000000004f8 0x00000000000004f8
                 0x000000000000004c 0x000000000000004c  R      0x4
  GNU_STACK      0x0000000000000000 0x0000000000000000 0x0000000000000000
                 0x0000000000000000 0x0000000000000000  RW     0x0
Section to Segment mapping:
  Segment Sections...
   00
   01     .interp
   02     .interp .dynsym .gnu.hash .dynstr .rela.dyn .rela.plt .eh_frame_hdr .eh_frame
   03     .text .init .fini .plt
   04     .init_array .fini_array .dynamic .got
   05     .data .got.plt .bss
   06     .dynamic
   07     .init_array .fini_array .dynamic .got
   08     .eh_frame_hdr
   09

.eh_frame of elf file:
00000000 0000000000000014 00000000 CIE "zR" cf=1 df=-4 ra=30
   LOC           CFA
0000000000000000 sp+0

00000018 000000000000001c 0000001c FDE cie=00000000 pc=0000000000010678..00000000000106c4
   LOC           CFA      x29   ra
0000000000010678 sp+0     u     u
0000000000010680 x29+16   c-16  c-8

00000038 000000000000001c 0000003c FDE cie=00000000 pc=00000000000106c4..0000000000010724
   LOC           CFA      x29   ra
00000000000106c4 sp+0     u     u
00000000000106cc x29+16   c-16  c-8

00000058 0000000000000014 0000005c FDE cie=00000000 pc=0000000000010724..000000000001073c
   LOC           CFA
0000000000010724 sp+0
0000000000010728 sp+16

00000070 0000000000000014 00000074 FDE cie=00000000 pc=000000000001073c..0000000000010778
   LOC           CFA      ra
000000000001073c sp+0     u
0000000000010744 sp+32    c-16

00000088 0000000000000014 0000008c FDE cie=00000000 pc=0000000000010778..0000000000010788
   LOC           CFA      ra
0000000000010778 sp+0     u
000000000001077c sp+16    c-16

000000a0 0000000000000014 000000a4 FDE cie=00000000 pc=0000000000010788..0000000000010798
   LOC           CFA      ra
0000000000010788 sp+0     u
000000000001078c sp+16    c-16

000000b8 0000000000000014 000000bc FDE cie=00000000 pc=0000000000010798..00000000000107a8
   LOC           CFA      ra
0000000000010798 sp+0     u
000000000001079c sp+16    c-16

000000d0 0000000000000014 000000d4 FDE cie=00000000 pc=00000000000107a8..00000000000107d0
   LOC           CFA      ra
00000000000107a8 sp+0     u
00000000000107b0 sp+32    c-16

000000e8 ZERO terminator


Contents of the .debug_frame section:


00000000 0000000000000014 ffffffff CIE "" cf=1 df=-4 ra=30
   LOC           CFA
0000000000000000 sp+0

00000018 0000000000000014 00000000 FDE cie=00000000 pc=0000000000010650..0000000000010678

The actual parameters of handle_cfi when I report:
Breakpoint 1, handle_cfi (state=state@entry=0xaaaaaadc45b0, pc=1888, cfi=0xaaaaaadc4900, bias=757661696) at frame_unwind.c:540
warning: Source file is more recent than executable.
540     {
(gdb) p/x pc
$1 = 0x760
(gdb) p/x bias
$2 = 0x2d290000


             reply	other threads:[~2023-02-13  1:44 UTC|newest]

Thread overview: 3+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2023-02-13  1:44 liuxu (AJ) [this message]
2023-02-16 22:48 ` Mark Wielaard
2023-02-23 10:25   ` Mark Wielaard

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=88c25e0709834e1a816630c944377640@huawei.com \
    --to=liuxu156@huawei.com \
    --cc=dingzhuang1@huawei.com \
    --cc=elfutils-devel@sourceware.org \
    --cc=wangqiangdong@huawei.com \
    --cc=zhangjianwei8@huawei.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).