diff --git a/mercurial/profiling.py b/mercurial/profiling.py --- a/mercurial/profiling.py +++ b/mercurial/profiling.py @@ -10,6 +10,7 @@ import contextlib import os import signal import subprocess +import sys from .i18n import _ from .pycompat import ( @@ -57,7 +58,23 @@ def lsprofile(ui, fp): ) ) p = lsprof.Profiler() - p.enable(subcalls=True) + try: + p.enable(subcalls=True) + except ValueError as exc: + if str(exc) != "Another profiling tool is already active": + raise + if not hasattr(sys, "monitoring"): + raise + # python >=3.12 prevent more than one profiler to run at the same + # time, tries to improve the report to help the user understand + # what is going on. + other_tool_name = sys.monitoring.get_tool(sys.monitoring.PROFILER_ID) + if other_tool_name == "cProfile": + msg = 'cannot recursively call `lsprof`' + raise error.Abort(msg) from None + else: + m = 'failed to start "lsprofile"; another profiler already running: %s' + raise error.Abort(_(m) % other_tool_name) from None try: yield finally: diff --git a/tests/test-profile.t b/tests/test-profile.t --- a/tests/test-profile.t +++ b/tests/test-profile.t @@ -50,16 +50,30 @@ In alias #endif -#if lsprof serve +#if serve Profiling of HTTP requests works - $ prof --config profiling.format=text --config profiling.output=../profile.log serve -d -p $HGPORT --pid-file ../hg.pid -A ../access.log + $ stats_prof () { + > hg --config profiling.type=stat --profile $@ + > } + + $ stats_prof \ + > --config profiling.format=text \ + > --config profiling.output=../profile.log \ + > serve -d \ + > -p $HGPORT \ + > --pid-file ../hg.pid \ + > -A ../access.log \ + > --errorlog ../error.log $ cat ../hg.pid >> $DAEMON_PIDS $ hg -q clone -U http://localhost:$HGPORT ../clone + $ cat ../error.log A single profile is logged because file logging doesn't append - $ grep CallCount ../profile.log | wc -l + $ grep 'Sample count:' ../profile.log | wc -l + \s*1 (re) + $ grep 'Total time:' ../profile.log | wc -l \s*1 (re) #endif