From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: by sourceware.org (Postfix, from userid 48) id 419CE385780E; Mon, 9 Nov 2020 09:57:01 +0000 (GMT) DKIM-Filter: OpenDKIM Filter v2.11.0 sourceware.org 419CE385780E From: "marxin at gcc dot gnu.org" To: gcc-bugs@gcc.gnu.org Subject: [Bug gcov-profile/97461] [11 Regression] allocate_gcov_kvp() deadlocks in firefox LTO+PGO build (overridden malloc() recursion) Date: Mon, 09 Nov 2020 09:57:01 +0000 X-Bugzilla-Reason: CC X-Bugzilla-Type: changed X-Bugzilla-Watch-Reason: None X-Bugzilla-Product: gcc X-Bugzilla-Component: gcov-profile X-Bugzilla-Version: 11.0 X-Bugzilla-Keywords: X-Bugzilla-Severity: normal X-Bugzilla-Who: marxin at gcc dot gnu.org X-Bugzilla-Status: NEW X-Bugzilla-Resolution: X-Bugzilla-Priority: P1 X-Bugzilla-Assigned-To: marxin at gcc dot gnu.org X-Bugzilla-Target-Milestone: 11.0 X-Bugzilla-Flags: X-Bugzilla-Changed-Fields: bug_status Message-ID: In-Reply-To: References: Content-Type: text/plain; charset="UTF-8" Content-Transfer-Encoding: quoted-printable X-Bugzilla-URL: http://gcc.gnu.org/bugzilla/ Auto-Submitted: auto-generated MIME-Version: 1.0 X-BeenThere: gcc-bugs@gcc.gnu.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: Gcc-bugs mailing list List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Mon, 09 Nov 2020 09:57:01 -0000 https://gcc.gnu.org/bugzilla/show_bug.cgi?id=3D97461 Martin Li=C5=A1ka changed: What |Removed |Added ---------------------------------------------------------------------------- Status|WAITING |NEW --- Comment #23 from Martin Li=C5=A1ka --- Thank you for the testing. Neither of the suggested changes help us. The core issue is that gcov does not know if it's called from a free/malloc function. That said, I see currently 2 possible fixes: 1. help from a malloc library that uses __gcov_supress_malloc/__gcov_allow_malloc: commit ee382a226ba0e76e2242dcbb4768033a4809a890 Author: Martin Liska Date: Fri Nov 6 16:59:43 2020 +0100 WIP patch. diff --git a/libgcc/Makefile.in b/libgcc/Makefile.in index d6075d32bd4..b235231f9d6 100644 --- a/libgcc/Makefile.in +++ b/libgcc/Makefile.in @@ -907,7 +907,7 @@ LIBGCOV_PROFILER =3D _gcov_interval_profiler=20=20=20= =20=20=20=20=20=20=20=20=20=20=20=20=20=20 \ LIBGCOV_INTERFACE =3D _gcov_dump _gcov_fork \ _gcov_execl _gcov_execlp \ _gcov_execle _gcov_execv _gcov_execvp _gcov_execve _gcov_reset \ - _gcov_lock_unlock + _gcov_lock_unlock _gcov_supress_malloc _gcov_allow_malloc LIBGCOV_DRIVER =3D _gcov libgcov-merge-objects =3D $(patsubst %,%$(objext),$(LIBGCOV_MERGE)) diff --git a/libgcc/gcov.h b/libgcc/gcov.h index 0e3eed31032..444f996692e 100644 --- a/libgcc/gcov.h +++ b/libgcc/gcov.h @@ -33,4 +33,12 @@ extern void __gcov_reset (void); extern void __gcov_dump (void); +/* Prevent from calling malloc. */ + +extern void __gcov_supress_malloc (void); + +/* Allow calling malloc. */ + +extern void __gcov_allow_malloc (void); + #endif /* GCC_GCOV_H */ diff --git a/libgcc/libgcov-interface.c b/libgcc/libgcov-interface.c index 3a8a5bf44b8..bcfc38b85c3 100644 --- a/libgcc/libgcov-interface.c +++ b/libgcc/libgcov-interface.c @@ -36,6 +36,14 @@ void __gcov_reset (void) {} void __gcov_dump (void) {} #endif +#ifdef L_gcov_supress_malloc +void __gcov_supress_malloc (void) {} +#endif + +#ifdef L_gcov_allow_malloc +void __gcov_allow_malloc (void) {} +#endif + #else extern __gthread_mutex_t __gcov_mx ATTRIBUTE_HIDDEN; @@ -174,6 +182,20 @@ __gcov_dump (void) #endif /* L_gcov_dump */ +#ifdef L_gcov_supress_malloc +void __gcov_supress_malloc (void) +{ + __gcov_block_malloc =3D 1; +} +#endif /* L_gcov_supress_malloc */ + +#ifdef L_gcov_allow_malloc +void __gcov_allow_malloc (void) +{ + __gcov_block_malloc =3D 0; +} +#endif /* L_gcov_block_malloc */ + #ifdef L_gcov_fork /* A wrapper for the fork function. We reset counters in the child so that they are not counted twice. */ diff --git a/libgcc/libgcov-profiler.c b/libgcc/libgcov-profiler.c index 45ab93c9776..b83b230cd9c 100644 --- a/libgcc/libgcov-profiler.c +++ b/libgcc/libgcov-profiler.c @@ -141,6 +141,12 @@ __thread #endif struct indirect_call_tuple __gcov_indirect_call; +// TODO: move to a proper place +#if defined(HAVE_CC_TLS) && !defined (USE_EMUTLS) +__thread +#endif +int __gcov_block_malloc; + /* By default, the C++ compiler will use function addresses in the vtable entries. Setting TARGET_VTABLE_USES_DESCRIPTORS to nonzero tells the compiler to use function descriptors instead. The value diff --git a/libgcc/libgcov.h b/libgcc/libgcov.h index e70cf63b414..2eaed9548ea 100644 --- a/libgcc/libgcov.h +++ b/libgcc/libgcov.h @@ -247,6 +247,12 @@ struct indirect_call_tuple /* Pointer to counters. */ gcov_type *counters; }; + +extern +#if defined(HAVE_CC_TLS) && !defined (USE_EMUTLS) +__thread +#endif +int __gcov_block_malloc; /* Exactly one of these will be active in the process. */ extern struct gcov_master __gcov_master; @@ -428,7 +434,12 @@ allocate_gcov_kvp (void) #endif if (new_node =3D=3D NULL) - new_node =3D (struct gcov_kvp *)xcalloc (1, sizeof (struct gcov_kvp)); + { +#if !defined(IN_GCOV_TOOL) + if (!__gcov_block_malloc) + new_node =3D (struct gcov_kvp *)xcalloc (1, sizeof (struct gcov_kvp= )); +#endif + } return new_node; } 2) make a dynamic allocation for counters for TOPN at the very beginning in __gcov_init. @Honza: What do you think about it?=