comparison mercurial/profiling.py @ 51836:1bb71046f5e0 stable

profiling: improve 3.12 error message for calling lsprof twice Python 3.12 prevent lsprof to be enabled if it is already enabled. This break the use of lsprof in `hg serve` as both the initial `serve` command and the request serving want to profile. The "stat" profiler (the default) does not have this problem, so we focus on improving the error message for now.
author Pierre-Yves David <pierre-yves.david@octobus.net>
date Wed, 11 Sep 2024 12:02:38 +0200
parents 1574718fa62f
children 3785814bc2b7
comparison
equal deleted inserted replaced
51835:17e2d5c46716 51836:1bb71046f5e0
5 # This software may be used and distributed according to the terms of the 5 # This software may be used and distributed according to the terms of the
6 # GNU General Public License version 2 or any later version. 6 # GNU General Public License version 2 or any later version.
7 7
8 8
9 import contextlib 9 import contextlib
10 import sys
10 11
11 from .i18n import _ 12 from .i18n import _
12 from .pycompat import ( 13 from .pycompat import (
13 open, 14 open,
14 ) 15 )
52 b'lsprof not available - install from ' 53 b'lsprof not available - install from '
53 b'http://codespeak.net/svn/user/arigo/hack/misc/lsprof/' 54 b'http://codespeak.net/svn/user/arigo/hack/misc/lsprof/'
54 ) 55 )
55 ) 56 )
56 p = lsprof.Profiler() 57 p = lsprof.Profiler()
57 p.enable(subcalls=True) 58 try:
59 p.enable(subcalls=True)
60 except ValueError as exc:
61 if str(exc) != "Another profiling tool is already active":
62 raise
63 if not hasattr(sys, "monitoring"):
64 raise
65 # python >=3.12 prevent more than one profiler to run at the same
66 # time, tries to improve the report to help the user understand
67 # what is going on.
68 other_tool_name = sys.monitoring.get_tool(sys.monitoring.PROFILER_ID)
69 if other_tool_name == "cProfile":
70 msg = 'cannot recursively call `lsprof`'
71 raise error.Abort(msg) from None
72 else:
73 m = 'failed to start "lsprofile"; another profiler already running: %s'
74 raise error.Abort(_(m) % other_tool_name) from None
58 try: 75 try:
59 yield 76 yield
60 finally: 77 finally:
61 p.disable() 78 p.disable()
62 79