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:
parent
24219d3890
commit
33e3e24d74
6 changed files with 63 additions and 9 deletions
|
@ -30,6 +30,7 @@ see the files COPYING3 and COPYING.RUNTIME respectively. If not, see
|
|||
#include "coretypes.h"
|
||||
#include "tm.h"
|
||||
#include "libgcc_tm.h"
|
||||
#include "gthr.h"
|
||||
|
||||
#if defined(inhibit_libc)
|
||||
#define IN_LIBGCOV (-1)
|
||||
|
@ -705,6 +706,25 @@ __gcov_init (struct gcov_info *info)
|
|||
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
|
||||
far and reset it to zero. This avoids duplication or loss of the
|
||||
profile information gathered so far. */
|
||||
|
@ -714,6 +734,9 @@ __gcov_flush (void)
|
|||
{
|
||||
const struct gcov_info *gi_ptr;
|
||||
|
||||
init_mx_once ();
|
||||
__gthread_mutex_lock (&__gcov_flush_mx);
|
||||
|
||||
gcov_exit ();
|
||||
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 */
|
||||
|
@ -975,8 +1000,13 @@ __gcov_ior_profiler (gcov_type *counters, gcov_type value)
|
|||
pid_t
|
||||
__gcov_fork (void)
|
||||
{
|
||||
pid_t pid;
|
||||
extern __gthread_mutex_t __gcov_flush_mx;
|
||||
__gcov_flush ();
|
||||
return fork ();
|
||||
pid = fork ();
|
||||
if (pid == 0)
|
||||
__GTHREAD_MUTEX_INIT_FUNCTION (&__gcov_flush_mx);
|
||||
return pid;
|
||||
}
|
||||
#endif
|
||||
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue