public inbox for gcc-bugs@sourceware.org
help / color / mirror / Atom feed
* [Bug libstdc++/60662] New: simple use of call_once throws a system_error exception, but not if sleep_for is called beforehand
@ 2014-03-26  1:02 sambler at alumni dot nd.edu
  2014-03-26 11:33 ` [Bug libstdc++/60662] " redi at gcc dot gnu.org
                   ` (5 more replies)
  0 siblings, 6 replies; 7+ messages in thread
From: sambler at alumni dot nd.edu @ 2014-03-26  1:02 UTC (permalink / raw)
  To: gcc-bugs

http://gcc.gnu.org/bugzilla/show_bug.cgi?id=60662

            Bug ID: 60662
           Summary: simple use of call_once throws a system_error
                    exception, but not if sleep_for is called beforehand
           Product: gcc
           Version: 4.8.1
            Status: UNCONFIRMED
          Severity: normal
          Priority: P3
         Component: libstdc++
          Assignee: unassigned at gcc dot gnu.org
          Reporter: sambler at alumni dot nd.edu

Created attachment 32457
  --> http://gcc.gnu.org/bugzilla/attachment.cgi?id=32457&action=edit
preprocessed source code, lengthy due to standard C++ headers

file test_unique.cc (misnomer from original guess at cause of problem):

#include <chrono>
#include <mutex>
#include <thread>

using namespace std;

int main() {
  once_flag once;
  // this_thread::sleep_for(chrono::milliseconds(1));
  call_once(once, [](){});
  return 0;
}

file buildcc11:

g++ -std=c++11 -Wall -Wextra -save-temps $1.cc -lpthread -o $1

execution:

$ ./buildcc11 test_unique
$ ./test_unique
terminate called after throwing an instance of 'std::system_error'
  what():  Unknown error -1
Aborted (core dumped)
$

whereas after uncommenting the sleep_for line:

$ ./buildcc11 test_unique
$ ./test_unique
$

BEGIN PARENTHETICAL NOTE:
Initially discovered in a more complicated context, this problem was quite
robust w.r.t. a number of changes such as for simplification.  For example,
the following less artificial use of call_once has the same problem (file
test_unique_2.cc):

#include <chrono>
#include <iostream>
#include <mutex>
#include <thread>

using namespace std;

once_flag once;
int n = 0;

void f(int n_arg) {
  n = n_arg;
}

int main() {
  // this_thread::sleep_for(chrono::milliseconds(1));
  int m = 1;
  call_once(once, f, m++);
  call_once(once, f, m++);
  call_once(once, f, m++);
  cout << "n " << n << endl;

  return 0;
}

$ ./buildcc11 test_unique_2
$ ./test_unique_2
terminate called after throwing an instance of 'std::system_error'
  what():  Unknown error -1
Aborted (core dumped)
$

whereas after uncommenting the sleep_for:

$ ./buildcc11 test_unique_2
$ ./test_unique_2
n 1
$
END PARENTHETICAL NOTE

compiler & system info:

$ gcc -v
Using built-in specs.
COLLECT_GCC=gcc
COLLECT_LTO_WRAPPER=/usr/lib/gcc/x86_64-linux-gnu/4.8/lto-wrapper
Target: x86_64-linux-gnu
Configured with: ../src/configure -v --with-pkgversion='Ubuntu/Linaro
4.8.1-10ubuntu9' --with-bugurl=file:///usr/share/doc/gcc-4.8/README.Bugs
--enable-languages=c,c++,java,go,d,fortran,objc,obj-c++ --prefix=/usr
--program-suffix=-4.8 --enable-shared --enable-linker-build-id
--libexecdir=/usr/lib --without-included-gettext --enable-threads=posix
--with-gxx-include-dir=/usr/include/c++/4.8 --libdir=/usr/lib --enable-nls
--with-sysroot=/ --enable-clocale=gnu --enable-libstdcxx-debug
--enable-libstdcxx-time=yes --enable-gnu-unique-object --enable-plugin
--with-system-zlib --disable-browser-plugin --enable-java-awt=gtk
--enable-gtk-cairo --with-java-home=/usr/lib/jvm/java-1.5.0-gcj-4.8-amd64/jre
--enable-java-home --with-jvm-root-dir=/usr/lib/jvm/java-1.5.0-gcj-4.8-amd64
--with-jvm-jar-dir=/usr/lib/jvm-exports/java-1.5.0-gcj-4.8-amd64
--with-arch-directory=amd64 --with-ecj-jar=/usr/share/java/eclipse-ecj.jar
--enable-objc-gc --enable-multiarch --disable-werror --with-arch-32=i686
--with-abi=m64 --with-multilib-list=m32,m64,mx32 --with-tune=generic
--enable-checking=release --build=x86_64-linux-gnu --host=x86_64-linux-gnu
--target=x86_64-linux-gnu
Thread model: posix
gcc version 4.8.1 (Ubuntu/Linaro 4.8.1-10ubuntu9) 

