Doug,

please try this patch also.

пт, 7 сент. 2018 г. в 11:18, Doug Moore <do...@rice.edu>:

> Sergey,
>
> Your patch does remove memory allocation from the file, but oddly, I
> still have problems with malloc being invoked.  The second time I
> tested with your patch, I got hung here:
>
> #0  0x0000ffffb5a85d74 in __lll_lock_wait_private () from /lib64/libc.so.6
> #1  0x0000ffffb5a0ea38 in malloc () from /lib64/libc.so.6
> #2  0x0000ffffb59c15bc in qsort_r () from /lib64/libc.so.6
> #3  0x0000ffffb592c8b0 in _ULaarch64_dwarf_find_debug_frame (found=0,
> di_debug=di_debug@entry=0xffffeb09a080, ip=ip@entry=281473734119984,
>      segbase=segbase@entry=281473734053888, obj_name=0xffffb67dc440
> "/home/dougm/.local/lib/hpctoolkit/ext-libs/libdwarf.so.1",
> start=<optimized out>,
>      end=<optimized out>) at dwarf/Gfind_proc_info-lsb.c:380
> #4  0x0000ffffb592cab0 in _ULaarch64_dwarf_callback
> (info=0xffffeb099ef8, size=<optimized out>, ptr=0xffffeb09a018) at
> dwarf/Gfind_proc_info-lsb.c:667
> #5  0x0000ffffb5abac88 in dl_iterate_phdr () from /lib64/libc.so.6
> #6  0x0000ffffb592cff4 in _ULaarch64_dwarf_find_proc_info
> (as=0xffffb5948230 <local_addr_space>, ip=ip@entry=281473734119984,
> pi=pi@entry=0xffffeb09a530,
>      need_unwind_info=1, arg=0xffffeb09a9a0) at
> dwarf/Gfind_proc_info-lsb.c:693
> #7  0x0000ffffb592a158 in fetch_proc_info (c=c@entry=0xffffeb09a1d0,
> ip=281473734119984) at dwarf/Gparser.c:454
> #8  0x0000ffffb592ba08 in _ULaarch64_dwarf_reg_states_iterate
> (c=0xffffeb09a1d0, cb=0xffffb6750844 <dwarf_reg_states_callback>,
> token=0xffffeb09a1b8)
>      at dwarf/Gparser.c:1034
>
> So, perhaps qsort isn't safe either, as odd as that seems.
>
> Doug
>
> Quoting Sergey Korolev <korolev.ser...@gmail.com>:
>
> > Doug,
> >
> > Can you try this patch?
> >
> http://lists.nongnu.org/archive/html/libunwind-devel/2018-06/msg00005.html
> >
> > пт, 7 сент. 2018 г. в 1:56, Doug Moore <do...@rice.edu>:
> >
> >> It seems that unw_get_proc_info calls dwarf_make_proc_info, calls
> >> fetch_proc_info, calls dwarf_find_proc_info, calls dl_iterate_phdr,
> >> calls dwarf_callback, calls dwarf_find_debug_frame, calls calloc, and
> >> callloc is not signal safe on the aarch64 device I'm testing on.
> >>
> >> So would there be a problem with replacing the calloc/realloc memory
> >> management of 'tab' in Gfind_proc_info-lsb.c with mmap and munmap and
> >> memcpy?
> >>
> >> Is the memory allocated for 'tab' freed anywhere?  It's not obvious that
> >> it is.
> >>
> >> Thanks,
> >>
> >> Doug Moore
> >>
> >> Rice University
> >>
> >>
> >> _______________________________________________
> >> Libunwind-devel mailing list
> >> Libunwind-devel@nongnu.org
> >> https://lists.nongnu.org/mailman/listinfo/libunwind-devel
> >>
>
>
>
>
From e6384fc17f6f18fa605b1aba03edb6268c838a45 Mon Sep 17 00:00:00 2001
From: Sergey Korolev <s.koro...@ndmsystems.com>
Date: Fri, 7 Sep 2018 13:34:57 +0300
Subject: [PATCH] dwarf: do not use qsort to sort the debug frame table

Some qsort implementations (e.g. glibc) may call memory
allocation functions that is not async-signal safe.
---
 src/dwarf/Gfind_proc_info-lsb.c | 45 +++++++++++++++++++++++++++--------------
 1 file changed, 30 insertions(+), 15 deletions(-)

diff --git a/src/dwarf/Gfind_proc_info-lsb.c b/src/dwarf/Gfind_proc_info-lsb.c
index 18819e6a..a186f870 100644
--- a/src/dwarf/Gfind_proc_info-lsb.c
+++ b/src/dwarf/Gfind_proc_info-lsb.c
@@ -223,19 +223,6 @@ locate_debug_info (unw_addr_space_t as, unw_word_t addr, const char *dlname,
   return fdesc;
 }
 
-static int
-debug_frame_index_compare (const void *a, const void *b)
-{
-  const struct table_entry *fa = a, *fb = b;
-
-  if (fa->start_ip_offset > fb->start_ip_offset)
-    return 1;
-  else if (fa->start_ip_offset < fb->start_ip_offset)
-    return -1;
-  else
-    return 0;
-}
-
 static size_t
 debug_frame_index_make (struct unw_debug_frame_list *fdesc)
 {
@@ -323,6 +310,35 @@ debug_frame_index_make (struct unw_debug_frame_list *fdesc)
   return count;
 }
 
+static void
+debug_frame_index_sort (struct unw_debug_frame_list *fdesc)
+{
+  size_t i, j, k, n = fdesc->index_size / sizeof (*fdesc->index);
+  struct table_entry *a = fdesc->index;
+  struct table_entry t;
+
+  /* Use a simple Shell sort as it relatively fast and
+   * does not require additional memory. */
+
+  for (k = n / 2; k > 0; k /= 2)
+    {
+      for (i = k; i < n; i++)
+        {
+          t = a[i];
+
+          for (j = i; j >= k; j -= k)
+            {
+              if (t.start_ip_offset >= a[j - k].start_ip_offset)
+                break;
+
+              a[j] = a[j - k];
+            }
+
+          a[j] = t;
+        }
+    }
+}
+
 int
 dwarf_find_debug_frame (int found, unw_dyn_info_t *di_debug, unw_word_t ip,
                         unw_word_t segbase, const char* obj_name,
@@ -377,8 +393,7 @@ dwarf_find_debug_frame (int found, unw_dyn_info_t *di_debug, unw_word_t ip,
       /* Then fill and sort the index. */
 
       debug_frame_index_make (fdesc);
-      qsort (fdesc->index, count, sizeof (struct table_entry),
-             debug_frame_index_compare);
+      debug_frame_index_sort (fdesc);
 
     /*for (i = 0; i < count; i++)
         {
-- 
2.11.0

_______________________________________________
Libunwind-devel mailing list
Libunwind-devel@nongnu.org
https://lists.nongnu.org/mailman/listinfo/libunwind-devel

Reply via email to