public inbox for libc-alpha@sourceware.org
 help / color / mirror / Atom feed
* [PATCH] Add comments to explain when a stream is freed by, __libc_freeres().
@ 2020-05-22 20:37 Carlos O'Donell
  2020-05-25 15:30 ` Florian Weimer
  0 siblings, 1 reply; 15+ messages in thread
From: Carlos O'Donell @ 2020-05-22 20:37 UTC (permalink / raw)
  To: libc-alpha

In bug 26022 a user reports that valgrind shows two unfreed
allocations when using stderr.  This is normal, we don't free
unbuffered streams in __libc_freeres() because users expect
that such streams will be available all the way through the
process shutdown.

To suppress this I've filed the following valgrind issue:
https://bugs.kde.org/show_bug.cgi?id=421931
---
 libio/genops.c | 23 ++++++++++++++++++++---
 1 file changed, 20 insertions(+), 3 deletions(-)

diff --git a/libio/genops.c b/libio/genops.c
index 28419cc963..d533d47fd5 100644
--- a/libio/genops.c
+++ b/libio/genops.c
@@ -768,7 +768,7 @@ weak_alias (_IO_flush_all_linebuffered, _flushlbf)
    function sin the libc_freeres section.  Those are called as part of
    the atexit routine, just like _IO_cleanup.  The problem is we do
    not know whether the freeres code is called first or _IO_cleanup.
-   if the former is the case, we set the DEALLOC_BUFFER variable to
+   if the former is the case, we set the dealloc_buffers variable to
    true and _IO_unbuffer_all will take care of the rest.  If
    _IO_unbuffer_all is called first we add the streams to a list
    which the freeres function later can walk through.  */
@@ -796,8 +796,23 @@ _IO_unbuffer_all (void)
 	legacy = 1;
 #endif
 
+      /* We free a stream if:
+
+	 (1) The stream is buffered and was used (_mode != 0), and
+	     so the user can't expect any output to be printed during
+	     shutdown since absolute order of destructors is not
+	     explicitly guaranteed.
+
+	 (2) The stream is buffered and is a legacy stream used for
+	     backwards compatibility with legacy libstdc++
+	     implementations.
+
+	 By default stderr starts unbuffered and so by default we
+	 never process it here, and as such it is always available for
+	 late destructors to use, and will not be freed by the
+	 buffer_free function below (unless it is changed by the
+	 user).  */
       if (! (fp->_flags & _IO_UNBUFFERED)
-	  /* Iff stream is un-orientated, it wasn't used. */
 	  && (legacy || fp->_mode != 0))
 	{
 #ifdef _IO_MTSAFE_IO
@@ -844,11 +859,13 @@ _IO_unbuffer_all (void)
 #endif
 }
 
-
+/* Called by __libc_freeres() to free streams.  */
 libc_freeres_fn (buffer_free)
 {
   dealloc_buffers = true;
 
+  /* See the note in _IO_unbuffer_all about when a stream is
+     considered for freeing.  */
   while (freeres_list != NULL)
     {
       free (freeres_list->_freeres_buf);
-- 
2.26.2


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

end of thread, other threads:[~2020-06-04 18:36 UTC | newest]

Thread overview: 15+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2020-05-22 20:37 [PATCH] Add comments to explain when a stream is freed by, __libc_freeres() Carlos O'Donell
2020-05-25 15:30 ` Florian Weimer
2020-05-25 21:17   ` Carlos O'Donell
2020-05-26  7:53     ` Florian Weimer
2020-05-26  8:16       ` Andreas Schwab
2020-05-26  8:39         ` Florian Weimer
2020-05-26  8:53           ` Andreas Schwab
2020-05-26  9:31             ` Florian Weimer
2020-05-26  9:37               ` Andreas Schwab
2020-05-26 12:31                 ` Florian Weimer
2020-05-26 12:57                   ` Andreas Schwab
2020-05-26 13:15                     ` Florian Weimer
2020-05-26 13:18                       ` Andreas Schwab
2020-05-26 13:23                         ` Florian Weimer
2020-06-04 18:35       ` Carlos O'Donell

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).