lenovo ThinkPad SL510 2x Intel Core 2 Duo T6670 2.20 GHz, 8 GB RAM, Ubuntu
13.10 (Lubuntu), Linux 3.11.0-18-generic (x86_64).

preprocessed file from ./buildcc11 test_unique with commented-out sleep_for not
included b/c of 64K char limit on this field; instead attached.

Thanks!


^ permalink raw reply	[flat|nested] 7+ messages in thread

* [Bug libstdc++/60662] simple use of call_once throws a system_error exception, but not if sleep_for is called beforehand
  2014-03-26  1:02 [Bug libstdc++/60662] New: simple use of call_once throws a system_error exception, but not if sleep_for is called beforehand sambler at alumni dot nd.edu
@ 2014-03-26 11:33 ` redi at gcc dot gnu.org
  2014-04-11  5:29 ` sambler at alumni dot nd.edu
                   ` (4 subsequent siblings)
  5 siblings, 0 replies; 7+ messages in thread
From: redi at gcc dot gnu.org @ 2014-03-26 11:33 UTC (permalink / raw)
  To: gcc-bugs

http://gcc.gnu.org/bugzilla/show_bug.cgi?id=60662

--- Comment #1 from Jonathan Wakely <redi at gcc dot gnu.org> ---
I can't reproduce this with 4.8.1 or later versions on Fedora, or 4.8.3 on
Debian, neither using your original source code nor your preprocessed source.

Please try debugging this yourself or report it to Ubuntu.


^ permalink raw reply	[flat|nested] 7+ messages in thread

* [Bug libstdc++/60662] simple use of call_once throws a system_error exception, but not if sleep_for is called beforehand
  2014-03-26  1:02 [Bug libstdc++/60662] New: simple use of call_once throws a system_error exception, but not if sleep_for is called beforehand sambler at alumni dot nd.edu
  2014-03-26 11:33 ` [Bug libstdc++/60662] " redi at gcc dot gnu.org
