From f209f127e654df7424adf41de07f88714d7952ab Mon Sep 17 00:00:00 2001 From: Richard Purdie Date: Wed, 16 Jul 2025 16:15:31 +0100 Subject: bitbake: main: Add an option to specify what to profile Starting with python 3.12, profiling now stays enabled over threads yet you can't extract the profile data in the threads themselves, which makes it difficult to use for our use case. Our main loop starts the idle loop which starts the parsing threads and this means we can't profile in the main loop and the parsing threads or the idle loop at the same time due to this. Add options to the commandline so you can specify which piece of bitbake you want to enable profiling for. This allows some profiling with python 3.12 onwards rather than crashing. (Bitbake rev: 09f29a4968841ee5070f70277ba8c253bb14f017) Signed-off-by: Richard Purdie --- bitbake/bin/bitbake-server | 2 +- bitbake/lib/bb/cooker.py | 2 +- bitbake/lib/bb/main.py | 6 ++++-- bitbake/lib/bb/server/process.py | 6 +++--- 4 files changed, 9 insertions(+), 7 deletions(-) (limited to 'bitbake') diff --git a/bitbake/bin/bitbake-server b/bitbake/bin/bitbake-server index a559109e3f..01f83d982f 100755 --- a/bitbake/bin/bitbake-server +++ b/bitbake/bin/bitbake-server @@ -30,7 +30,7 @@ logfile = sys.argv[4] lockname = sys.argv[5] sockname = sys.argv[6] timeout = float(sys.argv[7]) -profile = bool(int(sys.argv[8])) +profile = sys.argv[8] xmlrpcinterface = (sys.argv[9], int(sys.argv[10])) if xmlrpcinterface[0] == "None": xmlrpcinterface = (None, xmlrpcinterface[1]) diff --git a/bitbake/lib/bb/cooker.py b/bitbake/lib/bb/cooker.py index c60fcd2719..fe33a4f34c 100644 --- a/bitbake/lib/bb/cooker.py +++ b/bitbake/lib/bb/cooker.py @@ -2027,7 +2027,7 @@ class Parser(multiprocessing.Process): self.exit = True def run(self): - bb.utils.profile_function(self.profile, self.realrun, "profile-parse-%s.log" % multiprocessing.current_process().name, process=False) + bb.utils.profile_function("parsing" in self.profile, self.realrun, "profile-parse-%s.log" % multiprocessing.current_process().name, process=False) def realrun(self): # Signal handling here is hard. We must not terminate any process or thread holding the write diff --git a/bitbake/lib/bb/main.py b/bitbake/lib/bb/main.py index bca8ebfa09..597cb27846 100755 --- a/bitbake/lib/bb/main.py +++ b/bitbake/lib/bb/main.py @@ -208,8 +208,10 @@ def create_bitbake_parser(): "failed and anything depending on it cannot be built, as much as " "possible will be built before stopping.") - exec_group.add_argument("-P", "--profile", action="store_true", - help="Profile the command and save reports.") + exec_group.add_argument("-P", "--profile", action="append", + default=[], + help="Profile the command and save reports. Specify 'main', 'idle' or 'parsing' " + "to indicate which bitbake code to profile.") exec_group.add_argument("-S", "--dump-signatures", action="append", default=[], metavar="SIGNATURE_HANDLER", diff --git a/bitbake/lib/bb/server/process.py b/bitbake/lib/bb/server/process.py index 2c5057bff1..7d1b38f78c 100644 --- a/bitbake/lib/bb/server/process.py +++ b/bitbake/lib/bb/server/process.py @@ -137,7 +137,7 @@ class ProcessServer(): serverlog("Error writing to lock file: %s" % str(e)) pass - return bb.utils.profile_function(self.cooker.configuration.profile, self.main, "profile-mainloop.log") + return bb.utils.profile_function("main" in self.cooker.configuration.profile, self.main, "profile-mainloop.log") def _idle_check(self): return len(self._idlefuns) == 0 and self.cooker.command.currentAsyncCommand is None @@ -398,7 +398,7 @@ class ProcessServer(): serverlog("".join(msg)) def idle_thread(self): - bb.utils.profile_function(self.cooker.configuration.profile, self.idle_thread_internal, "profile-idleloop.log") + bb.utils.profile_function("idle" in self.cooker.configuration.profile, self.idle_thread_internal, "profile-idleloop.log") def idle_thread_internal(self): def remove_idle_func(function): @@ -600,7 +600,7 @@ class BitBakeServer(object): os.set_inheritable(self.bitbake_lock.fileno(), True) os.set_inheritable(self.readypipein, True) serverscript = os.path.realpath(os.path.dirname(__file__) + "/../../../bin/bitbake-server") - os.execl(sys.executable, sys.executable, serverscript, "decafbad", str(self.bitbake_lock.fileno()), str(self.readypipein), self.logfile, self.bitbake_lock.name, self.sockname, str(self.server_timeout or 0), str(int(self.profile)), str(self.xmlrpcinterface[0]), str(self.xmlrpcinterface[1])) + os.execl(sys.executable, sys.executable, serverscript, "decafbad", str(self.bitbake_lock.fileno()), str(self.readypipein), self.logfile, self.bitbake_lock.name, self.sockname, str(self.server_timeout or 0), str(list(self.profile)), str(self.xmlrpcinterface[0]), str(self.xmlrpcinterface[1])) def execServer(lockfd, readypipeinfd, lockname, sockname, server_timeout, xmlrpcinterface, profile): -- cgit v1.2.3-54-g00ecf