Bug 101749 - gcc -static-libasan broken because libasan.a needs __cxa_guard_release in libstdc++
Summary: gcc -static-libasan broken because libasan.a needs __cxa_guard_release in lib...
Status: RESOLVED FIXED
Alias: None
Product: gcc
Classification: Unclassified
Component: sanitizer (show other bugs)
Version: 11.2.0
: P3 normal
Target Milestone: ---
Assignee: Martin Liška
URL:
Keywords:
Depends on:
Blocks: 100114
  Show dependency treegraph
 
Reported: 2021-08-03 12:23 UTC by Xi Ruoyao
Modified: 2021-08-05 08:52 UTC (History)
5 users (show)

See Also:
Host:
Target:
Build:
Known to work: 12.0
Known to fail: 10.3.0, 11.2.0, 9.4.0
Last reconfirmed: 2021-08-03 00:00:00


Attachments

Note You need to log in before you can comment on or make changes to this bug.
Description Xi Ruoyao 2021-08-03 12:23:25 UTC
Test summary:

FAIL: c-c++-common/asan/pr59063-2.c   -O0  (test for excess errors)
UNRESOLVED: c-c++-common/asan/pr59063-2.c   -O0  compilation failed to produce executable
FAIL: c-c++-common/asan/pr59063-2.c   -O1  (test for excess errors)
UNRESOLVED: c-c++-common/asan/pr59063-2.c   -O1  compilation failed to produce executable
FAIL: c-c++-common/asan/pr59063-2.c   -O2  (test for excess errors)
UNRESOLVED: c-c++-common/asan/pr59063-2.c   -O2  compilation failed to produce executable
FAIL: c-c++-common/asan/pr59063-2.c   -O3 -g  (test for excess errors)
UNRESOLVED: c-c++-common/asan/pr59063-2.c   -O3 -g  compilation failed to produce executable
FAIL: c-c++-common/asan/pr59063-2.c   -Os  (test for excess errors)
UNRESOLVED: c-c++-common/asan/pr59063-2.c   -Os  compilation failed to produce executable
FAIL: c-c++-common/asan/pr59063-2.c   -O2 -flto -fno-use-linker-plugin -flto-partition=none  (test for excess errors)
UNRESOLVED: c-c++-common/asan/pr59063-2.c   -O2 -flto -fno-use-linker-plugin -flto-partition=none  compilation failed to produce executable
FAIL: c-c++-common/asan/pr59063-2.c   -O2 -flto -fuse-linker-plugin -fno-fat-lto-objects  (test for excess errors)
UNRESOLVED: c-c++-common/asan/pr59063-2.c   -O2 -flto -fuse-linker-plugin -fno-fat-lto-objects  compilation failed to produce executable

$ cc dummy.c -fsanitize=address -static-libasan
/usr/bin/ld: /usr/lib/gcc/x86_64-pc-linux-gnu/11.2.0/../../../../lib/libasan.a(sanitizer_posix_libcdep.o): in function `__sanitizer::SetAlternateSignalStack()':
/sources/gcc-11.2.0/build/x86_64-pc-linux-gnu/libsanitizer/sanitizer_common/../../../../libsanitizer/sanitizer_common/sanitizer_posix_libcdep.cpp:170: undefined reference to `__cxa_guard_acquire'
/usr/bin/ld: /usr/lib/gcc/x86_64-pc-linux-gnu/11.2.0/../../../../lib/libasan.a(sanitizer_posix_libcdep.o): in function `GetAltStackSize':
/sources/gcc-11.2.0/build/x86_64-pc-linux-gnu/libsanitizer/sanitizer_common/../../../../libsanitizer/sanitizer_common/sanitizer_posix_libcdep.cpp:170: undefined reference to `__cxa_guard_release'
/usr/bin/ld: /usr/lib/gcc/x86_64-pc-linux-gnu/11.2.0/../../../../lib/libasan.a(sanitizer_posix_libcdep.o): in function `__sanitizer::UnsetAlternateSignalStack()':
/sources/gcc-11.2.0/build/x86_64-pc-linux-gnu/libsanitizer/sanitizer_common/../../../../libsanitizer/sanitizer_common/sanitizer_posix_libcdep.cpp:170: undefined reference to `__cxa_guard_acquire'
/usr/bin/ld: /usr/lib/gcc/x86_64-pc-linux-gnu/11.2.0/../../../../lib/libasan.a(sanitizer_posix_libcdep.o): in function `GetAltStackSize':
/sources/gcc-11.2.0/build/x86_64-pc-linux-gnu/libsanitizer/sanitizer_common/../../../../libsanitizer/sanitizer_common/sanitizer_posix_libcdep.cpp:170: undefined reference to `__cxa_guard_release'
collect2: error: ld returned 1 exit status

Not sure if this is because something has changed in glibc-2.34.
Comment 1 Xi Ruoyao 2021-08-03 12:32:13 UTC
I guess it's fixed in trunk by something in 90e46074e6b3561ae7d8ebd205127f286cc0c6b6:

