[Bug debug/81135] New: Extra debug info generated for unused extern declarations
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=81135 Bug ID: 81135 Summary: Extra debug info generated for unused extern declarations Product: gcc Version: 6.1.0 Status: UNCONFIRMED Severity: normal Priority: P3 Component: debug Assignee: unassigned at gcc dot gnu.org Reporter: peadar at arista dot com Target Milestone: --- Created attachment 41589 --> https://gcc.gnu.org/bugzilla/attachment.cgi?id=41589&action=edit Contains trivial test program, and output from gcc-5 and gcc-6 showing old and new behaviour This is a follow-up to track the discussion at https://gcc.gnu.org/ml/gcc-help/2017-06/threads.html#00086 Since version 6.1.0, gcc has produced DW_TAG_variable DIEs for variables declared as extern, but not otherwise used in the translation unit. For libraries with large numbers of object files compiled from source containing a large number of extern declarations, the overhead of this can be quite significant I've attached a tarball including the output gcc-6 and gcc-5 from an ubuntu 17.04 system, the former of which exhibits the problem, the latter which does not. You can see that the `fooUnused` extern declaration has a DW_TAG_variable with gcc-6, but not gcc-5. As per the discussion thread, this seems to be fallout from the integration of the "debug-early" branch, and discussion at https://gcc.gnu.org/ml/gcc/2015-05/msg00046.html seems to suggest that some bloating of DWARF data was expected, and that later work would address the issue. Bisecting the git mirror on github does show the behaviour being introduced at https://github.com/gcc-mirror/gcc/commit/3a1c9df , which is where this branch merged in.
[Bug debug/97811] New: Adding transparent_union tag when typedeffing compiles but produces no debug info for components of the union
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=97811 Bug ID: 97811 Summary: Adding transparent_union tag when typedeffing compiles but produces no debug info for components of the union Product: gcc Version: unknown Status: UNCONFIRMED Severity: normal Priority: P3 Component: debug Assignee: unassigned at gcc dot gnu.org Reporter: peadar at arista dot com Target Milestone: --- Created attachment 49551 --> https://gcc.gnu.org/bugzilla/attachment.cgi?id=49551&action=edit Source file for good/bad example. This is against gcc (GCC) 10.2.1 20201016 (Red Hat 10.2.1-6) But exists as far back as gcc8.4 at least. transparent_enum's are used in glibc for example, with __SOCKADDR_ARG to allow any type of the numerous address family's variants of sockaddr to be passed to functions such as bind(2). The type __SOCKADDR_ARG is declared something like this: typedef union { sockaddr * restrict __sockadddr__; sockaddr_in * restrict __sockadddr_in__; /* more sockaddr_* types ... */ } __SOCKADDR_ARG __attribute__((transparent_union)); When compiled with -g, the resulting debug information does not contain any entries for the fields of the DIE for the (anonymous) union. The construction looked a little odd to me - it seemed that the attribute is being applied to the typedef, rather than the union itself, but gcc was happy to compile it, and the type behaves as expected when passing arguments to bind(2), for example. By putting the attribute before the __SOCKADDR_ARG token, it actually fixes the problem, but it seems either the debug information should be propagated to the union, or that the compiler should complain. The attachment is a source file transparent-union.c, and embedded a comment that is the output of `readelf --debug-dump=info transparent-union.o`. You can see that for UGood, there's a typedef to the union, and the union has child DIEs for each member. For UBad, there's the typedef and the union, but no members. gdb is, of course, unable to print the content of the problematic union when debugging, and other tools are equally unhappy.
[Bug libstdc++/118099] New: basic_filebuf::overflow is left inconsistent on I/O error.
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=118099 Bug ID: 118099 Summary: basic_filebuf::overflow is left inconsistent on I/O error. Product: gcc Version: 14.2.1 Status: UNCONFIRMED Severity: normal Priority: P3 Component: libstdc++ Assignee: unassigned at gcc dot gnu.org Reporter: peadar at arista dot com Target Milestone: --- Created attachment 59904 --> https://gcc.gnu.org/bugzilla/attachment.cgi?id=59904&action=edit Naive patch for issue. The following illustrates the problem directly: ``` #include int main(int argc, char *argv[]) { std::ofstream of("/dev/full", std::ios_base::out); auto rdbuf = of.rdbuf(); for (;;) rdbuf->sputc('x'); } ``` The same problem manifests writing to std::cout if you set `std::ios_base::sync_with_stdio(false)` when the buffer fills, sputc calls `std::basic_filebuf >::overflow`, passing the character as the 'overflow' character. basic_filebuf maintains space in the managed buffer for this overflow, and inserts it into the buffer via *pptr()/pbump(1) - about line 560 of fstream.tcc ``` if (!__testeof) { *this->pptr() = traits_type::to_char_type(__c); this->pbump(1); } ``` However, if the call to _M_convert_to_external fails (eventually due to the write failing, in the above case because we fail to write to /dev/full), then an error is returned, but the character is left sitting in the buffer, and pptr > epptr. A further call to sputc will hit the same point, and we will continue to write further past the end of the managed buffer. Of course the caller should check for an error, but even if they do, the streambuf is now in an inconsistent state, and there's no obvious approach to recover - regardless of the memory scribble, we're returning with an error from sputc(), but have also inserted the character we "failed" to write into the buffer, which is inconsistent with the error return. So the simplest thing to do here seems to be to just remove the character from the buffer . Dumb patch attached, for what its worth. This doesn't happen with std::cout if it's tied to C's stdout - the buffer is managed differently and the problem doesn't manifest.