This is the mail archive of the
gcc-bugs@gcc.gnu.org
mailing list for the GCC project.
[Bug libstdc++/60662] simple use of call_once throws a system_error exception, but not if sleep_for is called beforehand
- From: "sambler at alumni dot nd.edu" <gcc-bugzilla at gcc dot gnu dot org>
- To: gcc-bugs at gcc dot gnu dot org
- Date: Fri, 11 Apr 2014 05:29:24 +0000
- Subject: [Bug libstdc++/60662] simple use of call_once throws a system_error exception, but not if sleep_for is called beforehand
- Auto-submitted: auto-generated
- References: <bug-60662-4 at http dot gcc dot gnu dot org/bugzilla/>
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 *) >HR_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.