aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorRichard Purdie <richard.purdie@linuxfoundation.org>2021-09-23 12:16:14 +0100
committerRichard Purdie <richard.purdie@linuxfoundation.org>2021-09-23 12:27:01 +0100
commit032190aac31604d37740d8aecf6e74a5448de358 (patch)
tree59a44ea524bfeb422854620f2b46ad811b6c439c
parentdf89e37c33e4398a5f8ece9a8b973be3fe2ff361 (diff)
downloadbitbake-032190aac31604d37740d8aecf6e74a5448de358.tar.gz
build: Fix log flushing race
There is a race between sending the TaskFailed event which could trigger the UI to look at the logs and flushing and closing the log files. Reverse the order of the finally clause and the exception handling to ensure we've handled the logfiles before sending the task events. This should fix a race seen in bblogging.BitBakeLogging.test_python_exit_logging Signed-off-by: Richard Purdie <richard.purdie@linuxfoundation.org>
-rw-r--r--lib/bb/build.py76
1 files changed, 38 insertions, 38 deletions
diff --git a/lib/bb/build.py b/lib/bb/build.py
index 99954b0c2..7e4ab9f64 100644
--- a/lib/bb/build.py
+++ b/lib/bb/build.py
@@ -686,51 +686,51 @@ def _exec_task(fn, task, d, quieterr):
try:
try:
event.fire(TaskStarted(task, fn, logfn, flags, localdata), localdata)
- except (bb.BBHandledException, SystemExit):
- return 1
- try:
for func in (prefuncs or '').split():
exec_func(func, localdata)
exec_func(task, localdata)
for func in (postfuncs or '').split():
exec_func(func, localdata)
- except bb.BBHandledException:
- event.fire(TaskFailed(task, fn, logfn, localdata, True), localdata)
- return 1
- except (Exception, SystemExit) as exc:
- if quieterr:
- event.fire(TaskFailedSilent(task, fn, logfn, localdata), localdata)
- else:
- errprinted = errchk.triggered
- # If the output is already on stdout, we've printed the information in the
- # logs once already so don't duplicate
- if verboseStdoutLogging:
- errprinted = True
- logger.error(repr(exc))
- event.fire(TaskFailed(task, fn, logfn, localdata, errprinted), localdata)
- return 1
- finally:
- sys.stdout.flush()
- sys.stderr.flush()
-
- bblogger.removeHandler(handler)
-
- # Restore the backup fds
- os.dup2(osi[0], osi[1])
- os.dup2(oso[0], oso[1])
- os.dup2(ose[0], ose[1])
-
- # Close the backup fds
- os.close(osi[0])
- os.close(oso[0])
- os.close(ose[0])
+ finally:
+ # Need to flush and close the logs before sending events where the
+ # UI may try to look at the logs.
+ sys.stdout.flush()
+ sys.stderr.flush()
+
+ bblogger.removeHandler(handler)
+
+ # Restore the backup fds
+ os.dup2(osi[0], osi[1])
+ os.dup2(oso[0], oso[1])
+ os.dup2(ose[0], ose[1])
+
+ # Close the backup fds
+ os.close(osi[0])
+ os.close(oso[0])
+ os.close(ose[0])
+
+ logfile.close()
+ if os.path.exists(logfn) and os.path.getsize(logfn) == 0:
+ logger.debug2("Zero size logfn %s, removing", logfn)
+ bb.utils.remove(logfn)
+ bb.utils.remove(loglink)
+ except bb.BBHandledException:
+ event.fire(TaskFailed(task, fn, logfn, localdata, True), localdata)
+ return 1
+ except (Exception, SystemExit) as exc:
+ if quieterr:
+ event.fire(TaskFailedSilent(task, fn, logfn, localdata), localdata)
+ else:
+ errprinted = errchk.triggered
+ # If the output is already on stdout, we've printed the information in the
+ # logs once already so don't duplicate
+ if verboseStdoutLogging:
+ errprinted = True
+ logger.error(repr(exc))
+ event.fire(TaskFailed(task, fn, logfn, localdata, errprinted), localdata)
+ return 1
- logfile.close()
- if os.path.exists(logfn) and os.path.getsize(logfn) == 0:
- logger.debug2("Zero size logfn %s, removing", logfn)
- bb.utils.remove(logfn)
- bb.utils.remove(loglink)
event.fire(TaskSucceeded(task, fn, logfn, localdata), localdata)
if not localdata.getVarFlag(task, 'nostamp', False) and not localdata.getVarFlag(task, 'selfstamp', False):