On 4/29/19 6:18 PM, Arnaldo Carvalho de Melo wrote:
>>> Auto-detecting system features:
>>> ... dwarf: [ OFF ]
>>> ... dwarf_getlocations: [ OFF ]
>>> ... glibc: [ on ]
>> Not related to current issue, this run uses a uClibc toolchain and yet it is
>> detecting glibc - doesn't seem right to me.
> Ok, I'll improve that, I think it just tries to detect a libc, yeah,
> see:
>
> [acme@quaco linux]$ cat tools/build/feature/test-glibc.c
> // SPDX-License-Identifier: GPL-2.0
> #include <stdlib.h>
>
> #if !defined(__UCLIBC__)
> #include <gnu/libc-version.h>
> #else
> #define XSTR(s) STR(s)
> #define STR(s) #s
> #endif
>
> int main(void)
> {
> #if !defined(__UCLIBC__)
> const char *version = gnu_get_libc_version();
> #else
> const char *version = XSTR(__GLIBC__) "." XSTR(__GLIBC_MINOR__);
> #endif
>
> return (long)version;
> }
> [acme@quaco linux]$
>
> [perfbuilder@59ca4b424ded /]$ grep __GLIBC__ /arc_gnu_2017.09-rc2_prebuilt_uclibc_le_arc700_linux_install/arc-snps-linux-uclibc/sysroot/usr/include/*.h
> /arc_gnu_2017.09-rc2_prebuilt_uclibc_le_arc700_linux_install/arc-snps-linux-uclibc/sysroot/usr/include/features.h: The macros `__GNU_LIBRARY__', `__GLIBC__', and `__GLIBC_MINOR__' are
> /arc_gnu_2017.09-rc2_prebuilt_uclibc_le_arc700_linux_install/arc-snps-linux-uclibc/sysroot/usr/include/features.h:#define __GLIBC__ 2
> /arc_gnu_2017.09-rc2_prebuilt_uclibc_le_arc700_linux_install/arc-snps-linux-uclibc/sysroot/usr/include/features.h: ((__GLIBC__ << 16) + __GLIBC_MINOR__ >= ((maj) << 16) + (min))
> [perfbuilder@59ca4b424ded /]$
>
> Isn't that part of uClibc?
Right you are. Per the big fat comment right above that code, this gross hack in
uclibc is unavoidable as applications tend to rely on that define.
So a better fix would be to check for various !GLIBC libs explicitly.
#ifdef __UCLIBC__
#elseif defined __MUSL__
...
Not pretty from app usage pov, but that seems to be the only sane way of doing it.
-Vineet
Hi Volodymyr, all,
> -----Original Message-----
> From: Volodymyr Boyko <boyko.cxx(a)gmail.com>
> Sent: Monday, April 22, 2019 4:24 PM
> To: Alexey Brodkin <abrodkin(a)synopsys.com>
> Subject: Re: [uclibc-ng-devel] https://uclibc-ng.org/ is not available
>
> Can confirm that the site is available from Ukraine (16:23 22.04).
Looks like it was a short glitch and since then no other failures
have been observed, so sorry for the noise.
-Alexey
Hello,
I am wondering if libpthread/nptl/sysdeps/generic/dl-tls.c could be
cleaned up a little bit to improve code readability.
Especially I can see in the first lines that "#if SHARED => #error":
https://elixir.bootlin.com/uclibc-ng/latest/source/libpthread/nptl/sysdeps/…
And then the file contains some #ifdef SHARED (5 of them actually)
I wonder why this code is still guarded by ifdefs.
I am guessing that this is for maintainability purposes so that this
file does not diverge too much from its friend at ./ldso/ldso/dl-tls.c
and to ease maintaining both in sync.
If this guess is right, I believe removing code between "#ifdef SHARED"
is a no-go?
In this case, I would propose changing "#ifdef SHARED" by "#if 0".
So that it is very obvious for readers that the code is never included.
That would also keep it easy to maintain both files in sync.
If previous guesses are wrong maybe we can just strip the code altogether.
Based on the feedbacks I would propose a patch accordingly.
Thank's for your feedback on that!
Regards,
--
Yann
This test was changed from using fork to vfork by:
https://cgit.uclibc-ng.org/cgi/cgit/uclibc-ng.git/commit/?id=822e4896c1072b…
This change was wrong because man page says the child of vfork() must ONLY do either:
- a call to one of exec(2)
- a call to _exit(2)
- get killed by a signal
BUT the test case does:
- a call to kill
- and also a call to exit(3) and not _exit(2)
This test produces a double free() causing assert in free because this is called several times:
https://elixir.bootlin.com/uclibc-ng/latest/source/libc/stdlib/_atexit.c#L2…
So, it seems wrong both in theory (according to man page) and in fact in practice (assert in free).
Here I propose to get back to testing fork(), which is the original test case from:
https://sourceware.org/bugzilla/show_bug.cgi?id=838
And to just "PASS" on no-mmu systems.
For the record, here is the assert call stack:
FAIL tst-mallocfork got 1 expected 0
./tst-mallocfork: libc/stdlib/malloc-standard/malloc.c: 149: __do_check_inuse_chunk: Assertion `((((mchunkptr)(((char*)(p))+((p)->size & ~0x1)))->size) & 0x1)' failed.
Didn't expect signal from child: got `Aborted'
0 free (mem=0x3a010) at libc/stdlib/malloc-standard/free.c:285
1 0x00000000000220c4 in __exit_handler (status=1) at libc/stdlib/_atexit.c:270
2 0x000000000001afa0 in __GI_exit (rv=1) at libc/stdlib/_atexit.c:301
3 0x0000000000010dcc in main (argc=1, argv=0x7ffffffd98) at ../test-skeleton.c:405
4 0x000000000001cba8 in __uClibc_main (main=0x10988 <main>, argc=1, argv=0x7ffffffd98, app_init=0x100e8, app_fini=0x23918 <_fini>, rtld_fini=0x0 <k1c_start>, stack_end=0x7ffffffd90) at libc/misc/internals/__uClibc_main.c:512
5 0x00000000000eb8b8 in ?? ()
Signed-off-by: Yann Sionneau <ysionneau(a)kalray.eu>
---
test/malloc/tst-mallocfork.c | 17 +++++++++++++++--
1 file changed, 15 insertions(+), 2 deletions(-)
diff --git a/test/malloc/tst-mallocfork.c b/test/malloc/tst-mallocfork.c
index edd9c39..e9e5133 100644
--- a/test/malloc/tst-mallocfork.c
+++ b/test/malloc/tst-mallocfork.c
@@ -9,10 +9,12 @@
#include <sys/wait.h>
#include "../test-skeleton.h"
+#ifdef __ARCH_USE_MMU__
+
static void
sig_handler (int signum)
{
- pid_t child = vfork ();
+ pid_t child = fork ();
if (child == 0)
exit (0);
TEMP_FAILURE_RETRY (waitpid (child, NULL, 0));
@@ -35,7 +37,7 @@ do_test (void)
}
/* Create a child that sends the signal to be caught. */
- pid_t child = vfork ();
+ pid_t child = fork ();
if (child == 0)
{
if (kill (parent, SIGALRM) == -1)
@@ -48,5 +50,16 @@ do_test (void)
return 0;
}
+#else
+
+static int
+do_test (void)
+{
+ printf("Skipping test on non-mmu host!\n");
+ return EXIT_SUCCESS;
+}
+
+#endif
+
#define TEST_FUNCTION do_test ()
#include "../test-skeleton.c"
--
1.8.3.1
For ARCH where shared lib are not supported:
- SHARED is not set (!SHARED is true)
- __ARCH_HAS_NO_LDSO__ is set
so code inside #if !defined __ARCH_HAS_NO_LDSO__ && !defined SHARED
is compiled-out.
But without a call do _dl_aux_init(), _dl_phdr stays NULL and
__libc_setup_tls won't be able to allocate memory for the in-executable TLS
and also won't be able to load the initimage from ELF TLS segment.
This results in segfault when doing things like "errno = 0" like
in tst-cancel15.c for instance in uClibc-ng testsuite.
Signed-off-by: Yann Sionneau <ysionneau(a)kalray.eu>
---
libc/misc/internals/__uClibc_main.c | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/libc/misc/internals/__uClibc_main.c b/libc/misc/internals/__uClibc_main.c
index 849bca8..affa0ce 100644
--- a/libc/misc/internals/__uClibc_main.c
+++ b/libc/misc/internals/__uClibc_main.c
@@ -370,7 +370,7 @@ void __uClibc_main(int (*main)(int, char **, char **), int argc,
char **argv, void (*app_init)(void), void (*app_fini)(void),
void (*rtld_fini)(void), void *stack_end attribute_unused)
{
-#if !defined __ARCH_HAS_NO_LDSO__ && !defined SHARED
+#ifndef SHARED
unsigned long *aux_dat;
ElfW(auxv_t) auxvt[AT_EGID + 1];
#endif
@@ -396,7 +396,7 @@ void __uClibc_main(int (*main)(int, char **, char **), int argc,
__environ = &argv[argc];
}
-#if !defined __ARCH_HAS_NO_LDSO__ && !defined SHARED
+#ifndef SHARED
/* Pull stuff from the ELF header when possible */
memset(auxvt, 0x00, sizeof(auxvt));
aux_dat = (unsigned long*)__environ;
--
1.8.3.1
This patch seems needed in builds where
- SHARED is not defined (no shared lib support)
- and USE_TLS is set
Without this patch, static_dtv is free'ed.
See the following backtrace:
0 __do_check_chunk (p=0x52638 <fork_handler_pool+2296>) at libc/stdlib/malloc-standard/malloc.c:80
1 0x0000000000017fa0 in __do_check_inuse_chunk (p=0x52638 <fork_handler_pool+2296>) at libc/stdlib/malloc-standard/malloc.c:143
2 0x0000000000017354 in free (mem=0x52648 <static_dtv>) at libc/stdlib/malloc-standard/free.c:293
3 0x000000000002d5b0 in _dl_deallocate_tls (tcb=0x58690, dealloc_tcb=false) at libpthread/nptl/sysdeps/generic/dl-tls.c:588
4 0x0000000000021c0c in __deallocate_stack (pd=0x58000) at libpthread/nptl/allocatestack.c:717
5 0x0000000000024408 in __free_tcb (pd=0x58000) at libpthread/nptl/pthread_create.c:217
6 0x00000000000200ac in pthread_join (threadid=360448, thread_return=0x0 <k1c_start>) at libpthread/nptl/pthread_join.c:109
7 0x0000000000010354 in tf (a=0x58000) at tst-basic3.c:42
8 0x00000000000247c8 in start_thread (arg=0x4000200960) at libpthread/nptl/pthread_create.c:285
9 0x0000000000026560 in ?? ()
This backtrace is obtained while debugging tst-basic3 from the uclibc-ng nptl testsuite.
It aborts because of the assert in malloc:
https://elixir.bootlin.com/uclibc-ng/v1.0.31/source/libc/stdlib/malloc-stan…
Signed-off-by: Yann Sionneau <ysionneau(a)kalray.eu>
---
libpthread/nptl/sysdeps/generic/dl-tls.c | 5 +++++
libpthread/nptl/sysdeps/generic/libc-tls.c | 5 ++++-
2 files changed, 9 insertions(+), 1 deletion(-)
diff --git a/libpthread/nptl/sysdeps/generic/dl-tls.c b/libpthread/nptl/sysdeps/generic/dl-tls.c
index 989e587a2..7d25e4706 100644
--- a/libpthread/nptl/sysdeps/generic/dl-tls.c
+++ b/libpthread/nptl/sysdeps/generic/dl-tls.c
@@ -48,6 +48,9 @@
/* Value used for dtv entries for which the allocation is delayed. */
# define TLS_DTV_UNALLOCATED ((void *) -1l)
+#ifndef SHARED
+extern dtv_t static_dtv;
+#endif
/* Out-of-memory handler. */
# ifdef SHARED
@@ -584,6 +587,8 @@ _dl_deallocate_tls (void *tcb, bool dealloc_tcb)
/* The array starts with dtv[-1]. */
#ifdef SHARED
if (dtv != GL(dl_initial_dtv))
+#else
+ if ((dtv - 1) != &static_dtv)
#endif
free (dtv - 1);
diff --git a/libpthread/nptl/sysdeps/generic/libc-tls.c b/libpthread/nptl/sysdeps/generic/libc-tls.c
index a6df4cdc4..d746c9a38 100644
--- a/libpthread/nptl/sysdeps/generic/libc-tls.c
+++ b/libpthread/nptl/sysdeps/generic/libc-tls.c
@@ -42,7 +42,10 @@ extern size_t _dl_phnum;
extern int __tdata_start;
#endif
-static dtv_t static_dtv[2 + TLS_SLOTINFO_SURPLUS];
+#ifdef SHARED
+static
+#endif
+dtv_t static_dtv[2 + TLS_SLOTINFO_SURPLUS];
static struct
--
2.21.0
This patch seems needed in builds where
- SHARED is not defined (no shared lib support)
- and USE_TLS is set
Without this patch, static_dtv is free'ed.
See the following backtrace:
This backtrace is obtained while debugging tst-basic3 from the uclibc-ng nptl testsuite.
It aborts because of the assert in malloc:
https://elixir.bootlin.com/uclibc-ng/v1.0.31/source/libc/stdlib/malloc-stan…
Signed-off-by: Yann Sionneau <ysionneau(a)kalray.eu>
---
libpthread/nptl/sysdeps/generic/dl-tls.c | 5 +++++
libpthread/nptl/sysdeps/generic/libc-tls.c | 5 ++++-
2 files changed, 9 insertions(+), 1 deletion(-)
diff --git a/libpthread/nptl/sysdeps/generic/dl-tls.c b/libpthread/nptl/sysdeps/generic/dl-tls.c
index 989e587a2..7d25e4706 100644
--- a/libpthread/nptl/sysdeps/generic/dl-tls.c
+++ b/libpthread/nptl/sysdeps/generic/dl-tls.c
@@ -48,6 +48,9 @@
/* Value used for dtv entries for which the allocation is delayed. */
# define TLS_DTV_UNALLOCATED ((void *) -1l)
+#ifndef SHARED
+extern dtv_t static_dtv;
+#endif
/* Out-of-memory handler. */
# ifdef SHARED
@@ -584,6 +587,8 @@ _dl_deallocate_tls (void *tcb, bool dealloc_tcb)
/* The array starts with dtv[-1]. */
#ifdef SHARED
if (dtv != GL(dl_initial_dtv))
+#else
+ if ((dtv - 1) != &static_dtv)
#endif
free (dtv - 1);
diff --git a/libpthread/nptl/sysdeps/generic/libc-tls.c b/libpthread/nptl/sysdeps/generic/libc-tls.c
index a6df4cdc4..d746c9a38 100644
--- a/libpthread/nptl/sysdeps/generic/libc-tls.c
+++ b/libpthread/nptl/sysdeps/generic/libc-tls.c
@@ -42,7 +42,10 @@ extern size_t _dl_phnum;
extern int __tdata_start;
#endif
-static dtv_t static_dtv[2 + TLS_SLOTINFO_SURPLUS];
+#ifdef SHARED
+static
+#endif
+dtv_t static_dtv[2 + TLS_SLOTINFO_SURPLUS];
static struct
--
2.21.0