Skip site navigation (1)Skip section navigation (2)
Date:      Thu, 16 Feb 2017 12:05:54 +0000
From:      bugzilla-noreply@freebsd.org
To:        freebsd-amd64@FreeBSD.org
Subject:   [Bug 217138] head (e.g.) -r313783 sh vs. jemalloc asserts: include/jemalloc/internal/tsd.h:687: Failed assertion: "tsd_booted"
Message-ID:  <bug-217138-6@https.bugs.freebsd.org/bugzilla/>

next in thread | raw e-mail | index | archive | help
https://bugs.freebsd.org/bugzilla/show_bug.cgi?id=3D217138

            Bug ID: 217138
           Summary: head (e.g.) -r313783 sh vs. jemalloc asserts:
                    include/jemalloc/internal/tsd.h:687: Failed assertion:
                    "tsd_booted"
           Product: Base System
           Version: CURRENT
          Hardware: amd64
                OS: Any
            Status: New
          Severity: Affects Only Me
          Priority: ---
         Component: bin
          Assignee: freebsd-bugs@FreeBSD.org
          Reporter: markmi@dsl-only.net
                CC: freebsd-amd64@FreeBSD.org
                CC: freebsd-amd64@FreeBSD.org

For head -r313783 I built with a production arm64 kernel
but world without MALLOC_PRODUCTION . I intermittently
get the following sort of thing when, for example, I use
^z to put a process in the background and to get back
to the shell --or quitting a program and getting back to
the shell. The context involves already having been
su'd to root. I can not cause the crash on demand: it
is intermittent and fairly rare so far.

[Note: This was found while trying to track down why sh
fails sometimes during buildworld on a pine64 when
world was built with MALLOC_PRODUCTION.]

<jemalloc>: /usr/src/contrib/jemalloc/include/jemalloc/internal/tsd.h:687:
Failed assertion: "tsd_booted"

(lldb) bt
* thread #1: tid =3D 100164, 0x0000000040554e18 libc.so.7`_thr_kill + 8, na=
me =3D
'sh', stop reason =3D signal SIGABRT
  * frame #0: 0x0000000040554e18 libc.so.7`_thr_kill + 8
    frame #1: 0x0000000040554ddc libc.so.7`__raise(s=3D6) + 64 at raise.c:52
    frame #2: 0x0000000040554d50 libc.so.7`abort + 84 at abort.c:65
    frame #3: 0x0000000040528790 libc.so.7`__je_tsd_fetch [inlined]
__je_tsd_get + 248 at tsd.h:687
    frame #4: 0x000000004052876c libc.so.7`__je_tsd_fetch [inlined]
__je_tsd_fetch_impl(init=3Dtrue) at tsd.h:692
    frame #5: 0x000000004052876c libc.so.7`__je_tsd_fetch + 212 at tsd.h:717
    frame #6: 0x0000000040550214 libc.so.7`ialloc_body(size=3D11,
zero=3D<unavailable>, tsdn=3D0x0000ffffffffe650, usize=3D0x0000ffffffffe648,
slow_path=3Dtrue) + 56 at jemalloc_jemalloc.c:1586
    frame #7: 0x0000000040550184 libc.so.7`__malloc(size=3D1) + 184 at
jemalloc_jemalloc.c:1645
    frame #8: 0x000000000041126c sh`ckmalloc(nbytes=3D<unavailable>) + 32 at
memalloc.c:61
    frame #9: 0x000000000041bb6c sh`setvar(name=3D<unavailable>,
val=3D<unavailable>, flags=3D<unavailable>) + 176 at var.c:256
    frame #10: 0x0000000000406bf4 sh`evalcommand(cmd=3D<unavailable>,
flags=3D<unavailable>, backcmd=3D<unavailable>) + 3468 at eval.c:1180
    frame #11: 0x0000000000405570 sh`evaltree(n=3D0x0000000040ab9060,
flags=3D<unavailable>) + 212 at eval.c:290
    frame #12: 0x000000000041105c sh`cmdloop(top=3D<unavailable>) + 252 at
main.c:231
    frame #13: 0x0000000000410ed0 sh`main(argc=3D<unavailable>,
argv=3D<unavailable>) + 660 at main.c:178
    frame #14: 0x0000000000402f30 sh`__start + 360
    frame #15: 0x0000000040434658 ld-elf.so.1`.rtld_start + 24 at
