diff mbox

libstdc++: Make it possible to annotate the shared pointer operations in the std::thread implementation

Message ID 33987586.92vJibue4B@linux
State New
Headers show

Commit Message

Bart Van Assche Dec. 23, 2011, 3:57 p.m. UTC
As documented in the libstdc++ manual, the shared pointer operations in
libstdc++ headers can be instrumented by defining the macros
_GLIBCXX_SYNCHRONIZATION_HAPPENS_BEFORE()/AFTER() and libstdc++ has to be
rebuilt in order to instrument the remaining shared pointer operations.
However, rebuilding libstdc++ is inconvenient. So let's move the thread
wrapper code from thread.cc into <thread>.

See also:
* http://gcc.gnu.org/onlinedocs/libstdc++/manual/debug.html.
* http://gcc.gnu.org/bugzilla/show_bug.cgi?id=51504.

Signed-off-by: Bart Van Assche <bvanassche@acm.org>

Comments

Paolo Carlini Dec. 23, 2011, 5:04 p.m. UTC | #1
Hi,

> As documented in the libstdc++ manual, the shared pointer operations in
> libstdc++ headers can be instrumented by defining the macros
> _GLIBCXX_SYNCHRONIZATION_HAPPENS_BEFORE()/AFTER() and libstdc++ has to be
> rebuilt in order to instrument the remaining shared pointer operations.
> However, rebuilding libstdc++ is inconvenient. So let's move the thread
> wrapper code from thread.cc into <thread>.

First, do you have already a Copyright assignment on file? It's a precondition for any non trivial contribution.

That said, please leave alone the baselines. Otherwise, Jon can comment on whether the reshuffling makes sense and would be safe from the Abi point of view.

Paolo
Bart Van Assche Dec. 24, 2011, 9:48 a.m. UTC | #2
On Fri, Dec 23, 2011 at 5:04 PM, Paolo Carlini <pcarlini@gmail.com> wrote:
> First, do you have already a Copyright assignment on file? It's a precondition for any non trivial contribution.

I've just started the procedure to get a copyright assignment form filed.

> That said, please leave alone the baselines. Otherwise, Jon can comment on whether the reshuffling makes
> sense and would be safe from the Abi point of view.

I'll repost the patch on the libstdc++ mailing list as Jon asked.

Bart.
Jonathan Wakely Dec. 24, 2011, 11:11 a.m. UTC | #3
On 24 December 2011 09:53, Bart Van Assche wrote:
> As documented in the libstdc++ manual, the shared pointer operations in
> libstdc++ headers can be instrumented by defining the macros
> _GLIBCXX_SYNCHRONIZATION_HAPPENS_BEFORE()/AFTER() and either libstdc++ or
> thread.cc has to be rebuilt in order to instrument the remaining shared
> pointer operations. However, rebuilding is inconvenient. So let's move the
> thread wrapper code from thread.cc into <thread>.

