re PR gcov-profile/49484 (gcov crash if two(or more) forks happen at the same time)

2012-03-12  Richard Guenther  <rguenther@suse.de>

	* gthr.h (__GTHREAD_MUTEX_INIT_FUNCTION): Adjust specification.
	* gthr-posix.h (__GTHREAD_MUTEX_INIT_FUNCTION): Define.
	(__gthread_mutex_init_function): New function.
	* gthr-single.h (__GTHREAD_MUTEX_INIT_FUNCTION): Define.

	PR gcov/49484
	* libgcov.c: Include gthr.h.
	(__gcov_flush_mx): New global variable.
	(init_mx, init_mx_once): New functions.
	(__gcov_flush): Protect self with a mutex.
	(__gcov_fork): Re-initialize mutex after forking.
	* unwind-dw2-fde.c: Change condition under which to use
	__GTHREAD_MUTEX_INIT_FUNCTION.

From-SVN: r185231
This commit is contained in:
Richard Guenther 2012-03-12 14:23:27 +00:00 committed by Richard Biener
parent 24219d3890
commit 33e3e24d74
6 changed files with 63 additions and 9 deletions

View file

@ -1,3 +1,19 @@
2012-03-12 Richard Guenther <rguenther@suse.de>
* gthr.h (__GTHREAD_MUTEX_INIT_FUNCTION): Adjust specification.
* gthr-posix.h (__GTHREAD_MUTEX_INIT_FUNCTION): Define.
(__gthread_mutex_init_function): New function.
* gthr-single.h (__GTHREAD_MUTEX_INIT_FUNCTION): Define.
PR gcov/49484
* libgcov.c: Include gthr.h.
(__gcov_flush_mx): New global variable.
(init_mx, init_mx_once): New functions.
(__gcov_flush): Protect self with a mutex.
(__gcov_fork): Re-initialize mutex after forking.
* unwind-dw2-fde.c: Change condition under which to use
__GTHREAD_MUTEX_INIT_FUNCTION.
2012-03-12 Tristan Gingold <gingold@adacore.com> 2012-03-12 Tristan Gingold <gingold@adacore.com>
* config/alpha/t-vms: Define HOST_LIBGCC2_CFLAGS. * config/alpha/t-vms: Define HOST_LIBGCC2_CFLAGS.

View file

