bigywater.tech
新版本特性 · 4

Python 3.15 profiling.sampling 在 macOS 上报 Permission Error 要 sudo:cProfile 搬进 profiling.tracing 后 main、label 等四个名字没了

“Python 3.15 的 profiling.sampling 在 macOS 上报 Permission Error: Unable to access process memory” 是新采样分析器第一次运行最容易撞上的错,而且 cProfile 的实现已经搬进了 profiling.tracing。这篇在本机用 3.14.9 和 3.15.0 并排看包结构、消失的名字、报告格式,以及分析的代价;采样分析器本身因为需要 sudo 没有测。

Permission Error
macOS 上不加 sudo 运行 python -m profiling.sampling 的 run、attach、dump 都是这个错,退出码 1
4 个
3.15 的 cProfile 模块里消失的名字:main、label、io、importlib
20.70 ms
3.15 上用 cProfile 分析 fib(24) 的耗时(不分析是 3.83 ms)

包结构

实测 · 本机执行输出
  Python 3.14(退出码 0):
      import profiling -> ModuleNotFoundError: No module named 'profiling'
      cProfile.Profile.__module__ = cProfile
      profiling.tracing -> ModuleNotFoundError: No module named 'profiling'
  Python 3.15(退出码 0):
      import profiling -> profiling | 子包: ['sampling', 'tracing']
      cProfile.Profile.__module__ = profiling.tracing
      cProfile.Profile is profiling.tracing.Profile = True
      cProfile.run is profiling.tracing.run = True

3.15 新增 profiling 包;cProfile 变成指向 profiling.tracing 的兼容层。

消失的名字

实测 · 本机执行输出
  Python 3.14(退出码 0):
      hasattr(cProfile, 'main') = True
      hasattr(cProfile, 'label') = True
      hasattr(cProfile, 'io') = True
      hasattr(cProfile, 'importlib') = True
      Usage: cProfile.py [-o output_file_path] [-s sort] [-m module | scriptfile] [arg] ...
      
      cProfile.main() -> SystemExit: 2
  Python 3.15(退出码 0):
      hasattr(cProfile, 'main') = False
      hasattr(cProfile, 'label') = False
      hasattr(cProfile, 'io') = False
      hasattr(cProfile, 'importlib') = False
      cProfile.main() -> AttributeError: module 'cProfile' has no attribute 'main'
      from cProfile import label -> ImportError: cannot import name 'label' from 'cProfile' (<py3.15>/lib/python3.15/cProfile.py)
  Python 3.14:python -m cProfile -s tottime w.py(退出码 0)——前几行:
               109469 function calls (19 primitive calls) in 0.291 seconds
         Ordered by: internal time
         ncalls  tottime  percall  cumtime  percall filename:lineno(function)
  Python 3.15:python -m cProfile -s tottime w.py(退出码 0)——前几行:
               109469 function calls (19 primitive calls) in 0.284 seconds
         Ordered by: internal time
         ncalls  tottime  percall  cumtime  percall filename:lineno(function)

cProfile 模块里的 main、label、io、importlib 在 3.15 里没有了;命令行用法不变。

报告格式

实测 · 本机执行输出
  Python 3.14(退出码 0):
      109469 function calls (19 primitive calls)
      1 0.000 0.000 0.302 0.302 {built-in method builtins.exec}
      1 0.000 0.000 0.302 0.302 w.py:1(<module>)
      1 0.000 0.000 0.302 0.302 w.py:5(main)
      5 0.000 0.000 0.273 0.055 w.py:4(io)
      109455/5 0.029 0.000 0.029 0.006 w.py:3(fib)
  Python 3.15(退出码 0):
      109469 function calls (19 primitive calls)
      1 0.000 0.000 0.288 0.288 {built-in method builtins.exec}
      1 0.000 0.000 0.288 0.288 w.py:1(<module>)
      1 0.000 0.000 0.288 0.288 w.py:5(main)
      5 0.000 0.000 0.272 0.054 w.py:4(io)
      109455/5 0.016 0.000 0.016 0.003 w.py:3(fib)

同一个脚本的 cProfile 报告在两个版本上结构一样,只有耗时不同。

采样分析器

实测 · 本机执行输出
  python3.15 -m profiling.sampling --help(子命令部分):
      positional arguments:
        {run,attach,dump,replay}
                              Command to run
          run                 Run and profile a script or module
          attach              Attach to and profile a running process
          dump                Dump a running process's current stack
          replay              Replay a binary profile and convert to another format
      
  run 的采样模式 --mode: wall,cpu,gil,exception
  run 的输出格式选项: --pstats, --collapsed, --flamegraph, --gecko, --heatmap, --jsonl, --binary | 另有 --diff-flamegraph BASELINE
  默认采样率(帮助里写的): 1khz
  python3.15 -m profiling.sampling run w.py(退出码 1):
      🔒 Permission Error: Unable to access process memory on macOS
      Tachyon needs elevated permissions to profile processes. Try one of these solutions:
  python3.15 -m profiling.sampling attach <某个 pid>(退出码 1):
      🔒 Permission Error: Unable to access process memory on macOS
      Tachyon needs elevated permissions to profile processes. Try one of these solutions:
  python3.15 -m profiling.sampling dump <某个 pid>(退出码 1):
      🔒 Permission Error: Unable to access process memory on macOS
      Tachyon needs elevated permissions to profile processes. Try one of these solutions:

profiling.sampling 有 run、attach、dump、replay;macOS 上不加 sudo 三个命令都是 Permission Error。

代价

实测 · 本机执行输出
  Python 3.14:不分析 3.07 ms,cProfile 分析 20.64 ms
  Python 3.15:不分析 3.83 ms,cProfile 分析 20.70 ms
  Python 3.15 的 pstats 读 Python 3.14 写的 .prof(退出码 0):150050 function calls (2 primitive calls)
  Python 3.14 的 pstats 读 Python 3.15 写的 .prof(退出码 0):150050 function calls (2 primitive calls)

确定性分析把同一段代码拖慢好几倍;.prof 文件在 3.14 和 3.15 之间能互读。

分步演示

profiling 包实测
本步的对象

    本文用到的工具与边界

    • 本机 macOS 27 arm64 / Homebrew 的 Python 3.14.9 与 3.15.0(同一台机器上两个解释器并排跑同一份代码;两者都不是自由线程构建,也都没有启用 JIT);每个例子是临时目录里的独立小脚本,用子进程运行并取真实的 stdout / stderr(路径换成 );计时用 time.perf_counter,数字每次运行会有小幅抖动。本篇没有用 sudo,也没有改系统的任何权限设置;profiling.sampling 的命令行选项取自它自己的 --help 输出;分析代价用同一段 fib(24),不分析和 cProfile 分析各跑 7 次取最小值
    • 没有验证:profiling.sampling 的任何采样结果(需要 sudo,本机没有这样运行);采样分析器的开销与精度;火焰图、heatmap、gecko 等输出格式的实际内容;attach 到运行中的进程之外的子进程采样(--subprocesses);Linux 上采样分析器的权限要求(ptrace);cProfile 和 profile(纯 Python 版)的差异;3.15 上不分析的 fib(24) 比 3.14 更慢的原因(只量到了结果,两个 brew 版本的编译选项也不同)
    京ICP备2026067502号-1京公网安备11010502063487号