[Date Prev][Date Next] [Thread Prev][Thread Next] [Date Index] [Thread Index]

Re: glibc regression on alpha with 2.34+



Hi Frank!

On 12/14/22 18:21, Frank Scheiner wrote:
    (sid-alpha-sbuild)glaubitz@z6:~/glibc-git/build$ LD_LIBRARY_PATH=/home/glaubitz/glibc-git/build /bin/bash

    If the bug is present, this command will segfault:

    Segmentation fault

    Otherwise it will just spawn another bash which can be exited with "exit":

    (sid-alpha-sbuild)glaubitz@z6:~/glibc-git/build$ LD_LIBRARY_PATH=/home/glaubitz/glibc-git/build /bin/bash
    (sid-alpha-sbuild)glaubitz@z6:~/glibc-git/build$
    exit
    (sid-alpha-sbuild)glaubitz@z6:~/glibc-git/build$

Can we be sure that this reproducer identifies the same problem than the build failures from the original post ([1])?

[1]: https://lists.debian.org/debian-alpha/2022/11/msg00003.html

Well, this is how I identified that there was a problem with glibc on alpha.

I built the packages manually with the testsuite enabled and installed them
into a chroot for testing which resulted in a segfault when dpkg tried to
configure the libc-bin package.

I assume the many testsuite failures are a direct result of this bug which
just causes many tests to segfault. We had a similar problem on sparc64 where
a single bug in the static build caused many testsuite failures.

Regardless, I can confirm this on my DS15:

```
root@ds15:/srv/storage/build# LD_LIBRARY_PATH=$PWD/glibc-at-36231bee7ab36d59dd121ea85b91411ae86945f3 /bin/bash
root@ds15:/srv/storage/build# echo $?
0
root@ds15:/srv/storage/build# exit
exit

root@ds15:/srv/storage/build# LD_LIBRARY_PATH=$PWD/glibc-at-6c57d320484988e87e446e2e60ce42816bf51d53 /bin/bash
Segmentation fault
root@ds15:/srv/storage/build# echo $?
139
```

...6c57d320484988e87e446e2e60ce42816bf51d53 is the first bad commit and 36231bee7ab36d59dd121ea85b91411ae86945f3 is its parent.

Good.

Do we also have a result for glibc@6c57d320484988e87e446e2e60ce42816bf51d53 with `-mcpu=ev67`?

I actually tried to verify whether building with '-mcpu=ev67 -mtune=ev67' would fix the problem
but I was unable to. I'm not sure whether the cross-compiler supports the ev67 target.

On the other hand, I did some more testing and it turned out that with commit 6c57d320484988e87e446e2e60ce42816bf51d53
applied, I could fix the segfault with the following minimal change:

diff --git a/elf/dl-sysdep.c b/elf/dl-sysdep.c
index bd5066fe3b..bc45a6e9d3 100644
--- a/elf/dl-sysdep.c
+++ b/elf/dl-sysdep.c
@@ -115,10 +115,10 @@ _dl_sysdep_start (void **start_argptr,
   user_entry = (ElfW(Addr)) ENTRY_POINT;
   GLRO(dl_platform) = NULL; /* Default to nothing known about the platform.  */
- /* NB: Default to a constant CONSTANT_MINSIGSTKSZ. */
-  _Static_assert (__builtin_constant_p (CONSTANT_MINSIGSTKSZ),
-                 "CONSTANT_MINSIGSTKSZ is constant");
-  GLRO(dl_minsigstacksize) = CONSTANT_MINSIGSTKSZ;
+  /* /\* NB: Default to a constant CONSTANT_MINSIGSTKSZ.  *\/ */
+  /* _Static_assert (__builtin_constant_p (CONSTANT_MINSIGSTKSZ), */
+  /*             "CONSTANT_MINSIGSTKSZ is constant"); */
+  /* GLRO(dl_minsigstacksize) = CONSTANT_MINSIGSTKSZ; */
for (av = GLRO(dl_auxv); av->a_type != AT_NULL; set_seen (av++))
     switch (av->a_type)
@@ -184,9 +184,9 @@ _dl_sysdep_start (void **start_argptr,
       case AT_RANDOM:
        _dl_random = (void *) av->a_un.a_val;
        break;
-      case AT_MINSIGSTKSZ:
-       GLRO(dl_minsigstacksize) = av->a_un.a_val;
-       break;
+      /* case AT_MINSIGSTKSZ: */
+      /*       GLRO(dl_minsigstacksize) = av->a_un.a_val; */
+      /*       break; */
       DL_PLATFORM_AUXV
       }
diff --git a/sysdeps/generic/ldsodefs.h b/sysdeps/generic/ldsodefs.h
index 9720a4e446..9ead714718 100644
--- a/sysdeps/generic/ldsodefs.h
+++ b/sysdeps/generic/ldsodefs.h
@@ -536,8 +536,8 @@ struct rtld_global_ro
   /* Cached value of `getpagesize ()'.  */
   EXTERN size_t _dl_pagesize;
- /* Cached value of `sysconf (_SC_MINSIGSTKSZ)'. */
-  EXTERN size_t _dl_minsigstacksize;
+  /* /\* Cached value of `sysconf (_SC_MINSIGSTKSZ)'.  *\/ */
+  /* EXTERN size_t _dl_minsigstacksize; */
/* Do we read from ld.so.cache? */
   EXTERN int _dl_inhibit_cache;
diff --git a/sysdeps/unix/sysv/linux/sysconf.c b/sysdeps/unix/sysv/linux/sysconf.c
index 366fcef01e..5a5c89f80e 100644
--- a/sysdeps/unix/sysv/linux/sysconf.c
+++ b/sysdeps/unix/sysv/linux/sysconf.c
@@ -77,12 +77,12 @@ __sysconf (int name)
       }
       break;