@ -63,6 +63,7 @@ typedef struct timespec __gthread_time_t;
#define __GTHREAD_HAS_COND 1 #define __GTHREAD_HAS_COND 1
#define __GTHREAD_MUTEX_INIT PTHREAD_MUTEX_INITIALIZER #define __GTHREAD_MUTEX_INIT PTHREAD_MUTEX_INITIALIZER
#define __GTHREAD_MUTEX_INIT_FUNCTION __gthread_mutex_init_function
#define __GTHREAD_ONCE_INIT PTHREAD_ONCE_INIT #define __GTHREAD_ONCE_INIT PTHREAD_ONCE_INIT
#if defined(PTHREAD_RECURSIVE_MUTEX_INITIALIZER) #if defined(PTHREAD_RECURSIVE_MUTEX_INITIALIZER)
#define __GTHREAD_RECURSIVE_MUTEX_INIT PTHREAD_RECURSIVE_MUTEX_INITIALIZER #define __GTHREAD_RECURSIVE_MUTEX_INIT PTHREAD_RECURSIVE_MUTEX_INITIALIZER
@ -753,6 +754,14 @@ __gthread_mutex_init_function (__gthread_mutex_t *__mutex)
} }
#endif #endif
static inline int
__gthread_mutex_init_function (__gthread_mutex_t *__mutex)
{
if (__gthread_active_p ())
return __gthrw_(pthread_mutex_init) (__mutex, NULL);
return 0;
}
static inline int static inline int
__gthread_mutex_destroy (__gthread_mutex_t *__mutex) __gthread_mutex_destroy (__gthread_mutex_t *__mutex)
{ {

View file

@ -36,6 +36,7 @@ typedef int __gthread_recursive_mutex_t;
#define __GTHREAD_ONCE_INIT 0 #define __GTHREAD_ONCE_INIT 0
#define __GTHREAD_MUTEX_INIT 0 #define __GTHREAD_MUTEX_INIT 0
#define __GTHREAD_MUTEX_INIT_FUNCTION (mx)
#define __GTHREAD_RECURSIVE_MUTEX_INIT 0 #define __GTHREAD_RECURSIVE_MUTEX_INIT 0
#define UNUSED __attribute__((unused)) #define UNUSED __attribute__((unused))

View file

@ -52,11 +52,12 @@ see the files COPYING3 and COPYING.RUNTIME respectively. If not, see
to initialize __gthread_mutex_t to get a fast to initialize __gthread_mutex_t to get a fast
non-recursive mutex. non-recursive mutex.
__GTHREAD_MUTEX_INIT_FUNCTION __GTHREAD_MUTEX_INIT_FUNCTION
some systems can't initialize a mutex without a to initialize __gthread_mutex_t to get a fast
function call. On such systems, define this to a non-recursive mutex.
function which looks like this: Define this to a function which looks like this:
void __GTHREAD_MUTEX_INIT_FUNCTION (__gthread_mutex_t *) void __GTHREAD_MUTEX_INIT_FUNCTION (__gthread_mutex_t *)
Don't define __GTHREAD_MUTEX_INIT in this case Some systems can't initialize a mutex without a
function call. Don't define __GTHREAD_MUTEX_INIT in this case.
__GTHREAD_RECURSIVE_MUTEX_INIT __GTHREAD_RECURSIVE_MUTEX_INIT
__GTHREAD_RECURSIVE_MUTEX_INIT_FUNCTION __GTHREAD_RECURSIVE_MUTEX_INIT_FUNCTION
as above, but for a recursive mutex. as above, but for a recursive mutex.

View file

@ -30,6 +30,7 @@ see the files COPYING3 and COPYING.RUNTIME respectively. If not, see
#include "coretypes.h" #include "coretypes.h"
#include "tm.h" #include "tm.h"
#include "libgcc_tm.h" #include "libgcc_tm.h"
#include "gthr.h"
#if defined(inhibit_libc) #if defined(inhibit_libc)
#define IN_LIBGCOV (-1) #define IN_LIBGCOV (-1)
@ -705,6 +706,25 @@ __gcov_init (struct gcov_info *info)
info->version = 0; info->version = 0;
} }
#ifdef __GTHREAD_MUTEX_INIT
ATTRIBUTE_HIDDEN __gthread_mutex_t __gcov_flush_mx = __GTHREAD_MUTEX_INIT;
#define init_mx_once()
#else
__gthread_mutex_t __gcov_flush_mx ATTRIBUTE_HIDDEN;
static void
init_mx (void)
{
__GTHREAD_MUTEX_INIT_FUNCTION (&mx);
}
static void
init_mx_once (void)
{
static __gthread_once_t once = __GTHREAD_ONCE_INIT;
__gthread_once (&once, init_mx);
}
#endif
/* Called before fork or exec - write out profile information gathered so /* Called before fork or exec - write out profile information gathered so
far and reset it to zero. This avoids duplication or loss of the far and reset it to zero. This avoids duplication or loss of the
profile information gathered so far. */ profile information gathered so far. */
@ -714,6 +734,9 @@ __gcov_flush (void)
{ {
const struct gcov_info *gi_ptr; const struct gcov_info *gi_ptr;
init_mx_once ();
__gthread_mutex_lock (&__gcov_flush_mx);
gcov_exit (); gcov_exit ();
for (gi_ptr = gcov_list; gi_ptr; gi_ptr = gi_ptr->next) for (gi_ptr = gcov_list; gi_ptr; gi_ptr = gi_ptr->next)
{ {
@ -737,6 +760,8 @@ __gcov_flush (void)
} }
} }
} }
__gthread_mutex_unlock (&__gcov_flush_mx);
} }
#endif /* L_gcov */ #endif /* L_gcov */
@ -975,8 +1000,13 @@ __gcov_ior_profiler (gcov_type *counters, gcov_type value)
pid_t pid_t
__gcov_fork (void) __gcov_fork (void)
{ {
pid_t pid;
extern __gthread_mutex_t __gcov_flush_mx;
__gcov_flush (); __gcov_flush ();
return fork (); pid = fork ();
if (pid == 0)
__GTHREAD_MUTEX_INIT_FUNCTION (&__gcov_flush_mx);
return pid;
} }
#endif #endif

View file

@ -47,11 +47,10 @@ static struct object *seen_objects;
#ifdef __GTHREAD_MUTEX_INIT #ifdef __GTHREAD_MUTEX_INIT
static __gthread_mutex_t object_mutex = __GTHREAD_MUTEX_INIT; static __gthread_mutex_t object_mutex = __GTHREAD_MUTEX_INIT;
#define init_object_mutex_once()
#else #else
static __gthread_mutex_t object_mutex; static __gthread_mutex_t object_mutex;
#endif
#ifdef __GTHREAD_MUTEX_INIT_FUNCTION
static void static void
init_object_mutex (void) init_object_mutex (void)
{ {
@ -64,8 +63,6 @@ init_object_mutex_once (void)
static __gthread_once_t once = __GTHREAD_ONCE_INIT; static __gthread_once_t once = __GTHREAD_ONCE_INIT;
__gthread_once (&once, init_object_mutex); __gthread_once (&once, init_object_mutex);
} }
#else
#define init_object_mutex_once()
#endif #endif
/* Called from crtbegin.o to register the unwind info for an object. */ /* Called from crtbegin.o to register the unwind info for an object. */