- Having a solid library foundation actually matters.
- We have a long way to go, but there is hope!
- This is an exciting area to get involved and make things better.
The general pattern:
void mylib_init() { static int initialized = 0; if (initialized) return; initialized = 1; /* do stuff */ }
Major offenders:
av_log
handlers
g_mem_set_vtable
, which happens to be the only
way to inhibit abort
on malloc
failure in
glib.
alloca
or
variable-length arrays.
malloc
never returns NULL
.
malloc
at all.
abort()
when malloc
fails.
malloc
can failulimit
) are in
effect.
malloc
.
elf/dl-tls.c:
static void __attribute__ ((__noreturn__)) oom (void) { _dl_fatal_printf ("cannot allocate memory for thread-local data: ABORT\n"); }
if (dtv == GL(dl_initial_dtv)) { /* Comment snipped */ newp = malloc ((2 + newsize) * sizeof (dtv_t)); if (newp == NULL) oom (); memcpy (newp, &dtv[-1], (2 + oldsize) * sizeof (dtv_t)); } else { newp = realloc (&dtv[-1], (2 + newsize) * sizeof (dtv_t)); if (newp == NULL) oom (); }
abort
in pthread_cancel
nptl/sysdeps/pthread/unwind-forcedunwind.c:
handle = __libc_dlopen (LIBGCC_S_SO); if (handle == NULL || (resume = __libc_dlsym (handle, "_Unwind_Resume")) == NULL || (personality = __libc_dlsym (handle, "__gcc_personality_v0")) == NULL || (forcedunwind = __libc_dlsym (handle, "_Unwind_ForcedUnwind")) == NULL || (getcfa = __libc_dlsym (handle, "_Unwind_GetCFA")) == NULL #ifdef ARCH_CANCEL_INIT || ARCH_CANCEL_INIT (handle) #endif ) __libc_fatal (LIBGCC_S_SO " must be installed for pthread_cancel to work\n");
Open bug #12683
Example: sysdeps/unix/sysv/linux/readv.c:
ssize_t __libc_readv (fd, vector, count) int fd; const struct iovec *vector; int count; { ssize_t result; if (SINGLE_THREAD_P) result = INLINE_SYSCALL (readv, 3, fd, vector, count); else { int oldtype = LIBC_CANCEL_ASYNC (); result = INLINE_SYSCALL (readv, 3, fd, vector, count); LIBC_CANCEL_RESET (oldtype); }
wprintf
Open bug #14286
Examples:
wprintf(L"%d\n", wprintf(L"%s", hello_1gb_plus_1)); // gb = 1<<30
h1
wprintf(L"%d\n", wprintf(L"%s", hello_1gb_plus_5));
hello5
The cause?
stdio-common/vfprintf.c:
/* Allocate dynamically an array which definitely is long \ enough for the wide character version. Each byte in the \ multi-byte string can produce at most one wide character. */ \ if (__libc_use_alloca (len * sizeof (wchar_t))) \ string = (CHAR_T *) alloca (len * sizeof (wchar_t)); \ else if ((string = (CHAR_T *) malloc (len * sizeof (wchar_t))) \ == NULL) \
alloca
Some currently-open bugs:
alloca
usage in glibc are in
the works.
But...