- case _SC_MINSIGSTKSZ:
-      assert (GLRO(dl_minsigstacksize) != 0);
-      return GLRO(dl_minsigstacksize);
+    /* case _SC_MINSIGSTKSZ: */
+    /*   assert (GLRO(dl_minsigstacksize) != 0); */
+    /*   return GLRO(dl_minsigstacksize); */
- case _SC_SIGSTKSZ:
-      return sysconf_sigstksz ();
+    /* case _SC_SIGSTKSZ: */
+    /*   return sysconf_sigstksz (); */
default:
       break;

Looking at the changes, it can only be this particular hunk that causes the segfault:

diff --git a/sysdeps/generic/ldsodefs.h b/sysdeps/generic/ldsodefs.h
index 9720a4e446..9ead714718 100644
--- a/sysdeps/generic/ldsodefs.h
+++ b/sysdeps/generic/ldsodefs.h
@@ -536,8 +536,8 @@ struct rtld_global_ro
   /* Cached value of `getpagesize ()'.  */
   EXTERN size_t _dl_pagesize;
- /* Cached value of `sysconf (_SC_MINSIGSTKSZ)'. */
-  EXTERN size_t _dl_minsigstacksize;
+  /* /\* Cached value of `sysconf (_SC_MINSIGSTKSZ)'.  *\/ */
+  /* EXTERN size_t _dl_minsigstacksize; */
/* Do we read from ld.so.cache? */
   EXTERN int _dl_inhibit_cache;

Interestingly, when I checkout the tag glibc-2.34 and disabled the _dl_minsigstacksize symbol
in "struct rtld_global_ro {}" again with the following hack, I'm no longer getting a segfault
but a floating point exception:

