[Top][All Lists]

[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; ; )


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

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 
#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 
#7  0x00007ffff7667fd6 in _ULx86_64_dwarf_step (c=0x7fffffffd4b0) at 
#8  0x00007ffff76610b0 in _ULx86_64_step (cursor=0x7fffffffd4b0) at 
#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 
#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 
    #13 0x00007ffff7bb4768 in g_signal_emit_valist (instance=<optimized out>, 
signal_id=<optimized out>, detail=<optimized out>, address@hidden) at 
#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,

gcc -Wall -Wextra udevc.c -o udevc -g \
    $(pkg-config --cflags --libs gudev-1.0 libunwind)
#include <gudev/gudev.h>
#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)
        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 */
    save_trace ();  /* another way to kill it */

main (void)
#if !defined(GLIB_VERSION_2_36)
    g_type_init ();
    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;

reply via email to

[Prev in Thread] Current Thread [Next in Thread]