[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[Libunwind-devel] Segfault in dwarf_readu32 (x86-64)
From: |
Peter Wu |
Subject: |
[Libunwind-devel] Segfault in dwarf_readu32 (x86-64) |
Date: |
Sun, 23 Nov 2014 13:24:34 +0100 |
User-agent: |
KMail/4.14.3 (Linux/3.17.0-rc4-custom-00168-g7ec62d4; KDE/4.14.3; x86_64; ; ) |
Hi,
I am using libunwind in gobject-list[1] to get a backtrace at certain
points. It generally works fine, but there is one condition that
triggers a segfault and I have no idea how to tackle that.
It could be related to the use of signals, but I could not reproduce it
from a signal handler. Attached is a minimal example that exposes the
issue, namely a uevent trigger from libgudev which results in invocation
of unw_step, which triggers a segfault as shown below.
$ gdb -q -ex 'set pagination off' -ex r ./udevc
Please trigger an uevent, by inserting a USB device for example.
uevent: remove
uevent_signal
g_closure_invoke
g_signal_handler_disconnect
g_signal_emit_valist
g_signal_emit
monitor_event
Program received signal SIGSEGV, Segmentation fault.
0x00007ffff76645fd in dwarf_readu32 (as=0x7ffff7870540 <local_addr_space>,
a=0x7ffff7870540 <local_addr_space>, addr=0x7fffffffcaa8, val=0x7fffffffcadc,
arg=0x7fffffffd4b0) at ../../include/dwarf_i.h:117
117 *val = mvp->u32;
(gdb) bt
#0 0x00007ffff76645fd in dwarf_readu32 (as=0x7ffff7870540 <local_addr_space>,
a=0x7ffff7870540 <local_addr_space>, addr=0x7fffffffcaa8, val=0x7fffffffcadc,
arg=0x7fffffffd4b0) at ../../include/dwarf_i.h:117
#1 0x00007ffff7664860 in parse_cie (as=0x7ffff7870540 <local_addr_space>,
a=0x7ffff7870540 <local_addr_space>, addr=140737218672057, pi=0x7fffffffd610,
dci=0x7fffffffcb90, base=0, arg=0x7fffffffd4b0) at ../../src/dwarf/Gfde.c:74
#2 0x00007ffff7664ffe in _ULx86_64_dwarf_extract_proc_info_from_fde
(as=0x7ffff7870540 <local_addr_space>, a=0x7ffff7870540 <local_addr_space>,
addrp=0x7fffffffcc88, pi=0x7fffffffd610, need_unwind_info=1, base=0,
arg=0x7fffffffd4b0) at ../../src/dwarf/Gfde.c:301
#3 0x00007ffff766892a in _ULx86_64_dwarf_search_unwind_table
(as=0x7ffff7870540 <local_addr_space>, ip=140737353810467, di=0x7fffffffcda8,
pi=0x7fffffffd610, need_unwind_info=1, arg=0x7fffffffd4b0) at
../../src/dwarf/Gfind_proc_info-lsb.c:904
#4 0x00007ffff76686ac in _ULx86_64_dwarf_find_proc_info (as=0x7ffff7870540
<local_addr_space>, ip=140737353810467, pi=0x7fffffffd610, need_unwind_info=1,
arg=0x7fffffffd4b0) at ../../src/dwarf/Gfind_proc_info-lsb.c:742
#5 0x00007ffff76663e1 in fetch_proc_info (c=0x7fffffffd4b0,
ip=140737353810467, need_unwind_info=1) at ../../src/dwarf/Gparser.c:437
#6 0x00007ffff7667657 in _ULx86_64_dwarf_find_save_locs (c=0x7fffffffd4b0) at
../../src/dwarf/Gparser.c:885
#7 0x00007ffff7667fd6 in _ULx86_64_dwarf_step (c=0x7fffffffd4b0) at
../../src/dwarf/Gstep.c:34
#8 0x00007ffff76610b0 in _ULx86_64_step (cursor=0x7fffffffd4b0) at
../../src/x86_64/Gstep.c:71
#9 0x0000000000400a77 in save_trace () at udevc.c:18
#10 0x0000000000400b0a in uevent_signal (client=0x60f820 [GUdevClient],
action=0x6379a0 "remove", device=0x607220 [GUdevDevice], user_data=0x0) at
udevc.c:50
#14 0x00007ffff7bb49cf in <emit signal ??? on instance 0x60f820 [GUdevClient]>
(address@hidden, signal_id=<optimized out>, address@hidden) at gsignal.c:3365
#11 0x00007ffff7b9a255 in g_closure_invoke (closure=0x610960,
return_value=0x0, n_param_values=3, param_values=0x7fffffffde60,
invocation_hint=0x7fffffffde00) at gclosure.c:768
#12 0x00007ffff7babf5c in signal_emit_unlocked_R (address@hidden,
address@hidden, address@hidden, address@hidden, address@hidden) at
gsignal.c:3553
#13 0x00007ffff7bb4768 in g_signal_emit_valist (instance=<optimized out>,
signal_id=<optimized out>, detail=<optimized out>, address@hidden) at
gsignal.c:3309
#15 0x00007ffff7fb0224 in monitor_event (source=<optimized out>,
condition=<optimized out>, data=0x60f820) at src/gudev/gudevclient.c:103
#16 0x0000000000000000 in ()
(gdb) p *mvp
Cannot access memory at address 0x7fffefecf5b9
System details:
Arch Linux x86_64
libunwind 1.1-2 (Arch Linux package) v1.1-49-g3babc1d (git)
GCC 4.9.2
Linux v3.17-rc4-168-g7ec62d4
glib2 2.42.0
udev is part of systemd 217
Any idea what is wrong here and how it can be fixed?
--
Kind regards,
Peter
https://lekensteyn.nl
[1]: https://github.com/danni/gobject-list
/*
gcc -Wall -Wextra udevc.c -o udevc -g \
$(pkg-config --cflags --libs gudev-1.0 libunwind)
*/
#include <gudev/gudev.h>
#define UNW_LOCAL_ONLY
#include <libunwind.h>
static void
save_trace (void)
{
unw_context_t uc;
unw_cursor_t cursor;
unw_getcontext (&uc);
unw_init_local (&cursor, &uc);
while (unw_step (&cursor) > 0) {
gchar name[129];
unw_word_t off;
int result;
result = unw_get_proc_name (&cursor, name, sizeof (name), &off);
if (result < 0 && result != -UNW_ENOMEM)
break;
g_print ("%s\n", name);
}
}
static void
try_bt (void)
{
void *buffer[100];
int n, i;
n = unw_backtrace (buffer, G_N_ELEMENTS (buffer));
for (i = 0; i < n; i++)
g_print ("#%d %p\n", i, buffer[i]);
}
static void
uevent_signal (G_GNUC_UNUSED GUdevClient *client,
gchar *action,
G_GNUC_UNUSED GUdevDevice *device,
G_GNUC_UNUSED gpointer user_data)
{
g_print ("uevent: %s\n", action);
#if 0
try_bt (); /* one way to kill it */
#else
save_trace (); /* another way to kill it */
#endif
}
int
main (void)
{
#if !defined(GLIB_VERSION_2_36)
g_type_init ();
#endif
const gchar *subsystems[] = {NULL};
GUdevClient *gudev_client = g_udev_client_new (subsystems);
g_signal_connect (gudev_client, "uevent", G_CALLBACK (uevent_signal), NULL);
GMainLoop *loop = g_main_loop_new (NULL, FALSE);
g_print ("Please trigger an uevent, "
"by inserting a USB device for example.\n");
g_main_loop_run (loop);
g_object_unref (gudev_client);
return 0;
}
- [Libunwind-devel] Segfault in dwarf_readu32 (x86-64),
Peter Wu <=