The problem here is how errno is handled in cwidget (used by aptitude).
man errno:
In cwidget-0.5.18/src/cwidget/toplevel.cc:488 result of select is used
incorrectly. It's allowed to return any value different than -1 on success.
errno can be checked **only** if select returns -1.
Relevant part of code:
pthread_testcancel();
int result = select(1, &selectfds, NULL, NULL, &timeout);
pthread_testcancel(); // Workaround for Linux threads suckage.
// See pthread_cancel(3).
if(result != 1)
{
if(errno != EINTR && errno != 0)
{
// Probably means that there was an error reading
// standard input. (could also be ENOMEM)
post_event(new fatal_input_error(errno));
break;
}
}
If errno was not 0 before we are entering a loop it's game over.
fatal_input_error path is triggered and aptitude will die.
How it was found? First observation is that error is:
Let's run aptitude under strace: strace -f aptitude and search for
EINVAL.
Here is a result in my test env:
1209 madvise(0xaaab14a00000, 2097152, MADV_HUGEPAGE) = -1 EINVAL (Invalid argument)
1210 <... madvise resumed>) = -1 EINVAL (Invalid argument)
1211 <... madvise resumed>) = -1 EINVAL (Invalid argument)
1212 <... madvise resumed>) = -1 EINVAL (Invalid argument)
1209 readlinkat(AT_FDCWD, "/var", 0xffffd3d22040, 1023) = -1 EINVAL (Invalid argument)
1209 readlinkat(AT_FDCWD, "/var/lib", 0xffffd3d22040, 1023) = -1 EINVAL (Invalid argument)
1209 readlinkat(AT_FDCWD, "/var/lib/dpkg", 0xffffd3d22040, 1023) = -1 EINVAL (Invalid argument)
1209 readlinkat(AT_FDCWD, "/var/lib/dpkg/status", 0xffffd3d22040, 1023) = -1 EINVAL (Invalid argument)
1209 madvise(0xffffa4c5f000, 4677632, MADV_HUGEPAGE) = -1 EINVAL (Invalid argument)
1209 madvise(0xffffa4363000, 9420800, MADV_HUGEPAGE) = -1 EINVAL (Invalid argument)
1209 madvise(0xffff92d39000, 25116672, MADV_HUGEPAGE) = -1 EINVAL (Invalid argument)
1209 madvise(0xffff9243d000, 9420800, MADV_HUGEPAGE) = -1 EINVAL (Invalid argument)
1209 madvise(0xffff90c49000, 25116672, MADV_HUGEPAGE) = -1 EINVAL (Invalid argument)
1209 madvise(0xffff90a48000, 2101248, MADV_HUGEPAGE) = -1 EINVAL (Invalid argument)
1209 madvise(0xffff90647000, 4198400, MADV_HUGEPAGE) = -1 EINVAL (Invalid argument)
1209 madvise(0xffff8fe46000, 8392704, MADV_HUGEPAGE) = -1 EINVAL (Invalid argument)
1209 madvise(0xffff8ee45000, 16781312, MADV_HUGEPAGE) = -1 EINVAL (Invalid argument)
1209 madvise(0xffff902ae000, 10072064, MADV_HUGEPAGE) = -1 EINVAL (Invalid argument)
1209 madvise(0xffff8e4aa000, 10072064, MADV_HUGEPAGE) = -1 EINVAL (Invalid argument)
1209 madvise(0xaaab14c00000, 2097152, MADV_HUGEPAGE) = -1 EINVAL (Invalid argument)
1209 madvise(0xaaab14e00000, 10485760, MADV_HUGEPAGE) = -1 EINVAL (Invalid argument)
1209 madvise(0xaaab15800000, 4194304, MADV_HUGEPAGE) = -1 EINVAL (Invalid argument)
1209 madvise(0xaaab15c00000, 4194304, MADV_HUGEPAGE) = -1 EINVAL (Invalid argument)
1209 madvise(0xaaab16000000, 2097152, MADV_HUGEPAGE) = -1 EINVAL (Invalid argument)
1209 madvise(0xaaab16200000, 2097152, MADV_HUGEPAGE) = -1 EINVAL (Invalid argument)
1209 madvise(0xaaab16400000, 6291456, MADV_HUGEPAGE) = -1 EINVAL (Invalid argument)
1209 madvise(0xaaab16a00000, 10485760, MADV_HUGEPAGE) = -1 EINVAL (Invalid argument)
1209 madvise(0xaaab17400000, 2097152, MADV_HUGEPAGE) = -1 EINVAL (Invalid argument)
1209 madvise(0xaaab17600000, 2097152, MADV_HUGEPAGE) = -1 EINVAL (Invalid argument)
1209 madvise(0xaaab17800000, 2097152, MADV_HUGEPAGE) = -1 EINVAL (Invalid argument)
1209 madvise(0xaaab17a00000, 2097152, MADV_HUGEPAGE) = -1 EINVAL (Invalid argument)
1209 madvise(0xaaab17c00000, 2097152, MADV_HUGEPAGE) = -1 EINVAL (Invalid argument)
1209 madvise(0xaaab17e00000, 2097152, MADV_HUGEPAGE) = -1 EINVAL (Invalid argument)
1209 madvise(0xaaab18000000, 2097152, MADV_HUGEPAGE) = -1 EINVAL (Invalid argument)
1209 madvise(0xaaab18200000, 2097152, MADV_HUGEPAGE) = -1 EINVAL (Invalid argument)
1209 madvise(0xaaab18400000, 2097152, MADV_HUGEPAGE) = -1 EINVAL (Invalid argument)
1209 madvise(0xaaab18600000, 2097152, MADV_HUGEPAGE) = -1 EINVAL (Invalid argument)
1209 madvise(0xaaab18800000, 2097152, MADV_HUGEPAGE) = -1 EINVAL (Invalid argument)
1209 madvise(0xaaab18a00000, 2097152, MADV_HUGEPAGE) = -1 EINVAL (Invalid argument)
1209 madvise(0xaaab18c00000, 2097152, MADV_HUGEPAGE) = -1 EINVAL (Invalid argument)
1209 madvise(0xaaab18e00000, 2097152, MADV_HUGEPAGE) = -1 EINVAL (Invalid argument)
1209 madvise(0xaaab19000000, 2097152, MADV_HUGEPAGE) = -1 EINVAL (Invalid argument)
1209 madvise(0xaaab19200000, 2097152, MADV_HUGEPAGE) = -1 EINVAL (Invalid argument)
1209 madvise(0xaaab19400000, 2097152, MADV_HUGEPAGE) = -1 EINVAL (Invalid argument)
1209 madvise(0xaaab19600000, 2097152, MADV_HUGEPAGE) = -1 EINVAL (Invalid argument)
1209 madvise(0xaaab19800000, 2097152, MADV_HUGEPAGE) = -1 EINVAL (Invalid argument)
1209 madvise(0xaaab19a00000, 2097152, MADV_HUGEPAGE) = -1 EINVAL (Invalid argument)
1209 madvise(0xaaab19c00000, 2097152, MADV_HUGEPAGE) = -1 EINVAL (Invalid argument)
1209 madvise(0xaaab19e00000, 2097152, MADV_HUGEPAGE) = -1 EINVAL (Invalid argument)
1209 madvise(0xaaab1a000000, 2097152, MADV_HUGEPAGE) = -1 EINVAL (Invalid argument)
1209 madvise(0xaaab1a200000, 2097152, MADV_HUGEPAGE) = -1 EINVAL (Invalid argument)
1209 madvise(0xaaab1a400000, 2097152, MADV_HUGEPAGE) = -1 EINVAL (Invalid argument)
1209 madvise(0xaaab1a600000, 2097152, MADV_HUGEPAGE) = -1 EINVAL (Invalid argument)
1209 madvise(0xaaab1a800000, 2097152, MADV_HUGEPAGE) = -1 EINVAL (Invalid argument)
1209 madvise(0xaaab1aa00000, 2097152, MADV_HUGEPAGE) = -1 EINVAL (Invalid argument)
1209 madvise(0xaaab1ac00000, 2097152, MADV_HUGEPAGE) = -1 EINVAL (Invalid argument)
1209 madvise(0xaaab1ae00000, 2097152, MADV_HUGEPAGE) = -1 EINVAL (Invalid argument)
1209 madvise(0xaaab1b000000, 2097152, MADV_HUGEPAGE) = -1 EINVAL (Invalid argument)
1209 madvise(0xaaab1b200000, 2097152, MADV_HUGEPAGE) = -1 EINVAL (Invalid argument)
1209 madvise(0xaaab1b400000, 2097152, MADV_HUGEPAGE) = -1 EINVAL (Invalid argument)
1209 madvise(0xaaab1b600000, 2097152, MADV_HUGEPAGE) = -1 EINVAL (Invalid argument)
1209 madvise(0xaaab1b800000, 2097152, MADV_HUGEPAGE) = -1 EINVAL (Invalid argument)
Why that happens? Looks like since libc 2.43 in arm64 version of Debian
libc tries to be smart about hugepages and set hints.
Here is a snippet from glibc malloc.c:
static inline void
madvise_thp (void *p, INTERNAL_SIZE_T size)
{
#ifdef MADV_HUGEPAGE
/* Only use __madvise if the system is using 'madvise' mode and the size
is at least a huge page, otherwise the call is wasteful. */
if (mp_.thp_mode != thp_mode_madvise || size < mp_.thp_pagesize)
return;
/* Linux requires the input address to be page-aligned, and unaligned
inputs happens only for initial data segment. */
if (__glibc_unlikely (!PTR_IS_ALIGNED (p, GLRO (dl_pagesize))))
{
void *q = PTR_ALIGN_UP (p, GLRO (dl_pagesize));
size -= PTR_DIFF (q, p);
p = q;
}