summaryrefslogtreecommitdiffstats
path: root/bitbake/lib/bb/ui/knotty.py
diff options
context:
space:
mode:
authorMark Asselstine <mark.asselstine@windriver.com>2023-12-28 16:01:18 -0500
committerRichard Purdie <richard.purdie@linuxfoundation.org>2024-01-10 14:02:38 +0000
commit98c5c96dd3902cdc4a455a9ed46591037ab3f676 (patch)
tree4a555be1e9110218bb1a25e71cbf83d11b50ecf9 /bitbake/lib/bb/ui/knotty.py
parentbc22d82c2f0c16ee8ad2edeb3bcdfb31db0afa94 (diff)
downloadpoky-98c5c96dd3902cdc4a455a9ed46591037ab3f676.tar.gz
bitbake: ui/knotty: properly handle exceptions when calling runCommand()
In runCommand() the send() and recv() can fail and raise BrokenPipeError and EOFError exceptions when the bitbake-server is unexpectedly terminated. In these cases a python traceback is currently dumped. Similarly updateFromServer() which calls runCommand() can also raise these and other exceptions, and currently lacks proper exception handling resulting in python traceback. We wrap calls to runCommand() and updateFromServer() in a try/except block as well as improve the exception handling for updateToServer(). This along with the earlier commit which added text to the BrokenPipeError and EOFError exceptions in runCommand() to indicate a bitbake-server termination may have occurred, should improve the user's ability to understand and handle these errors. An easy way to trigger each of the runCommand() exceptions is to 'kill -9' bitbake-server before (causes EOFError) or after (causes BrokenPipeError) the "Loading Cache" stage. (Bitbake rev: 804d366ee3ddc0f37f0a6c712c8d42db45b119bc) Signed-off-by: Mark Asselstine <mark.asselstine@windriver.com> Signed-off-by: Richard Purdie <richard.purdie@linuxfoundation.org>
Diffstat (limited to 'bitbake/lib/bb/ui/knotty.py')
-rw-r--r--bitbake/lib/bb/ui/knotty.py62
1 files changed, 52 insertions, 10 deletions
diff --git a/bitbake/lib/bb/ui/knotty.py b/bitbake/lib/bb/ui/knotty.py
index 431baa15ef..5a97d040b0 100644
--- a/bitbake/lib/bb/ui/knotty.py
+++ b/bitbake/lib/bb/ui/knotty.py
@@ -420,6 +420,11 @@ def main(server, eventHandler, params, tf = TerminalFilter):
420 except bb.BBHandledException: 420 except bb.BBHandledException:
421 drain_events_errorhandling(eventHandler) 421 drain_events_errorhandling(eventHandler)
422 return 1 422 return 1
423 except Exception as e:
424 # bitbake-server comms failure
425 early_logger = bb.msg.logger_create('bitbake', sys.stdout)
426 early_logger.fatal("Attempting to set server environment: %s", e)
427 return 1
423 428
424 if params.options.quiet == 0: 429 if params.options.quiet == 0:
425 console_loglevel = loglevel 430 console_loglevel = loglevel
@@ -585,7 +590,12 @@ def main(server, eventHandler, params, tf = TerminalFilter):
585 return 590 return
586 591
587 llevel, debug_domains = bb.msg.constructLogOptions() 592 llevel, debug_domains = bb.msg.constructLogOptions()
588 server.runCommand(["setEventMask", server.getEventHandle(), llevel, debug_domains, _evt_list]) 593 try:
594 server.runCommand(["setEventMask", server.getEventHandle(), llevel, debug_domains, _evt_list])
595 except (BrokenPipeError, EOFError) as e:
596 # bitbake-server comms failure
597 logger.fatal("Attempting to set event mask: %s", e)
598 return 1
589 599
590 # The logging_tree module is *extremely* helpful in debugging logging 600 # The logging_tree module is *extremely* helpful in debugging logging
591 # domains. Uncomment here to dump the logging tree when bitbake starts 601 # domains. Uncomment here to dump the logging tree when bitbake starts
@@ -594,7 +604,11 @@ def main(server, eventHandler, params, tf = TerminalFilter):
594 604
595 universe = False 605 universe = False
596 if not params.observe_only: 606 if not params.observe_only:
597 params.updateFromServer(server) 607 try:
608 params.updateFromServer(server)
609 except Exception as e:
610 logger.fatal("Fetching command line: %s", e)
611 return 1
598 cmdline = params.parseActions() 612 cmdline = params.parseActions()
599 if not cmdline: 613 if not cmdline:
600 print("Nothing to do. Use 'bitbake world' to build everything, or run 'bitbake --help' for usage information.") 614 print("Nothing to do. Use 'bitbake world' to build everything, or run 'bitbake --help' for usage information.")
@@ -605,7 +619,12 @@ def main(server, eventHandler, params, tf = TerminalFilter):
605 if cmdline['action'][0] == "buildTargets" and "universe" in cmdline['action'][1]: 619 if cmdline['action'][0] == "buildTargets" and "universe" in cmdline['action'][1]:
606 universe = True 620 universe = True
607 621
608 ret, error = server.runCommand(cmdline['action']) 622 try:
623 ret, error = server.runCommand(cmdline['action'])
624 except (BrokenPipeError, EOFError) as e:
625 # bitbake-server comms failure
626 logger.fatal("Command '{}' failed: %s".format(cmdline), e)
627 return 1
609 if error: 628 if error:
610 logger.error("Command '%s' failed: %s" % (cmdline, error)) 629 logger.error("Command '%s' failed: %s" % (cmdline, error))
611 return 1 630 return 1
@@ -854,15 +873,26 @@ def main(server, eventHandler, params, tf = TerminalFilter):
854 873
855 logger.error("Unknown event: %s", event) 874 logger.error("Unknown event: %s", event)
856 875
876 except (BrokenPipeError, EOFError) as e:
877 # bitbake-server comms failure, don't attempt further comms and exit
878 logger.fatal("Executing event: %s", e)
879 return_value = 1
880 errors = errors + 1
881 main.shutdown = 3
857 except EnvironmentError as ioerror: 882 except EnvironmentError as ioerror:
858 termfilter.clearFooter() 883 termfilter.clearFooter()
859 # ignore interrupted io 884 # ignore interrupted io
860 if ioerror.args[0] == 4: 885 if ioerror.args[0] == 4:
861 continue 886 continue
862 sys.stderr.write(str(ioerror)) 887 sys.stderr.write(str(ioerror))
863 if not params.observe_only:
864 _, error = server.runCommand(["stateForceShutdown"])
865 main.shutdown = 2 888 main.shutdown = 2
889 if not params.observe_only:
890 try:
891 _, error = server.runCommand(["stateForceShutdown"])
892 except (BrokenPipeError, EOFError) as e:
893 # bitbake-server comms failure, don't attempt further comms and exit
894 logger.fatal("Unable to force shutdown: %s", e)
895 main.shutdown = 3
866 except KeyboardInterrupt: 896 except KeyboardInterrupt:
867 termfilter.clearFooter() 897 termfilter.clearFooter()
868 if params.observe_only: 898 if params.observe_only:
@@ -871,9 +901,13 @@ def main(server, eventHandler, params, tf = TerminalFilter):
871 901
872 def state_force_shutdown(): 902 def state_force_shutdown():
873 print("\nSecond Keyboard Interrupt, stopping...\n") 903 print("\nSecond Keyboard Interrupt, stopping...\n")
874 _, error = server.runCommand(["stateForceShutdown"]) 904 try:
875 if error: 905 _, error = server.runCommand(["stateForceShutdown"])
876 logger.error("Unable to cleanly stop: %s" % error) 906 if error:
907 logger.error("Unable to cleanly stop: %s" % error)
908 except (BrokenPipeError, EOFError) as e:
909 # bitbake-server comms failure
910 logger.fatal("Unable to cleanly stop: %s", e)
877 911
878 if not params.observe_only and main.shutdown == 1: 912 if not params.observe_only and main.shutdown == 1:
879 state_force_shutdown() 913 state_force_shutdown()
@@ -886,6 +920,9 @@ def main(server, eventHandler, params, tf = TerminalFilter):
886 _, error = server.runCommand(["stateShutdown"]) 920 _, error = server.runCommand(["stateShutdown"])
887 if error: 921 if error:
888 logger.error("Unable to cleanly shutdown: %s" % error) 922 logger.error("Unable to cleanly shutdown: %s" % error)
923 except (BrokenPipeError, EOFError) as e:
924 # bitbake-server comms failure
925 logger.fatal("Unable to cleanly shutdown: %s", e)
889 except KeyboardInterrupt: 926 except KeyboardInterrupt:
890 state_force_shutdown() 927 state_force_shutdown()
891 928
@@ -893,9 +930,14 @@ def main(server, eventHandler, params, tf = TerminalFilter):
893 except Exception as e: 930 except Exception as e:
894 import traceback 931 import traceback
895 sys.stderr.write(traceback.format_exc()) 932 sys.stderr.write(traceback.format_exc())
896 if not params.observe_only:
897 _, error = server.runCommand(["stateForceShutdown"])
898 main.shutdown = 2 933 main.shutdown = 2
934 if not params.observe_only:
935 try:
936 _, error = server.runCommand(["stateForceShutdown"])
937 except (BrokenPipeError, EOFError) as e:
938 # bitbake-server comms failure, don't attempt further comms and exit
939 logger.fatal("Unable to force shutdown: %s", e)
940 main.shudown = 3
899 return_value = 1 941 return_value = 1
900 try: 942 try:
901 termfilter.clearFooter() 943 termfilter.clearFooter()