@ 2014-04-11  5:29 ` sambler at alumni dot nd.edu
  2014-04-13 22:42 ` redi at gcc dot gnu.org
                   ` (3 subsequent siblings)
  5 siblings, 0 replies; 7+ messages in thread
From: sambler at alumni dot nd.edu @ 2014-04-11  5:29 UTC (permalink / raw)
  To: gcc-bugs

http://gcc.gnu.org/bugzilla/show_bug.cgi?id=60662

--- Comment #2 from Stuart Ambler <sambler at alumni dot nd.edu> ---
Using gdb on my code, it appears that the immediate problem is caused by what
gthr-default.h and/or gthr-posix.h do to detect whether a program is
multi-threaded, which they seem to assume is ok as a precondition for using
call_once.  I think they do this with the code
#ifdef __GLIBC__
__gthrw2(__gthrw_(__pthread_key_create),
     __pthread_key_create,
     pthread_key_create)
# define GTHR_ACTIVE_PROXY    __gthrw_(__pthread_key_create)

Just after that code is

static inline int
__gthread_active_p (void)
{
  static void *const __gthread_active_ptr
    = __extension__ (void *) &GTHR_ACTIVE_PROXY;
  return __gthread_active_ptr != 0;
}

This function is called by __gthread_once, which if __gthread_active_p()
returns false, does nothing other than return -1, which results in call_once
throwing a system_error.

__pthread_key_create is a function in libpthread, which my gcc command line
links with.  It's possible to display the value of __gthread_active_ptr in
main, and it's 0 at a point before call_once is called and the error is thrown,
unless the this_thread::sleep_for code is uncommented, in which case
__gthread_active_ptr is not 0 and there is no problem.

It's not necessary for the this_thread::sleep to be executed to avoid the
problem.  Putting that line in a function in the same source file as main also
results in nonzero __gthread_active_ptr and no problem, even if the function is
never called.

I thought it might depend on order of loading the libraries and gave gcc the
-static option to hopefully have more control over that.  Giving gcc also -v
libpthread is listed before libstdc++.  But with static linking,
__gthread_active_ptr is 0 and the problem occurs whether or not the
this_thread::sleep_for is present.  So I gave up on static linking.

this_thread::sleep_for calls nano_sleep, which libpthread exports.  I don't
know much about the linux linker, but it seems that somehow the existence of
this call to nano_sleep, even if not executed, causes libpthread to be loaded
in a way that gives a nonzero value for __gthread_active_ptr when it is
checked.

Though it may work differently on different systems, it seems like the problem
may revolve around an assumption that call_once won't be called except by a
multi-threaded program, and a perhaps somewhat fragile way of determining
whether it's a multi-threaded program.

If you still think I should report it to Ubuntu, I will.

Thanks.


^ permalink raw reply	[flat|nested] 7+ messages in thread

* [Bug libstdc++/60662] simple use of call_once throws a system_error exception, but not if sleep_for is called beforehand
  2014-03-26  1:02 [Bug libstdc++/60662] New: simple use of call_once throws a system_error exception, but not if sleep_for is called beforehand sambler at alumni dot nd.edu
  2014-03-26 11:33 ` [Bug libstdc++/60662] " redi at gcc dot gnu.org
  2014-04-11  5:29 ` sambler at alumni dot nd.edu
@ 2014-04-13 22:42 ` redi at gcc dot gnu.org
  2014-09-19 13:17 ` redi at gcc dot gnu.org
                   ` (2 subsequent siblings)
  5 siblings, 0 replies; 7+ messages in thread
From: redi at gcc dot gnu.org @ 2014-04-13 22:42 UTC (permalink / raw)
  To: gcc-bugs

http://gcc.gnu.org/bugzilla/show_bug.cgi?id=60662

--- Comment #3 from Jonathan Wakely <redi at gcc dot gnu.org> ---
-lpthread (or more correctly, -pthread) should cause the executable to link to
libpthread.so for pthread_once, but for some reason on your system is
preferring the weak pthread_once symbol found in libc.so and so your executable
is not linked to libpthread.so

I do not think that is a GCC problem.


^ permalink raw reply	[flat|nested] 7+ messages in thread

* [Bug libstdc++/60662] simple use of call_once throws a system_error exception, but not if sleep_for is called beforehand
  2014-03-26  1:02 [Bug libstdc++/60662] New: simple use of call_once throws a system_error exception, but not if sleep_for is called beforehand sambler at alumni dot nd.edu
                   ` (2 preceding siblings ...)
  2014-04-13 22:42 ` redi at gcc dot gnu.org
