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