@@ -166,9 +158,10 @@ bool SupportsColoredOutput(fd_t fd) {
 #if !SANITIZER_GO
 // TODO(glider): different tools may require different altstack size.
 static uptr GetAltStackSize() {
-  // SIGSTKSZ is not enough.
-  static const uptr kAltStackSize = SIGSTKSZ * 4;
-  return kAltStackSize;
+  // Note: since GLIBC_2.31, SIGSTKSZ may be a function call, so this may be
+  // more costly that you think. However GetAltStackSize is only call 2-3 times
+  // per thread so don't cache the evaluation.
+  return SIGSTKSZ * 4;
 }

Not tested though.
Comment 2 Richard Biener 2021-08-03 12:57:43 UTC
This was last changed for PR100114
Comment 3 Xi Ruoyao 2021-08-03 13:08:02 UTC Comment hidden (obsolete)
Comment 4 Xi Ruoyao 2021-08-03 13:10:44 UTC Comment hidden (obsolete)
Comment 5 Jonathan Wakely 2021-08-03 16:15:59 UTC Comment hidden (obsolete)
Comment 6 Martin Liška 2021-08-04 08:08:43 UTC
(In reply to Xi Ruoyao from comment #1)
> I guess it's fixed in trunk by something in
> 90e46074e6b3561ae7d8ebd205127f286cc0c6b6:

Does it really fix the issue you see? I mean the unresolved references.
Comment 7 Jakub Jelinek 2021-08-04 09:00:11 UTC
(In reply to Martin Liška from comment #6)
> (In reply to Xi Ruoyao from comment #1)
> > I guess it's fixed in trunk by something in
> > 90e46074e6b3561ae7d8ebd205127f286cc0c6b6:
> 
> Does it really fix the issue you see? I mean the unresolved references.

It should.  Before that change there is a block scope variable that needs initialization and so that it is initialized just once (by the first thread calling that function and other threads waiting until the initialization completes) in a thread-safe way, it uses __cxa_guard*.
With the patch, there is no such variable, SIGSTKSZ * 4 is evaluated by each thread as many times as the function is called.
Comment 8 Martin Liška 2021-08-04 15:31:51 UTC
> It should.  Before that change there is a block scope variable that needs
> initialization and so that it is initialized just once (by the first thread
> calling that function and other threads waiting until the initialization
> completes) in a thread-safe way, it uses __cxa_guard*.
> With the patch, there is no such variable, SIGSTKSZ * 4 is evaluated by each
> thread as many times as the function is called.

Thanks for the full explanation.
So it seems it's fine on master, should I backport the fix to release branches?
Or is your fix g:d9f462fb372fb02da032cefd6b091d7582c425ae sufficient?
Comment 9 Jakub Jelinek 2021-08-04 15:34:21 UTC
(In reply to Martin Liška from comment #8)
> Thanks for the full explanation.
> So it seems it's fine on master, should I backport the fix to release
> branches?

Yes, please.
Comment 10 Martin Liška 2021-08-04 15:36:24 UTC
Mine then.
Comment 11 GCC Commits 2021-08-05 08:48:40 UTC
The releases/gcc-11 branch has been updated by Martin Liska <marxin@gcc.gnu.org>:

https://gcc.gnu.org/g:91f8a7a34cf29ae7c465603a801326767f1cc7e9

commit r11-8828-g91f8a7a34cf29ae7c465603a801326767f1cc7e9
Author: Martin Liska <mliska@suse.cz>
Date:   Thu Aug 5 10:43:17 2021 +0200

    sanitizer: cherry pick 414482751452e54710f16bae58458c66298aaf69
    
    The patch is needed in order to support recent glibc (2.34).
    
    libsanitizer/ChangeLog:
    
            PR sanitizer/101749
            * sanitizer_common/sanitizer_posix_libcdep.cpp: Prevent
            generation of dependency on _cxa_guard for static
            initialization.
Comment 12 GCC Commits 2021-08-05 08:49:24 UTC
The releases/gcc-10 branch has been updated by Martin Liska <marxin@gcc.gnu.org>:

https://gcc.gnu.org/g:6bbaa64881715b8df2d717e418eeec7b7e974a22

commit r10-10020-g6bbaa64881715b8df2d717e418eeec7b7e974a22
Author: Martin Liska <mliska@suse.cz>
Date:   Thu Aug 5 10:43:17 2021 +0200

    sanitizer: cherry pick 414482751452e54710f16bae58458c66298aaf69
    
    The patch is needed in order to support recent glibc (2.34).
    
    libsanitizer/ChangeLog:
    
            PR sanitizer/101749
            * sanitizer_common/sanitizer_posix_libcdep.cpp: Prevent
            generation of dependency on _cxa_guard for static
            initialization.
Comment 13 GCC Commits 2021-08-05 08:51:58 UTC
The releases/gcc-9 branch has been updated by Martin Liska <marxin@gcc.gnu.org>:

https://gcc.gnu.org/g:11e2ac8f75060d9be432e8db1f358298a75c98d4

commit r9-9661-g11e2ac8f75060d9be432e8db1f358298a75c98d4
Author: Martin Liska <mliska@suse.cz>
Date:   Thu Aug 5 10:43:17 2021 +0200

    sanitizer: cherry pick 414482751452e54710f16bae58458c66298aaf69
    
    The patch is needed in order to support recent glibc (2.34).
    
    libsanitizer/ChangeLog:
    
            PR sanitizer/101749
            * sanitizer_common/sanitizer_posix_libcdep.cc: Prevent
            generation of dependency on _cxa_guard for static
            initialization.
Comment 14 Martin Liška 2021-08-05 08:52:27 UTC
Fixes now on all active branches.