@ 2014-09-19 13:17 ` redi at gcc dot gnu.org
  2020-11-23 14:00 ` redi at gcc dot gnu.org
  2020-11-23 15:50 ` redi at gcc dot gnu.org
  5 siblings, 0 replies; 7+ messages in thread
From: redi at gcc dot gnu.org @ 2014-09-19 13:17 UTC (permalink / raw)
  To: gcc-bugs

https://gcc.gnu.org/bugzilla/show_bug.cgi?id=60662

--- Comment #4 from Jonathan Wakely <redi at gcc dot gnu.org> ---
Probably related to PR 55394


^ permalink raw reply	[flat|nested] 7+ messages in thread

* [Bug libstdc++/60662] simple use of call_once throws a system_error exception, but not if sleep_for is called beforehand
  2014-03-26  1:02 [Bug libstdc++/60662] New: simple use of call_once throws a system_error exception, but not if sleep_for is called beforehand sambler at alumni dot nd.edu
                   ` (3 preceding siblings ...)
  2014-09-19 13:17 ` redi at gcc dot gnu.org
@ 2020-11-23 14:00 ` redi at gcc dot gnu.org
  2020-11-23 15:50 ` redi at gcc dot gnu.org
  5 siblings, 0 replies; 7+ messages in thread
From: redi at gcc dot gnu.org @ 2020-11-23 14:00 UTC (permalink / raw)
  To: gcc-bugs

https://gcc.gnu.org/bugzilla/show_bug.cgi?id=60662

Jonathan Wakely <redi at gcc dot gnu.org> changed:

           What    |Removed                     |Added
----------------------------------------------------------------------------
         Resolution|---                         |FIXED
             Status|UNCONFIRMED                 |RESOLVED
   Target Milestone|---                         |11.0

--- Comment #5 from Jonathan Wakely <redi at gcc dot gnu.org> ---
I am able to reproduce this on Ubuntu 13.10, and it can be fixed by using
-Wl,--no-as-needed before -lpthread which ensures the executable is linked to
libpthread.so even though the linker thinks it's not needed.

I'm not sure why this_thread::sleep_for (which just calls nanosleep) causes
libpthread.so to get linked in, but ldd shows that there is a libpthread.so
dependency with it.

This should be fixed in GCC 11 which no longer uses pthread_once for
std::call_once.

^ permalink raw reply	[flat|nested] 7+ messages in thread

* [Bug libstdc++/60662] simple use of call_once throws a system_error exception, but not if sleep_for is called beforehand
  2014-03-26  1:02 [Bug libstdc++/60662] New: simple use of call_once throws a system_error exception, but not if sleep_for is called beforehand sambler at alumni dot nd.edu
                   ` (4 preceding siblings ...)
  2020-11-23 14:00 ` redi at gcc dot gnu.org
@ 2020-11-23 15:50 ` redi at gcc dot gnu.org
  5 siblings, 0 replies; 7+ messages in thread
From: redi at gcc dot gnu.org @ 2020-11-23 15:50 UTC (permalink / raw)
  To: gcc-bugs

https://gcc.gnu.org/bugzilla/show_bug.cgi?id=60662

--- Comment #6 from Jonathan Wakely <redi at gcc dot gnu.org> ---
(In reply to Jonathan Wakely from comment #5)
> I'm not sure why this_thread::sleep_for (which just calls nanosleep) causes
> libpthread.so to get linked in, but ldd shows that there is a libpthread.so
> dependency with it.

nanosleep used to be defined in both libc.so and libpthread.so, so if you link
with -lpthread then the definition in libpthread.so will be found (because of
the order of libraries gcc passes to the linker) and you get a dependency on
libpthread.so

Recent versions of glibc only define it in libc.so

^ permalink raw reply	[flat|nested] 7+ messages in thread

end of thread, other threads:[~2020-11-23 15:50 UTC | newest]

Thread overview: 7+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2014-03-26  1:02 [Bug libstdc++/60662] New: simple use of call_once throws a system_error exception, but not if sleep_for is called beforehand sambler at alumni dot nd.edu
2014-03-26 11:33 ` [Bug libstdc++/60662] " redi at gcc dot gnu.org
2014-04-11  5:29 ` sambler at alumni dot nd.edu
2014-04-13 22:42 ` redi at gcc dot gnu.org
2014-09-19 13:17 ` redi at gcc dot gnu.org
2020-11-23 14:00 ` redi at gcc dot gnu.org
2020-11-23 15:50 ` redi at gcc dot gnu.org

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).