Bug 108732 - Pre-compiled headers cannot be output to /dev/null
Summary: Pre-compiled headers cannot be output to /dev/null
Status: UNCONFIRMED
Alias: None
Product: gcc
Classification: Unclassified
Component: pch (show other bugs)
Version: 12.2.0
: P3 normal
Target Milestone: ---
Assignee: Not yet assigned to anyone
URL:
Keywords:
Depends on:
Blocks:
 
Reported: 2023-02-08 21:59 UTC by Matt Hellige
Modified: 2023-05-22 23:39 UTC (History)
2 users (show)

See Also:
Host:
Target:
Build:
Known to work: 11.2.0
Known to fail: 12.1.0, 12.2.0
Last reconfirmed:


Attachments

Note You need to log in before you can comment on or make changes to this bug.
Description Matt Hellige 2023-02-08 21:59:34 UTC
with GCC 12, the following command fails with a fairly obscure error:

   $ gcc12.2.0 -c foo.h -o /dev/null
   foo.h:1: fatal error: cannot write PCH file: required memory segment unavailable
   compilation terminated.

This also fails when invoked via g++. It works fine if the output is a normal file, and it always worked with previous GCC versions, so this is a pretty surprising change.

This may seem like a strange thing to want to do, but I maintain a number of builds that do similar invocations to verify that each header file is self-contained.

Either way, I think it would be best to fix it, or if that's not possible, it would be nice to improve the error message at the very least.
Comment 1 Andrew Pinski 2023-02-08 22:09:09 UTC
>it always worked with previous GCC versions

Not really. Just by accident really.

See r12-5320-ge4641191287ca6

Basically it means mmap failed on the file; well because mmap does not work on /dev/null .
Comment 2 Andrew Pinski 2023-02-08 22:11:32 UTC
>I maintain a number of builds that do similar invocations to verify that each header file is self-contained.

You could just do:
gcc -xc -include header.h /dev/null -o /dev/null -c

Which works better and will always work when modules become standard ...
Comment 3 Matt Hellige 2023-02-08 22:23:20 UTC
As long as I'm updating builds, I'll switch to that invocation, thanks.

I still do think it's a little odd that in this case (and *only* in this case?) output needs to be written to a mappable file. That does not seem to be a typical implication of a -o flag of any tool I've ever used.

And in fact your suggested change sort of proves my point... Why would a user suspect that /dev/null can be used for both input and output of that gcc -xc invocation, but not the other one?
Comment 4 Andrew Pinski 2023-02-08 22:45:48 UTC
(In reply to Matt Hellige from comment #3)
> As long as I'm updating builds, I'll switch to that invocation, thanks.
> 
> I still do think it's a little odd that in this case (and *only* in this
> case?) output needs to be written to a mappable file. 

The way PCH works is mapping files in and out for speed reasons. So it is not really that odd. Even though it is not expliclty mentioned in the manual:
https://gcc.gnu.org/onlinedocs/gcc-12.2.0/gcc/Precompiled-Headers.html#Precompiled-Headers

The whole idea of PCH is that the file is mapped in with almost no changes done afterwards so an exact dump of the memory from compiler can be loaded back in without doing anything special; rather the OS handles the loading into memory from the file.
Comment 5 Matt Hellige 2023-02-08 22:56:43 UTC
That makes sense, but it's just a strange inconsistency from a usability point of view.

.so files are generally mmapped as well, I believe, aren't they? But I can still generate one to /dev/null if I like:

   $ gcc12.2.0 -o /dev/null -rdynamic -shared foo.o bar.o -lrt ...

Works fine.
Comment 6 Andrew Pinski 2023-02-08 23:01:19 UTC
(In reply to Matt Hellige from comment #5)
> That makes sense, but it's just a strange inconsistency from a usability
> point of view.
> 
> .so files are generally mmapped as well, I believe, aren't they? But I can
> still generate one to /dev/null if I like:
> 
>    $ gcc12.2.0 -o /dev/null -rdynamic -shared foo.o bar.o -lrt ...
> 
> Works fine.

Well so works differently because the linker produces runtime relocations for some segments of the shared objects which get applied at runtime. This is unlike pch which does have a relocation method but that method is slow. Also the linker is basically doing copies from other files into the final file while gcc is outputting its internals out for pch.
Comment 7 Matt Hellige 2023-02-08 23:15:18 UTC
Those make sense as internal details. I don't think a typical user should be expected to guess or learn these differences in order to use the GCC from the command line. So, whether or not they suffice as justification for a command failing when it always worked with prior versions, I suppose will be a matter of taste.
Comment 8 Justin Chen 2023-05-22 23:16:05 UTC
I ran into the exact issue. Took me a while to figure out the issue was "-o /dev/null". The inconsistency also caught me off guard. I agree we need some consistency here.