Commit 33e3e24d by Richard Guenther Committed by Richard Biener

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
parent 24219d38
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.
......
...@@ -63,6 +63,7 @@ typedef struct timespec __gthread_time_t; ...@@ -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
...@@ -754,6 +755,14 @@ __gthread_mutex_init_function (__gthread_mutex_t *__mutex) ...@@ -754,6 +755,14 @@ __gthread_mutex_init_function (__gthread_mutex_t *__mutex)
#endif #endif
static inline int 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
__gthread_mutex_destroy (__gthread_mutex_t *__mutex) __gthread_mutex_destroy (__gthread_mutex_t *__mutex)
{ {
if (__gthread_active_p ()) if (__gthread_active_p ())
......
...@@ -36,6 +36,7 @@ typedef int __gthread_recursive_mutex_t; ...@@ -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))
......
...@@ -52,11 +52,12 @@ see the files COPYING3 and COPYING.RUNTIME respectively. If not, see ...@@ -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.
......
...@@ -30,6 +30,7 @@ see the files COPYING3 and COPYING.RUNTIME respectively. If not, see ...@@ -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) ...@@ -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) ...@@ -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) ...@@ -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) ...@@ -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
......
...@@ -47,11 +47,10 @@ static struct object *seen_objects; ...@@ -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) ...@@ -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. */
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment