[bitbake-devel] [PATCH] daemonize: Flush stdio on exit
Richard Purdie
richard.purdie at linuxfoundation.org
Fri Aug 24 06:57:31 UTC 2018
On Wed, 2018-08-22 at 15:33 +0200, Rasmus Villemoes wrote:
> On 2018-08-21 16:04, Joshua Watt wrote:
> > In spite of a comment suggesting otherwise, os._exit() does not
> > flush
> > buffered output from file descriptors before exiting the process
> > like
> > os.exit() does. This means that any un-flushed output is lost in
> > the
> > daemon process, in particular the traceback from any thrown
> > exceptions,
> > making debugging exceptions in the daemon quite difficult.
> >
> > The solution is to flush stdout and stderr before exiting.
> >
> > Signed-off-by: Joshua Watt <JPEWhacker at gmail.com>
> > ---
> > bitbake/lib/bb/daemonize.py | 9 +++++++--
> > 1 file changed, 7 insertions(+), 2 deletions(-)
> >
> > diff --git a/bitbake/lib/bb/daemonize.py
> > b/bitbake/lib/bb/daemonize.py
> > index 8300d1d0f0f..bf16793468e 100644
> > --- a/bitbake/lib/bb/daemonize.py
> > +++ b/bitbake/lib/bb/daemonize.py
> > @@ -49,8 +49,8 @@ def createDaemon(function, logfile):
> > # exit() or _exit()?
> > # _exit is like exit(), but it doesn't call any
> > functions registered
> > # with atexit (and on_exit) or any registered signal
> > handlers. It also
> > - # closes any open file descriptors. Using exit() may
> > cause all stdio
> > - # streams to be flushed twice and any temporary files
> > may be unexpectedly
> > + # closes any open file descriptors, but doesn't flush
> > any buffered output.
> > + # Using exit() may cause all any temporary files to be
> > unexpectedly
> > # removed. It's therefore recommended that child
> > branches of a fork()
> > # and the parent branch(es) of a daemon use _exit().
> > os._exit(0)
> > @@ -79,4 +79,9 @@ def createDaemon(function, logfile):
> > traceback.print_exc()
> > finally:
> > bb.event.print_ui_queue()
> > + # os._exit() doesn't flush open files like os.exit() does.
> > Manually flush
> > + # stdout and stderr so that any logging output will be
> > seen, particularly
> > + # exception tracebacks.
> > + sys.stdout.flush()
> > + sys.stderr.flush()
> > os._exit(0)
> >
>
> Well, that's of course better than not getting the output, but
> there's then the issue of double printing: The intermediate child
> does _exit(), but the grandparent may have had stuff in the stdio
> buffers before the very first fork(), and that content would be
> inherited down to the grandchild. So I think you should (also)
> explicitly flush stdout and stderr before the first fork().
You're correct, we should do that. I was thinking we did flush things
before forking but looking at the code I'm thinking of the fork() call
in bitbake-worker, not the one in daemonize.py.
I'd happily take a patch if someone wants to work one up!
Cheers,
Richard
More information about the bitbake-devel
mailing list