[Bug debug/81135] New: Extra debug info generated for unused extern declarations

2017-06-20 Thread peadar at arista dot com
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

2020-11-12 Thread peadar at arista dot com via Gcc-bugs
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.

2024-12-17 Thread peadar at arista dot com via Gcc-bugs
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.