public inbox for gcc-patches@gcc.gnu.org
 help / color / mirror / Atom feed
* [PATCH, c-family] Fix a PCH thinko (and thus PR61250).
@ 2019-08-22 21:31 Iain Sandoe
  2019-08-22 22:37 ` Jeff Law
  0 siblings, 1 reply; 3+ messages in thread
From: Iain Sandoe @ 2019-08-22 21:31 UTC (permalink / raw)
  To: GCC Patches; +Cc: Jason Merrill, Joseph Myers

Hi,

When we are parsing a source file, the very first token might
be a PRAGMA_GCC_PCH_PREPROCESS.  This indicates that we are going
read in a PCH file (named as the value of the pragma).  If we don't
see this pragma, then we know that it's OK to release any resources
that the host might have set aside for the PCH file.

There is a thinko in the current implementation, in that the decision
to release resources is happening unconditionally right after the first
token is extracted but before it's been checked or acted upon.

This leads to the pch bug on Darwin, because we actually do release
resources - which are subsequently (reasonably) assumed to be available
when reading a PCH file.  We then get random crashes or hangs depending
on the interaction between unmmap and malloc.

The bug is present everywhere but doesn't show on (say) Linux, since
the release of PCH resources is a NOP there.

This effects all the c-family front ends, because they all use c_lex_with_flags ()
to implement this.

The solution is to check for the PRAGMA_GCC_PCH_PREPROCESS and only call
c_common_no_more_pch () when that is not the first token.

A secondary effect of the collection is that the name of the PCH file
can be collected during the ggc_pch_read() reset of state.  Therefore
we should issue any diagnostic that might name the file before the
collections are triggered.

Tested on x86-64-darwin16/18 (where the pch.exp tests fail roughly half the
time for any parallel testing) and pass reliably without it.
Tested on x86_64,powerpc-linux-gnu with no regressions (and no expectation
of any progression either).

Since the fix is in common code, it needs the ack of both C and C++ to apply
(I’m obviously OK with applying it from the Objective-C/C++ PoV)

OK for trunk?

given that this is a  show-stopper for PCH + -save-temps I would also like
to fix it on the open branches?

thanks
Iain

gcc/c-family/

2019-08-22  Iain Sandoe  <iain@sandoe.co.uk>

	PR pch/61250
	* c-lex.c (c_lex_with_flags):  Don't call
	c_common_no_more_pch () from here.

gcc/c/

2019-08-22  Iain Sandoe  <iain@sandoe.co.uk>

	PR pch/61250
	* c-parser.c (c_parse_file): Call c_common_no_more_pch ()
	after determining that the first token is not
	PRAGMA_GCC_PCH_PREPROCESS.

gcc/cp/

2019-08-22  Iain Sandoe  <iain@sandoe.co.uk>

	PR pch/61250
	* parser.c (cp_parser_initial_pragma): Call c_common_no_more_pch ()
	after determining that the first token is not
	PRAGMA_GCC_PCH_PREPROCESS.

gcc/

2019-08-22  Iain Sandoe  <iain@sandoe.co.uk>

	PR pch/61250
	* ggc-page.c (ggc_pch_read): Read the ggc_pch_ondisk structure
	and issue any diagnostics needed before collecting the pre-PCH
	state.

---
 gcc/c-family/c-lex.c | 7 -------
 gcc/c/c-parser.c     | 2 ++
 gcc/cp/parser.c      | 5 ++++-
 gcc/ggc-page.c       | 5 +++--
 4 files changed, 9 insertions(+), 10 deletions(-)

diff --git a/gcc/c-family/c-lex.c b/gcc/c-family/c-lex.c
index 851fd704e5..e3c602fbb8 100644
--- a/gcc/c-family/c-lex.c
+++ b/gcc/c-family/c-lex.c
@@ -394,7 +394,6 @@ enum cpp_ttype
 c_lex_with_flags (tree *value, location_t *loc, unsigned char *cpp_flags,
 		  int lex_flags)
 {
-  static bool no_more_pch;
   const cpp_token *tok;
   enum cpp_ttype type;
   unsigned char add_flags = 0;
@@ -628,12 +627,6 @@ c_lex_with_flags (tree *value, location_t *loc, unsigned char *cpp_flags,
   if (cpp_flags)
     *cpp_flags = tok->flags | add_flags;
 
-  if (!no_more_pch)
-    {
-      no_more_pch = true;
-      c_common_no_more_pch ();
-    }
-
   timevar_pop (TV_CPP);
 
   return type;
diff --git a/gcc/c/c-parser.c b/gcc/c/c-parser.c
index 81919a89cc..cf973b3c8d 100644
--- a/gcc/c/c-parser.c
+++ b/gcc/c/c-parser.c
@@ -20232,6 +20232,8 @@ c_parse_file (void)
 
   if (c_parser_peek_token (&tparser)->pragma_kind == PRAGMA_GCC_PCH_PREPROCESS)
     c_parser_pragma_pch_preprocess (&tparser);
+  else
+    c_common_no_more_pch ();
 
   the_parser = ggc_alloc<c_parser> ();
   *the_parser = tparser;
diff --git a/gcc/cp/parser.c b/gcc/cp/parser.c
index dbbfe1dbc2..ab8a0cabb4 100644
--- a/gcc/cp/parser.c
+++ b/gcc/cp/parser.c
@@ -41353,7 +41353,10 @@ cp_parser_initial_pragma (cp_token *first_token)
 
   cp_lexer_get_preprocessor_token (NULL, first_token);
   if (cp_parser_pragma_kind (first_token) != PRAGMA_GCC_PCH_PREPROCESS)
-    return;
+    {
+      c_common_no_more_pch ();
+      return;
+    }
 
   cp_lexer_get_preprocessor_token (NULL, first_token);
   if (first_token->type == CPP_STRING)
diff --git a/gcc/ggc-page.c b/gcc/ggc-page.c
index a2736bc1df..220f20c5cf 100644
--- a/gcc/ggc-page.c
+++ b/gcc/ggc-page.c
@@ -2556,6 +2556,9 @@ ggc_pch_read (FILE *f, void *addr)
 
   count_old_page_tables = G.by_depth_in_use;
 
+  if (fread (&d, sizeof (d), 1, f) != 1)
+    fatal_error (input_location, "cannot read PCH file: %m");
+
   /* We've just read in a PCH file.  So, every object that used to be
      allocated is now free.  */
   clear_marks ();
@@ -2584,8 +2587,6 @@ ggc_pch_read (FILE *f, void *addr)
 
   /* Allocate the appropriate page-table entries for the pages read from
      the PCH file.  */
-  if (fread (&d, sizeof (d), 1, f) != 1)
-    fatal_error (input_location, "cannot read PCH file: %m");
 
   for (i = 0; i < NUM_ORDERS; i++)
     {
-- 
2.17.1



^ permalink raw reply	[flat|nested] 3+ messages in thread

* Re: [PATCH, c-family] Fix a PCH thinko (and thus PR61250).
  2019-08-22 21:31 [PATCH, c-family] Fix a PCH thinko (and thus PR61250) Iain Sandoe
@ 2019-08-22 22:37 ` Jeff Law
  2019-08-23  2:46   ` Jason Merrill
  0 siblings, 1 reply; 3+ messages in thread
From: Jeff Law @ 2019-08-22 22:37 UTC (permalink / raw)
  To: Iain Sandoe, GCC Patches; +Cc: Jason Merrill, Joseph Myers

On 8/22/19 1:59 PM, Iain Sandoe wrote:
> Hi,
> 
> When we are parsing a source file, the very first token might
> be a PRAGMA_GCC_PCH_PREPROCESS.  This indicates that we are going
> read in a PCH file (named as the value of the pragma).  If we don't
> see this pragma, then we know that it's OK to release any resources
> that the host might have set aside for the PCH file.
> 
> There is a thinko in the current implementation, in that the decision
> to release resources is happening unconditionally right after the first
> token is extracted but before it's been checked or acted upon.
> 
> This leads to the pch bug on Darwin, because we actually do release
> resources - which are subsequently (reasonably) assumed to be available
> when reading a PCH file.  We then get random crashes or hangs depending
> on the interaction between unmmap and malloc.
> 
> The bug is present everywhere but doesn't show on (say) Linux, since
> the release of PCH resources is a NOP there.
> 
> This effects all the c-family front ends, because they all use c_lex_with_flags ()
> to implement this.
> 
> The solution is to check for the PRAGMA_GCC_PCH_PREPROCESS and only call
> c_common_no_more_pch () when that is not the first token.
> 
> A secondary effect of the collection is that the name of the PCH file
> can be collected during the ggc_pch_read() reset of state.  Therefore
> we should issue any diagnostic that might name the file before the
> collections are triggered.
> 
> Tested on x86-64-darwin16/18 (where the pch.exp tests fail roughly half the
> time for any parallel testing) and pass reliably without it.
> Tested on x86_64,powerpc-linux-gnu with no regressions (and no expectation
> of any progression either).
> 
> Since the fix is in common code, it needs the ack of both C and C++ to apply
> (I’m obviously OK with applying it from the Objective-C/C++ PoV)
> 
> OK for trunk?
> 
> given that this is a  show-stopper for PCH + -save-temps I would also like
> to fix it on the open branches?
> 
> thanks
> Iain
> 
> gcc/c-family/
> 
> 2019-08-22  Iain Sandoe  <iain@sandoe.co.uk>
> 
> 	PR pch/61250
> 	* c-lex.c (c_lex_with_flags):  Don't call
> 	c_common_no_more_pch () from here.
> 
> gcc/c/
> 
> 2019-08-22  Iain Sandoe  <iain@sandoe.co.uk>
> 
> 	PR pch/61250
> 	* c-parser.c (c_parse_file): Call c_common_no_more_pch ()
> 	after determining that the first token is not
> 	PRAGMA_GCC_PCH_PREPROCESS.
> 
> gcc/cp/
> 
> 2019-08-22  Iain Sandoe  <iain@sandoe.co.uk>
> 
> 	PR pch/61250
> 	* parser.c (cp_parser_initial_pragma): Call c_common_no_more_pch ()
> 	after determining that the first token is not
> 	PRAGMA_GCC_PCH_PREPROCESS.
> 
> gcc/
> 
> 2019-08-22  Iain Sandoe  <iain@sandoe.co.uk>
> 
> 	PR pch/61250
> 	* ggc-page.c (ggc_pch_read): Read the ggc_pch_ondisk structure
> 	and issue any diagnostics needed before collecting the pre-PCH
> 	state.
OK
jeff

^ permalink raw reply	[flat|nested] 3+ messages in thread

* Re: [PATCH, c-family] Fix a PCH thinko (and thus PR61250).
  2019-08-22 22:37 ` Jeff Law