The patch is not OK because the function passed to pthread_create must
be extern "C" and a static member function is not extern "C"
(G++ fails to diagnose that error, but that's a long-standing bug:
http://gcc.gnu.org/PR2316 )

Apart from that, I prefer to keep the thread-launching logic in the
library rather than headers, as it allows us to change it more easily
and for users to benefit just by linking to a newer library rather
than recompiling. I don't think the data race detection macros are a
compelling reason to change that.

As I noted yesterday on PR 51504, you don't need to recompile the
whole library, you only need to recompile thread.cc with the data race
detection macros defined and link that object earlier in your linker
search path than libstdc++ to allow symbol interposition to replace
std::thread::_M_start_thread from the library with your instrument
version of that symbol.  I'll update the manual to say that.
Jonathan Wakely Dec. 24, 2011, 11:15 a.m. UTC | #4
On 24 December 2011 11:11, Jonathan Wakely wrote:
>
> Apart from that, I prefer to keep the thread-launching logic in the
> library rather than headers, as it allows us to change it more easily
> and for users to benefit just by linking to a newer library rather
> than recompiling. I don't think the data race detection macros are a
> compelling reason to change that.

An example improvement (which I'm working on) is to give better stack
traces when a process is terminated by an uncaught exception in a
function run by std::thread. If that's improved in the library, all
existing code using std::thread would get better stack traces just by
linking to a newer libstdc++.so, rather than having to recompile with
a newer GCC.
Bart Van Assche Dec. 24, 2011, 11:46 a.m. UTC | #5
On Sat, Dec 24, 2011 at 11:15 AM, Jonathan Wakely <jwakely.gcc@gmail.com> wrote:
> On 24 December 2011 11:11, Jonathan Wakely wrote:
>> Apart from that, I prefer to keep the thread-launching logic in the
>> library rather than headers, as it allows us to change it more easily
>> and for users to benefit just by linking to a newer library rather
>> than recompiling. I don't think the data race detection macros are a
>> compelling reason to change that.
>
> An example improvement (which I'm working on) is to give better stack
> traces when a process is terminated by an uncaught exception in a
> function run by std::thread. If that's improved in the library, all
> existing code using std::thread would get better stack traces just by
> linking to a newer libstdc++.so, rather than having to recompile with
> a newer GCC.

Would it be acceptable to replace the
_GLIBCXX_SYNCHRONIZATION_HAPPENS_BEFORE() and ..._AFTER() macros by
something like this:

  if (pf) (*pf)(addr, before_or_after_flag)

where pf is a function pointer that is NULL by default and can be set
by libstdc++ users. That approach would also avoid that libstdc++ has
to be recompiled in order to instrument reference count decrementing
for data race detectors.

Bart.
Jonathan Wakely Dec. 24, 2011, 12:05 p.m. UTC | #6
On 24 December 2011 11:46, Bart Van Assche wrote:
>
> Would it be acceptable to replace the
> _GLIBCXX_SYNCHRONIZATION_HAPPENS_BEFORE() and ..._AFTER() macros by
> something like this:
>
>  if (pf) (*pf)(addr, before_or_after_flag)
>
> where pf is a function pointer that is NULL by default and can be set
> by libstdc++ users. That approach would also avoid that libstdc++ has
> to be recompiled in order to instrument reference count decrementing
> for data race detectors.

I think the cost of checking that on every ref-count update would be
too high for the vast majority of users who don't use race detectors.
A macro has zero cost if it's not used, and even people using race
detectors don't want them enabled all the time. As I said, you don't
need to recompile the whole library to instrument the parts that are
affected, only specific objects.  I think the right thing to do is
identify the parts that need to be recompiled and document how to do
just that.
Bart Van Assche Dec. 24, 2011, 12:14 p.m. UTC | #7
On Sat, Dec 24, 2011 at 12:05 PM, Jonathan Wakely <jwakely.gcc@gmail.com> wrote:
> On 24 December 2011 11:46, Bart Van Assche wrote:
>> Would it be acceptable to replace the
>> _GLIBCXX_SYNCHRONIZATION_HAPPENS_BEFORE() and ..._AFTER() macros by
>> something like this:
>>
>>  if (pf) (*pf)(addr, before_or_after_flag)
>>
>> where pf is a function pointer that is NULL by default and can be set
>> by libstdc++ users. That approach would also avoid that libstdc++ has
>> to be recompiled in order to instrument reference count decrementing
>> for data race detectors.
>
> I think the cost of checking that on every ref-count update would be
> too high for the vast majority of users who don't use race detectors.
> A macro has zero cost if it's not used, and even people using race
> detectors don't want them enabled all the time. As I said, you don't
> need to recompile the whole library to instrument the parts that are
> affected, only specific objects.  I think the right thing to do is
> identify the parts that need to be recompiled and document how to do
> just that.

Would it be technically possible to implement a binary patching
approach in a user space shared library similar to the binary patching
technique used in the kprobe implementation in the Linux kernel ?

For more information, see also
http://git.kernel.org/?p=linux/kernel/git/next/linux-next.git;a=blob;f=Documentation/kprobes.txt.

Bart.

Bart.
Jonathan Wakely Dec. 24, 2011, 12:50 p.m. UTC | #8
On 24 December 2011 12:14, Bart Van Assche wrote:
>
> Would it be technically possible to implement a binary patching
> approach in a user space shared library similar to the binary patching
> technique used in the kprobe implementation in the Linux kernel ?
>
> For more information, see also
> http://git.kernel.org/?p=linux/kernel/git/next/linux-next.git;a=blob;f=Documentation/kprobes.txt.


I don't know, but honestly, IMHO the use case of race detectors is not
important enough to bother. Recompiling the required objects and
linking to them is just not that difficult.

I think the guideline of "you don't pay for what you don't use" must
apply to any changes made for race detection in the library.  While
runtime cost is the most important, maintenance cost also matters.  We
accepted the patch adding the macros to the library sources because
they add no cost for most users and allow those who care to use race
detectors (albeit with some minor hassle of recompiling some source
files).  You are now trying to turn something where we said "sure, why
not, let's include it" into something far more intrusive that is not
stritly necessary (just more convenient) and of no value for most
users.

I would support adding a configure option such as
--enable-libstdcxx-race-detection={drd,tsan,...} which automatically
built and installed a variant of the library using the specified race
detector, similar to the --enable-libstdcxx-debug option which builds
an unoptimized, unstripped libstdc++.so and places it in
${libdir}/debug/

One of the values for the option could be "user" which would make the
relevant libstdc++ files include a user-defined header, which could
define the macros to whatever you want, including calling a global
function pointer which may or may not be set.
diff mbox

Patch

Index: libstdc++-v3/src/thread.cc
===================================================================
--- libstdc++-v3/src/thread.cc	(revision 182271)
+++ libstdc++-v3/src/thread.cc	(working copy)
@@ -59,28 +59,6 @@  static inline int get_nprocs()
 
 namespace std _GLIBCXX_VISIBILITY(default)
 {
-  namespace
-  {
-    extern "C" void*
-    execute_native_thread_routine(void* __p)
-    {
-      thread::_Impl_base* __t = static_cast<thread::_Impl_base*>(__p);
-      thread::__shared_base_type __local;
-      __local.swap(__t->_M_this_ptr);
-
-      __try
-	{
-	  __t->_M_run();
-	}
-      __catch(...)
-	{
-	  std::terminate();
-	}
-
-      return 0;
-    }
-  }
-
 _GLIBCXX_BEGIN_NAMESPACE_VERSION
 
   void
@@ -114,12 +92,17 @@  _GLIBCXX_BEGIN_NAMESPACE_VERSION
   void
   thread::_M_start_thread(__shared_base_type __b)
   {
+      _M_start_thread(__b, &_M_entry);
+  }
+
+  void
+  thread::_M_start_thread(__shared_base_type __b, void* (*__pf)(void*))
+  {
     if (!__gthread_active_p())
       __throw_system_error(int(errc::operation_not_permitted));
 
     __b->_M_this_ptr = __b;
-    int __e = __gthread_create(&_M_id._M_thread,
-			       &execute_native_thread_routine, __b.get());
+    int __e = __gthread_create(&_M_id._M_thread, __pf, __b.get());
     if (__e)
     {
       __b->_M_this_ptr.reset();
Index: libstdc++-v3/include/std/thread
===================================================================
--- libstdc++-v3/include/std/thread	(revision 182271)
+++ libstdc++-v3/include/std/thread	(working copy)
@@ -132,7 +132,8 @@  _GLIBCXX_BEGIN_NAMESPACE_VERSION
       {
         _M_start_thread(_M_make_routine(std::__bind_simple(
                 std::forward<_Callable>(__f),
-                std::forward<_Args>(__args)...)));
+                std::forward<_Args>(__args)...)),
+                        &thread::_M_entry);
       }
 
     ~thread()
@@ -180,9 +181,30 @@  _GLIBCXX_BEGIN_NAMESPACE_VERSION
     hardware_concurrency() noexcept;
 
   private:
+    static void* _M_entry(void* __p)
+    {
+      thread::_Impl_base* __t = static_cast<thread::_Impl_base*>(__p);
+      thread::__shared_base_type __local;
+      __local.swap(__t->_M_this_ptr);
+  
+      __try
+        {
+          __t->_M_run();
+        }
+      __catch(...)
+        {
+          std::terminate();
+        }
+  
+      return 0;
+    }
+
     void
     _M_start_thread(__shared_base_type);
 
+    void
+    _M_start_thread(__shared_base_type, void* (*)(void*));
+
     template<typename _Callable>
       shared_ptr<_Impl<_Callable>>
       _M_make_routine(_Callable&& __f)
Index: libstdc++-v3/config/abi/post/s390-linux-gnu/baseline_symbols.txt
===================================================================
--- libstdc++-v3/config/abi/post/s390-linux-gnu/baseline_symbols.txt	(revision 182271)
+++ libstdc++-v3/config/abi/post/s390-linux-gnu/baseline_symbols.txt	(working copy)
@@ -2145,6 +2145,7 @@  FUNC:_ZNSt6localeD1Ev@@GLIBCXX_3.4
 FUNC:_ZNSt6localeD2Ev@@GLIBCXX_3.4
 FUNC:_ZNSt6localeaSERKS_@@GLIBCXX_3.4
 FUNC:_ZNSt6thread15_M_start_threadESt10shared_ptrINS_10_Impl_baseEE@@GLIBCXX_3.4.11
+FUNC:_ZNSt6thread15_M_start_threadESt10shared_ptrINS_10_Impl_baseEEPFPvS3_E@@GLIBCXX_3.4.17
 FUNC:_ZNSt6thread4joinEv@@GLIBCXX_3.4.11
 FUNC:_ZNSt6thread6detachEv@@GLIBCXX_3.4.11
 FUNC:_ZNSt7codecvtIcc11__mbstate_tEC1EP15__locale_structm@@GLIBCXX_3.4
Index: libstdc++-v3/config/abi/post/x86_64-linux-gnu/baseline_symbols.txt
===================================================================
--- libstdc++-v3/config/abi/post/x86_64-linux-gnu/baseline_symbols.txt	(revision 182271)
+++ libstdc++-v3/config/abi/post/x86_64-linux-gnu/baseline_symbols.txt	(working copy)
@@ -1955,6 +1955,7 @@  FUNC:_ZNSt6localeD1Ev@@GLIBCXX_3.4
 FUNC:_ZNSt6localeD2Ev@@GLIBCXX_3.4
 FUNC:_ZNSt6localeaSERKS_@@GLIBCXX_3.4
 FUNC:_ZNSt6thread15_M_start_threadESt10shared_ptrINS_10_Impl_baseEE@@GLIBCXX_3.4.11
+FUNC:_ZNSt6thread15_M_start_threadESt10shared_ptrINS_10_Impl_baseEEPFPvS3_E@@GLIBCXX_3.4.17
 FUNC:_ZNSt6thread4joinEv@@GLIBCXX_3.4.11
 FUNC:_ZNSt6thread6detachEv@@GLIBCXX_3.4.11
 FUNC:_ZNSt7codecvtIcc11__mbstate_tEC1EP15__locale_structm@@GLIBCXX_3.4
Index: libstdc++-v3/config/abi/post/ia64-linux-gnu/baseline_symbols.txt
===================================================================
--- libstdc++-v3/config/abi/post/ia64-linux-gnu/baseline_symbols.txt	(revision 182271)
+++ libstdc++-v3/config/abi/post/ia64-linux-gnu/baseline_symbols.txt	(working copy)
@@ -1852,6 +1852,7 @@  FUNC:_ZNSt6localeD1Ev@@GLIBCXX_3.4
 FUNC:_ZNSt6localeD2Ev@@GLIBCXX_3.4
 FUNC:_ZNSt6localeaSERKS_@@GLIBCXX_3.4
 FUNC:_ZNSt6thread15_M_start_threadESt10shared_ptrINS_10_Impl_baseEE@@GLIBCXX_3.4.11
+FUNC:_ZNSt6thread15_M_start_threadESt10shared_ptrINS_10_Impl_baseEEPFPvS3_E@@GLIBCXX_3.4.17
 FUNC:_ZNSt6thread4joinEv@@GLIBCXX_3.4.11
 FUNC:_ZNSt6thread6detachEv@@GLIBCXX_3.4.11
 FUNC:_ZNSt7codecvtIcc11__mbstate_tEC1EP15__locale_structm@@GLIBCXX_3.4
Index: libstdc++-v3/config/abi/post/sparc-linux-gnu/baseline_symbols.txt
===================================================================
--- libstdc++-v3/config/abi/post/sparc-linux-gnu/baseline_symbols.txt	(revision 182271)
+++ libstdc++-v3/config/abi/post/sparc-linux-gnu/baseline_symbols.txt	(working copy)
@@ -2145,6 +2145,7 @@  FUNC:_ZNSt6localeD1Ev@@GLIBCXX_3.4
 FUNC:_ZNSt6localeD2Ev@@GLIBCXX_3.4
 FUNC:_ZNSt6localeaSERKS_@@GLIBCXX_3.4
 FUNC:_ZNSt6thread15_M_start_threadESt10shared_ptrINS_10_Impl_baseEE@@GLIBCXX_3.4.11
+FUNC:_ZNSt6thread15_M_start_threadESt10shared_ptrINS_10_Impl_baseEEPFPvS3_E@@GLIBCXX_3.4.17
 FUNC:_ZNSt6thread4joinEv@@GLIBCXX_3.4.11
 FUNC:_ZNSt6thread6detachEv@@GLIBCXX_3.4.11
 FUNC:_ZNSt7codecvtIcc11__mbstate_tEC1EP15__locale_structj@@GLIBCXX_3.4
Index: libstdc++-v3/config/abi/post/powerpc-linux-gnu/baseline_symbols.txt
===================================================================
--- libstdc++-v3/config/abi/post/powerpc-linux-gnu/baseline_symbols.txt	(revision 182271)
+++ libstdc++-v3/config/abi/post/powerpc-linux-gnu/baseline_symbols.txt	(working copy)
@@ -2145,6 +2145,7 @@  FUNC:_ZNSt6localeD1Ev@@GLIBCXX_3.4
 FUNC:_ZNSt6localeD2Ev@@GLIBCXX_3.4
 FUNC:_ZNSt6localeaSERKS_@@GLIBCXX_3.4
 FUNC:_ZNSt6thread15_M_start_threadESt10shared_ptrINS_10_Impl_baseEE@@GLIBCXX_3.4.11
+FUNC:_ZNSt6thread15_M_start_threadESt10shared_ptrINS_10_Impl_baseEEPFPvS3_E@@GLIBCXX_3.4.17
 FUNC:_ZNSt6thread4joinEv@@GLIBCXX_3.4.11
 FUNC:_ZNSt6thread6detachEv@@GLIBCXX_3.4.11
 FUNC:_ZNSt7codecvtIcc11__mbstate_tEC1EP15__locale_structj@@GLIBCXX_3.4
Index: libstdc++-v3/config/abi/post/mips64-linux-gnu/baseline_symbols.txt
===================================================================
--- libstdc++-v3/config/abi/post/mips64-linux-gnu/baseline_symbols.txt	(revision 182271)
+++ libstdc++-v3/config/abi/post/mips64-linux-gnu/baseline_symbols.txt	(working copy)
@@ -1852,6 +1852,7 @@  FUNC:_ZNSt6localeD1Ev@@GLIBCXX_3.4
 FUNC:_ZNSt6localeD2Ev@@GLIBCXX_3.4
 FUNC:_ZNSt6localeaSERKS_@@GLIBCXX_3.4
 FUNC:_ZNSt6thread15_M_start_threadESt10shared_ptrINS_10_Impl_baseEE@@GLIBCXX_3.4.11
+FUNC:_ZNSt6thread15_M_start_threadESt10shared_ptrINS_10_Impl_baseEEPFPvS3_E@@GLIBCXX_3.4.17
 FUNC:_ZNSt6thread4joinEv@@GLIBCXX_3.4.11
 FUNC:_ZNSt6thread6detachEv@@GLIBCXX_3.4.11
 FUNC:_ZNSt7codecvtIcc11__mbstate_tEC1EP15__locale_structj@@GLIBCXX_3.4
Index: libstdc++-v3/config/abi/post/alpha-linux-gnu/baseline_symbols.txt
===================================================================
--- libstdc++-v3/config/abi/post/alpha-linux-gnu/baseline_symbols.txt	(revision 182271)
+++ libstdc++-v3/config/abi/post/alpha-linux-gnu/baseline_symbols.txt	(working copy)
@@ -2145,6 +2145,7 @@  FUNC:_ZNSt6localeD1Ev@@GLIBCXX_3.4
 FUNC:_ZNSt6localeD2Ev@@GLIBCXX_3.4
 FUNC:_ZNSt6localeaSERKS_@@GLIBCXX_3.4
 FUNC:_ZNSt6thread15_M_start_threadESt10shared_ptrINS_10_Impl_baseEE@@GLIBCXX_3.4.11
+FUNC:_ZNSt6thread15_M_start_threadESt10shared_ptrINS_10_Impl_baseEEPFPvS3_E@@GLIBCXX_3.4.17
 FUNC:_ZNSt6thread4joinEv@@GLIBCXX_3.4.11
 FUNC:_ZNSt6thread6detachEv@@GLIBCXX_3.4.11
 FUNC:_ZNSt7codecvtIcc11__mbstate_tEC1EP15__locale_structm@@GLIBCXX_3.4
Index: libstdc++-v3/config/abi/post/s390x-linux-gnu/baseline_symbols.txt
===================================================================
--- libstdc++-v3/config/abi/post/s390x-linux-gnu/baseline_symbols.txt	(revision 182271)
+++ libstdc++-v3/config/abi/post/s390x-linux-gnu/baseline_symbols.txt	(working copy)
@@ -2145,6 +2145,7 @@  FUNC:_ZNSt6localeD1Ev@@GLIBCXX_3.4
 FUNC:_ZNSt6localeD2Ev@@GLIBCXX_3.4
 FUNC:_ZNSt6localeaSERKS_@@GLIBCXX_3.4
 FUNC:_ZNSt6thread15_M_start_threadESt10shared_ptrINS_10_Impl_baseEE@@GLIBCXX_3.4.11
+FUNC:_ZNSt6thread15_M_start_threadESt10shared_ptrINS_10_Impl_baseEEPFPvS3_E@@GLIBCXX_3.4.17
 FUNC:_ZNSt6thread4joinEv@@GLIBCXX_3.4.11
 FUNC:_ZNSt6thread6detachEv@@GLIBCXX_3.4.11
 FUNC:_ZNSt7codecvtIcc11__mbstate_tEC1EP15__locale_structm@@GLIBCXX_3.4
Index: libstdc++-v3/config/abi/post/i386-linux-gnu/baseline_symbols.txt
===================================================================
--- libstdc++-v3/config/abi/post/i386-linux-gnu/baseline_symbols.txt	(revision 182271)
+++ libstdc++-v3/config/abi/post/i386-linux-gnu/baseline_symbols.txt	(working copy)
@@ -1955,6 +1955,7 @@  FUNC:_ZNSt6localeD1Ev@@GLIBCXX_3.4
 FUNC:_ZNSt6localeD2Ev@@GLIBCXX_3.4
 FUNC:_ZNSt6localeaSERKS_@@GLIBCXX_3.4
 FUNC:_ZNSt6thread15_M_start_threadESt10shared_ptrINS_10_Impl_baseEE@@GLIBCXX_3.4.11
+FUNC:_ZNSt6thread15_M_start_threadESt10shared_ptrINS_10_Impl_baseEEPFPvS3_E@@GLIBCXX_3.4.17
 FUNC:_ZNSt6thread4joinEv@@GLIBCXX_3.4.11
 FUNC:_ZNSt6thread6detachEv@@GLIBCXX_3.4.11
 FUNC:_ZNSt7codecvtIcc11__mbstate_tEC1EP15__locale_structj@@GLIBCXX_3.4
Index: libstdc++-v3/config/abi/post/powerpc64-linux-gnu/baseline_symbols.txt
===================================================================
--- libstdc++-v3/config/abi/post/powerpc64-linux-gnu/baseline_symbols.txt	(revision 182271)
+++ libstdc++-v3/config/abi/post/powerpc64-linux-gnu/baseline_symbols.txt	(working copy)
@@ -2145,6 +2145,7 @@  FUNC:_ZNSt6localeD1Ev@@GLIBCXX_3.4
 FUNC:_ZNSt6localeD2Ev@@GLIBCXX_3.4
 FUNC:_ZNSt6localeaSERKS_@@GLIBCXX_3.4
 FUNC:_ZNSt6thread15_M_start_threadESt10shared_ptrINS_10_Impl_baseEE@@GLIBCXX_3.4.11
+FUNC:_ZNSt6thread15_M_start_threadESt10shared_ptrINS_10_Impl_baseEEPFPvS3_E@@GLIBCXX_3.4.17
 FUNC:_ZNSt6thread4joinEv@@GLIBCXX_3.4.11
 FUNC:_ZNSt6thread6detachEv@@GLIBCXX_3.4.11
 FUNC:_ZNSt7codecvtIcc11__mbstate_tEC1EP15__locale_structm@@GLIBCXX_3.4
Index: libstdc++-v3/config/abi/post/solaris2.10/baseline_symbols.txt
===================================================================
--- libstdc++-v3/config/abi/post/solaris2.10/baseline_symbols.txt	(revision 182271)
+++ libstdc++-v3/config/abi/post/solaris2.10/baseline_symbols.txt	(working copy)
@@ -1920,6 +1920,7 @@  FUNC:_ZNSt6localeD1Ev@@GLIBCXX_3.4
 FUNC:_ZNSt6localeD2Ev@@GLIBCXX_3.4
 FUNC:_ZNSt6localeaSERKS_@@GLIBCXX_3.4
 FUNC:_ZNSt6thread15_M_start_threadESt10shared_ptrINS_10_Impl_baseEE@@GLIBCXX_3.4.11
+FUNC:_ZNSt6thread15_M_start_threadESt10shared_ptrINS_10_Impl_baseEEPFPvS3_E@@GLIBCXX_3.4.17
 FUNC:_ZNSt6thread4joinEv@@GLIBCXX_3.4.11
 FUNC:_ZNSt6thread6detachEv@@GLIBCXX_3.4.11
 FUNC:_ZNSt7codecvtIcc11__mbstate_tEC1EPij@@GLIBCXX_3.4
Index: libstdc++-v3/config/abi/post/i486-linux-gnu/baseline_symbols.txt
===================================================================
--- libstdc++-v3/config/abi/post/i486-linux-gnu/baseline_symbols.txt	(revision 182271)
+++ libstdc++-v3/config/abi/post/i486-linux-gnu/baseline_symbols.txt	(working copy)
@@ -1955,6 +1955,7 @@  FUNC:_ZNSt6localeD1Ev@@GLIBCXX_3.4
 FUNC:_ZNSt6localeD2Ev@@GLIBCXX_3.4
 FUNC:_ZNSt6localeaSERKS_@@GLIBCXX_3.4
 FUNC:_ZNSt6thread15_M_start_threadESt10shared_ptrINS_10_Impl_baseEE@@GLIBCXX_3.4.11
+FUNC:_ZNSt6thread15_M_start_threadESt10shared_ptrINS_10_Impl_baseEEPFPvS3_E@@GLIBCXX_3.4.17
 FUNC:_ZNSt6thread4joinEv@@GLIBCXX_3.4.11
 FUNC:_ZNSt6thread6detachEv@@GLIBCXX_3.4.11
 FUNC:_ZNSt7codecvtIcc11__mbstate_tEC1EP15__locale_structj@@GLIBCXX_3.4
Index: libstdc++-v3/config/abi/pre/gnu.ver
===================================================================
--- libstdc++-v3/config/abi/pre/gnu.ver	(revision 182271)
+++ libstdc++-v3/config/abi/pre/gnu.ver	(working copy)
@@ -1307,6 +1307,9 @@  GLIBCXX_3.4.17 {
     # std::wstring::pop_back()
     _ZNSbIwSt11char_traitsIwESaIwEE8pop_backEv;
 
+    # std::thread
+    _ZNSt6thread15_M_start_threadESt10shared_ptrINS_10_Impl_baseEEPFPvS3_E;
+
 } GLIBCXX_3.4.16;
 
 # Symbols in the support library (libsupc++) have their own tag.