rtld_start.S:41
(lldb) up 10
frame #10: 0x0000000000406bf4 sh`evalcommand(cmd=3D<unavailable>,
flags=3D<unavailable>, backcmd=3D<unavailable>) + 3468 at eval.c:1180
   1177=20
   1178 out:
   1179         if (lastarg)
-> 1180                 setvar("_", lastarg, 0);
   1181         if (do_clearcmdentry)
   1182                 clearcmdentry();
   1183 }

Unless tsd_booted has been trashed it would appear that
tsd_boot0() never happened before the attempted setvar
above indirectly tries the __je_tsd_get. Supporting
details from the source code:

/usr/src/contrib/jemalloc/include/jemalloc/internal/jemalloc_internal_defs.h
establishes:

#define JEMALLOC_MALLOC_THREAD_CLEANUP=20
#define JEMALLOC_TLS=20

which is context that is needed when looking things up.

/* malloc_tsd_externs(). */
#ifdef JEMALLOC_MALLOC_THREAD_CLEANUP
#define malloc_tsd_externs(a_name, a_type)                              \
extern __thread a_type  a_name##tsd_tls;                                \
extern __thread bool    a_name##tsd_initialized;                        \
extern bool             a_name##tsd_booted;
. . .
#ifdef JEMALLOC_MALLOC_THREAD_CLEANUP
#define malloc_tsd_data(a_attr, a_name, a_type, a_initializer)          \
. . .                                    \
a_attr bool             a_name##tsd_booted =3D false;
. . .

#ifdef JEMALLOC_MALLOC_THREAD_CLEANUP
#define malloc_tsd_funcs(a_attr, a_name, a_type, a_initializer,         \
    a_cleanup)                                                          \
. . .
a_name##tsd_boot0(void)                                                 \
{                                                                       \
                                                                        \
        if (a_cleanup !=3D malloc_tsd_no_cleanup) {                       \
                malloc_tsd_cleanup_register(                            \
                    &a_name##tsd_cleanup_wrapper);                      \
        }                                                               \
        a_name##tsd_booted =3D true;                                      \
        return (false);                                                 \
}                                                                       \
. . .
a_attr bool                                                             \
a_name##tsd_boot(void)                                                  \
{                                                                       \
                                                                        \
        return (a_name##tsd_boot0());                                   \
}                                                                       \
. . .
/* Get/set. */                                                          \
a_attr a_type *                                                         \
a_name##tsd_get(bool init)                                              \
{                                                                       \
                                                                        \
        assert(a_name##tsd_booted);                                     \
        return (&a_name##tsd_tls);                                      \
}                                                                       \
a_attr void                                                             \
a_name##tsd_set(a_type *val)                                            \
{                                                                       \
                                                                        \
        assert(a_name##tsd_booted);                                     \
        a_name##tsd_tls =3D (*val);                                       \
        if (a_cleanup !=3D malloc_tsd_no_cleanup)                         \
                a_name##tsd_initialized =3D true;                         \
}
. . .

#if (defined(JEMALLOC_ENABLE_INLINE) || defined(JEMALLOC_TSD_C_))
malloc_tsd_externs(, tsd_t)
malloc_tsd_funcs(JEMALLOC_ALWAYS_INLINE, , tsd_t, tsd_initializer, tsd_clea=
nup)

. . .

tsd_t *
malloc_tsd_boot0(void)
{
        tsd_t *tsd;

        ncleanups =3D 0;
        if (tsd_boot0())
                return (NULL);
        tsd =3D tsd_fetch();
        *tsd_arenas_tdata_bypassp_get(tsd) =3D true;
        return (tsd);
}
. . .
static bool
malloc_init_hard(void)
{
. . .
        tsd =3D malloc_tsd_boot0();
. . .

JEMALLOC_ALWAYS_INLINE_C bool
malloc_init(void)
{

        if (unlikely(!malloc_initialized()) && malloc_init_hard())
                return (true);
        malloc_thread_init();

        return (false);
}=20=20=20=20=20=20=20
. . .
typedef enum {
        malloc_init_uninitialized       =3D 3,
        malloc_init_a0_initialized      =3D 2,
        malloc_init_recursible          =3D 1,
        malloc_init_initialized         =3D 0 /* Common case --> jnz. */
} malloc_init_t;
static malloc_init_t    malloc_init_state =3D malloc_init_uninitialized;
. . .
JEMALLOC_ALWAYS_INLINE_C bool
malloc_initialized(void)
{

        return (malloc_init_state =3D=3D malloc_init_initialized);
}

--=20
You are receiving this mail because:
You are on the CC list for the bug.=



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?bug-217138-6>