Add DRD suppression patterns for races triggered by std::ostream
[valgrind.git] / drd / drd_libstdcxx_intercepts.c
blob354f8da25f7ccfe1bd86cbd9c53ad6565227f122
1 /*--------------------------------------------------------------------*/
2 /*--- Client-space code for DRD. drd_libstdcxx_intercepts.c ---*/
3 /*--------------------------------------------------------------------*/
5 /*
6 This file is part of DRD, a thread error detector.
8 Copyright (C) 2014-2017 Bart Van Assche <bvanassche@acm.org>.
10 This program is free software; you can redistribute it and/or
11 modify it under the terms of the GNU General Public License as
12 published by the Free Software Foundation; either version 2 of the
13 License, or (at your option) any later version.
15 This program is distributed in the hope that it will be useful, but
16 WITHOUT ANY WARRANTY; without even the implied warranty of
17 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
18 General Public License for more details.
20 You should have received a copy of the GNU General Public License
21 along with this program; if not, write to the Free Software
22 Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
23 02111-1307, USA.
25 The GNU General Public License is contained in the file COPYING.
28 /* ---------------------------------------------------------------------
29 ALL THE CODE IN THIS FILE RUNS ON THE SIMULATED CPU.
31 These functions are not called directly - they're the targets of code
32 redirection or load notifications (see pub_core_redir.h for info).
33 They're named weirdly so that the intercept code can find them when the
34 shared object is initially loaded.
36 Note that this filename has the "drd_" prefix because it can appear
37 in stack traces, and the "drd_" makes it a little clearer that it
38 originates from Valgrind.
39 ------------------------------------------------------------------ */
41 #include "drd_basics.h" /* DRD_() */
42 #include "drd_clientreq.h"
43 #include "pub_tool_redir.h" /* VG_WRAP_FUNCTION_ZZ() */
45 /* From <cxxabi.h> */
46 int __cxa_guard_acquire(void* guard);
47 void __cxa_guard_release(void* guard) __attribute__((__nothrow__));
48 void __cxa_guard_abort(void* guard) __attribute__((__nothrow__));
50 #define LIBSTDCXX_FUNC(ret_ty, zf, implf, argl_decl, argl) \
51 ret_ty VG_WRAP_FUNCTION_ZZ(VG_Z_LIBSTDCXX_SONAME,zf) argl_decl; \
52 ret_ty VG_WRAP_FUNCTION_ZZ(VG_Z_LIBSTDCXX_SONAME,zf) argl_decl \
53 { return implf argl; }
56 * Not inlining one of the intercept functions will cause the regression
57 * tests to fail because this would cause an additional stackfram to appear
58 * in the output. The __always_inline macro guarantees that inlining will
59 * happen, even when compiling with optimization disabled.
61 #undef __always_inline /* since already defined in <cdefs.h> */
62 #if __GNUC__ > 3 || __GNUC__ == 3 && __GNUC_MINOR__ >= 2
63 #define __always_inline __inline__ __attribute__((always_inline))
64 #else
65 #define __always_inline __inline__
66 #endif
68 static __always_inline
69 int __cxa_guard_acquire_intercept(void *guard)
71 int ret;
72 OrigFn fn;
73 VALGRIND_GET_ORIG_FN(fn);
74 VALGRIND_DO_CLIENT_REQUEST_STMT(VG_USERREQ__PRE_MUTEX_LOCK,
75 guard, mutex_type_cxa_guard, 0, 0, 0);
76 CALL_FN_W_W(ret, fn, guard);
77 VALGRIND_DO_CLIENT_REQUEST_STMT(VG_USERREQ__POST_MUTEX_LOCK,
78 guard, 1, 0, 0, 0);
79 if (ret == 0) {
80 VALGRIND_DO_CLIENT_REQUEST_STMT(VG_USERREQ__PRE_MUTEX_UNLOCK,
81 guard, mutex_type_cxa_guard, 0, 0, 0);
82 VALGRIND_DO_CLIENT_REQUEST_STMT(VG_USERREQ__POST_MUTEX_UNLOCK,
83 guard, 0, 0, 0, 0);
85 return ret;
88 LIBSTDCXX_FUNC(int, ZuZucxaZuguardZuacquire, __cxa_guard_acquire_intercept,
89 (void *guard), (guard));
90 LIBSTDCXX_FUNC(int, ZuZucxaZuguardZuacquireZAZACXXABIZu1Zd3,
91 __cxa_guard_acquire_intercept, (void *guard), (guard));
93 static __always_inline
94 void __cxa_guard_abort_release_intercept(void *guard)
96 int ret;
97 OrigFn fn;
98 VALGRIND_GET_ORIG_FN(fn);
99 VALGRIND_DO_CLIENT_REQUEST_STMT(VG_USERREQ__PRE_MUTEX_UNLOCK,
100 guard, mutex_type_cxa_guard, 0, 0, 0);
101 CALL_FN_W_W(ret, fn, guard);
102 VALGRIND_DO_CLIENT_REQUEST_STMT(VG_USERREQ__POST_MUTEX_UNLOCK,
103 guard, 0, 0, 0, 0);
106 LIBSTDCXX_FUNC(void, ZuZucxaZuguardZurelease,
107 __cxa_guard_abort_release_intercept, (void *guard), (guard));
108 LIBSTDCXX_FUNC(void, ZuZucxaZuguardZuabort,
109 __cxa_guard_abort_release_intercept, (void *guard), (guard));