@ 2019-08-23  2:46   ` Jason Merrill
  0 siblings, 0 replies; 3+ messages in thread
From: Jason Merrill @ 2019-08-23  2:46 UTC (permalink / raw)
  To: Jeff Law; +Cc: Iain Sandoe, GCC Patches, Joseph Myers

On Thu, Aug 22, 2019 at 2:39 PM Jeff Law <law@redhat.com> wrote:
>
> On 8/22/19 1:59 PM, Iain Sandoe wrote:
> > Hi,
> >
> > When we are parsing a source file, the very first token might
> > be a PRAGMA_GCC_PCH_PREPROCESS.  This indicates that we are going
> > read in a PCH file (named as the value of the pragma).  If we don't
> > see this pragma, then we know that it's OK to release any resources
> > that the host might have set aside for the PCH file.
> >
> > There is a thinko in the current implementation, in that the decision
> > to release resources is happening unconditionally right after the first
> > token is extracted but before it's been checked or acted upon.
> >
> > This leads to the pch bug on Darwin, because we actually do release
> > resources - which are subsequently (reasonably) assumed to be available
> > when reading a PCH file.  We then get random crashes or hangs depending
> > on the interaction between unmmap and malloc.
> >
> > The bug is present everywhere but doesn't show on (say) Linux, since
> > the release of PCH resources is a NOP there.
> >
> > This effects all the c-family front ends, because they all use c_lex_with_flags ()
> > to implement this.
> >
> > The solution is to check for the PRAGMA_GCC_PCH_PREPROCESS and only call
> > c_common_no_more_pch () when that is not the first token.
> >
> > A secondary effect of the collection is that the name of the PCH file
> > can be collected during the ggc_pch_read() reset of state.  Therefore
> > we should issue any diagnostic that might name the file before the
> > collections are triggered.
> >
> > Tested on x86-64-darwin16/18 (where the pch.exp tests fail roughly half the
> > time for any parallel testing) and pass reliably without it.
> > Tested on x86_64,powerpc-linux-gnu with no regressions (and no expectation
> > of any progression either).
> >
> > Since the fix is in common code, it needs the ack of both C and C++ to apply
> > (I’m obviously OK with applying it from the Objective-C/C++ PoV)
> >
> > OK for trunk?
> >
> > given that this is a  show-stopper for PCH + -save-temps I would also like
> > to fix it on the open branches?
> >
> > thanks
> > Iain
> >
> > gcc/c-family/
> >
> > 2019-08-22  Iain Sandoe  <iain@sandoe.co.uk>
> >
> >       PR pch/61250
> >       * c-lex.c (c_lex_with_flags):  Don't call
> >       c_common_no_more_pch () from here.
> >
> > gcc/c/
> >
> > 2019-08-22  Iain Sandoe  <iain@sandoe.co.uk>
> >
> >       PR pch/61250
> >       * c-parser.c (c_parse_file): Call c_common_no_more_pch ()
> >       after determining that the first token is not
> >       PRAGMA_GCC_PCH_PREPROCESS.
> >
> > gcc/cp/
> >
> > 2019-08-22  Iain Sandoe  <iain@sandoe.co.uk>
> >
> >       PR pch/61250
> >       * parser.c (cp_parser_initial_pragma): Call c_common_no_more_pch ()
> >       after determining that the first token is not
> >       PRAGMA_GCC_PCH_PREPROCESS.
> >
> > gcc/
> >
> > 2019-08-22  Iain Sandoe  <iain@sandoe.co.uk>
> >
> >       PR pch/61250
> >       * ggc-page.c (ggc_pch_read): Read the ggc_pch_ondisk structure
> >       and issue any diagnostics needed before collecting the pre-PCH
> >       state.
> OK

OK with me, too.  Joseph recently mentioned being swamped with
reviews, so I wouldn't worry about waiting for his review.

Jason

^ permalink raw reply	[flat|nested] 3+ messages in thread

end of thread, other threads:[~2019-08-23  0:05 UTC | newest]

Thread overview: 3+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2019-08-22 21:31 [PATCH, c-family] Fix a PCH thinko (and thus PR61250) Iain Sandoe
2019-08-22 22:37 ` Jeff Law
2019-08-23  2:46   ` Jason Merrill

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).