diff mbox series

[4/4] main: Add an option to specify what to profile

Message ID 20250716152249.96126-4-richard.purdie@linuxfoundation.org
State Accepted, archived
Commit 09f29a4968841ee5070f70277ba8c253bb14f017
Headers show
Series [1/4] asyncrpc: Avoid file not found traceback in logs | expand

Commit Message

Richard Purdie July 16, 2025, 3:22 p.m. UTC
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.

Signed-off-by: Richard Purdie <richard.purdie@linuxfoundation.org>
---
 bin/bitbake-server       | 2 +-
 lib/bb/cooker.py         | 2 +-
 lib/bb/main.py           | 6 ++++--
 lib/bb/server/process.py | 6 +++---
 4 files changed, 9 insertions(+), 7 deletions(-)
diff mbox series

Patch

diff --git a/bin/bitbake-server b/bin/bitbake-server
index a559109e3f5..7a13de60de6 100755
--- a/bin/bitbake-server
+++ b/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 = list(sys.argv[8])
 xmlrpcinterface = (sys.argv[9], int(sys.argv[10]))
 if xmlrpcinterface[0] == "None":
     xmlrpcinterface = (None, xmlrpcinterface[1])
diff --git a/lib/bb/cooker.py b/lib/bb/cooker.py
index 74b2d075d00..260cba1e212 100644
--- a/lib/bb/cooker.py
+++ b/lib/bb/cooker.py
@@ -2027,7 +2027,7 @@  class Parser(multiprocessing.Process):
             self.exit = True
 
     def run(self):
-        bb.utils.profle_function(self.profile, self.realrun, "profile-parse-%s.log" % multiprocessing.current_process().name, process=False)
+        bb.utils.profle_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/lib/bb/main.py b/lib/bb/main.py
index bca8ebfa090..597cb278464 100755
--- a/lib/bb/main.py
+++ b/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/lib/bb/server/process.py b/lib/bb/server/process.py
index 78d0a606e23..da3f833f1d5 100644
--- a/lib/bb/server/process.py
+++ b/lib/bb/server/process.py
@@ -140,7 +140,7 @@  class ProcessServer():
             serverlog("Error writing to lock file: %s" % str(e))
             pass
 
-        return bb.utils.profle_function(self.cooker.configuration.profile, self.main, "profile.log")
+        return bb.utils.profle_function("main" in self.cooker.configuration.profile, self.main, "profile.log")
 
     def _idle_check(self):
         return len(self._idlefuns) == 0 and self.cooker.command.currentAsyncCommand is None
@@ -401,7 +401,7 @@  class ProcessServer():
                 serverlog("".join(msg))
 
     def idle_thread(self):
-        bb.utils.profle_function(self.cooker.configuration.profile, self.idle_thread_internal, "profile-idleloop.log")
+        bb.utils.profle_function("idle" in self.cooker.configuration.profile, self.idle_thread_internal, "profile-idleloop.log")
 
     def idle_thread_internal(self):
         def remove_idle_func(function):
@@ -603,7 +603,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):