diff --git a/elf/dl-sysdep.c b/elf/dl-sysdep.c
index d47bef1340..8462e5859a 100644
--- a/elf/dl-sysdep.c
+++ b/elf/dl-sysdep.c
@@ -116,10 +116,10 @@ _dl_sysdep_start (void **start_argptr,
   user_entry = (ElfW(Addr)) ENTRY_POINT;
   GLRO(dl_platform) = NULL; /* Default to nothing known about the platform.  */
- /* NB: Default to a constant CONSTANT_MINSIGSTKSZ. */
-  _Static_assert (__builtin_constant_p (CONSTANT_MINSIGSTKSZ),
-             "CONSTANT_MINSIGSTKSZ is constant");
-  GLRO(dl_minsigstacksize) = CONSTANT_MINSIGSTKSZ;
+  /* /\* NB: Default to a constant CONSTANT_MINSIGSTKSZ.  *\/ */
+  /* _Static_assert (__builtin_constant_p (CONSTANT_MINSIGSTKSZ), */
+  /*                   "CONSTANT_MINSIGSTKSZ is constant"); */
+  /* GLRO(dl_minsigstacksize) = CONSTANT_MINSIGSTKSZ; */
for (av = GLRO(dl_auxv); av->a_type != AT_NULL; set_seen (av++))
     switch (av->a_type)
@@ -185,9 +185,9 @@ _dl_sysdep_start (void **start_argptr,
       case AT_RANDOM:
        _dl_random = (void *) av->a_un.a_val;
        break;
-      case AT_MINSIGSTKSZ:
-   GLRO(dl_minsigstacksize) = av->a_un.a_val;
-   break;
+      /* case AT_MINSIGSTKSZ: */
+      /*     GLRO(dl_minsigstacksize) = av->a_un.a_val; */
+      /*     break; */
       DL_PLATFORM_AUXV
       }
diff --git a/elf/rtld_static_init.c b/elf/rtld_static_init.c
index 3f8abb6800..aeac492235 100644
--- a/elf/rtld_static_init.c
+++ b/elf/rtld_static_init.c
@@ -67,9 +67,9 @@ __rtld_static_init (struct link_map *map)
   dl->_dl_hwcap = _dl_hwcap;
   extern __typeof (dl->_dl_hwcap2) _dl_hwcap2 attribute_hidden;
   dl->_dl_hwcap2 = _dl_hwcap2;
-  extern __typeof (dl->_dl_minsigstacksize) _dl_minsigstacksize
-    attribute_hidden;
-  dl->_dl_minsigstacksize = _dl_minsigstacksize;
+  /* extern __typeof (dl->_dl_minsigstacksize) _dl_minsigstacksize */
+  /*   attribute_hidden; */
+  /* dl->_dl_minsigstacksize = _dl_minsigstacksize; */
   extern __typeof (dl->_dl_pagesize) _dl_pagesize attribute_hidden;
   dl->_dl_pagesize = _dl_pagesize;
   extern __typeof (dl->_dl_tls_static_align) _dl_tls_static_align
diff --git a/sysdeps/generic/ldsodefs.h b/sysdeps/generic/ldsodefs.h
index 9c15259236..62117727e1 100644
--- a/sysdeps/generic/ldsodefs.h
+++ b/sysdeps/generic/ldsodefs.h
@@ -545,9 +545,6 @@ struct rtld_global_ro
   /* Cached value of `getpagesize ()'.  */
   EXTERN size_t _dl_pagesize;
- /* Cached value of `sysconf (_SC_MINSIGSTKSZ)'. */
-  EXTERN size_t _dl_minsigstacksize;
-
   /* Do we read from ld.so.cache?  */
   EXTERN int _dl_inhibit_cache;
diff --git a/sysdeps/unix/sysv/linux/sysconf-pthread_stack_min.h b/sysdeps/unix/sysv/linux/sysconf-pthread_stack_min.h
index 9e0eb0f7fc..2ba132e1fe 100644
--- a/sysdeps/unix/sysv/linux/sysconf-pthread_stack_min.h
+++ b/sysdeps/unix/sysv/linux/sysconf-pthread_stack_min.h
@@ -22,7 +22,7 @@ static inline long int
 __get_pthread_stack_min (void)
 {
   /* sysconf (_SC_THREAD_STACK_MIN) >= sysconf (_SC_MINSIGSTKSZ).  */
-  long int pthread_stack_min = GLRO(dl_minsigstacksize);
+  long int pthread_stack_min = 4096;
   assert (pthread_stack_min != 0);
   _Static_assert (__builtin_constant_p (PTHREAD_STACK_MIN),
                  "PTHREAD_STACK_MIN is constant");
diff --git a/sysdeps/unix/sysv/linux/sysconf.c b/sysdeps/unix/sysv/linux/sysconf.c
index daaeeb7d36..24afb2fdc5 100644
--- a/sysdeps/unix/sysv/linux/sysconf.c
+++ b/sysdeps/unix/sysv/linux/sysconf.c
@@ -84,11 +84,11 @@ __sysconf (int name)
       break;
case _SC_MINSIGSTKSZ:
-      assert (GLRO(dl_minsigstacksize) != 0);
-      return GLRO(dl_minsigstacksize);
+      //      assert (GLRO(dl_minsigstacksize) != 0);
+      return 4096; // GLRO(dl_minsigstacksize);
case _SC_SIGSTKSZ:
-      return sysconf_sigstksz ();
+      return 16384 ; //sysconf_sigstksz ();

Could you verify this on your DS-15?

Adrian

--
 .''`.  John Paul Adrian Glaubitz
: :' :  Debian Developer
`. `'   Physicist
  `-    GPG: 62FF 8A75 84E0 2956 9546  0006 7426 3B37 F5B5 F913



Reply to: