mirror of
https://github.com/python/cpython.git
synced 2025-07-19 17:25:54 +00:00

Some checks are pending
Tests / (push) Blocked by required conditions
Tests / Windows MSI (push) Blocked by required conditions
Tests / Change detection (push) Waiting to run
Tests / Docs (push) Blocked by required conditions
Tests / Check if Autoconf files are up to date (push) Blocked by required conditions
Tests / Check if generated files are up to date (push) Blocked by required conditions
Tests / Ubuntu SSL tests with OpenSSL (push) Blocked by required conditions
Tests / WASI (push) Blocked by required conditions
Tests / Hypothesis tests on Ubuntu (push) Blocked by required conditions
Tests / Address sanitizer (push) Blocked by required conditions
Tests / Undefined behavior sanitizer (push) Blocked by required conditions
Tests / Cross build Linux (push) Blocked by required conditions
Tests / CIFuzz (push) Blocked by required conditions
Tests / All required checks pass (push) Blocked by required conditions
Lint / lint (push) Waiting to run
mypy / Run mypy on Lib/_pyrepl (push) Waiting to run
mypy / Run mypy on Lib/test/libregrtest (push) Waiting to run
mypy / Run mypy on Lib/tomllib (push) Waiting to run
mypy / Run mypy on Tools/build (push) Waiting to run
mypy / Run mypy on Tools/cases_generator (push) Waiting to run
mypy / Run mypy on Tools/clinic (push) Waiting to run
mypy / Run mypy on Tools/jit (push) Waiting to run
mypy / Run mypy on Tools/peg_generator (push) Waiting to run
Implement a statistical sampling profiler that can profile external Python processes by PID. Uses the _remote_debugging module and converts the results to pstats-compatible format for analysis. Co-authored-by: Pablo Galindo <pablogsal@gmail.com>
37 lines
1.2 KiB
Python
37 lines
1.2 KiB
Python
import collections
|
|
import os
|
|
|
|
from .collector import Collector
|
|
|
|
|
|
class StackTraceCollector(Collector):
|
|
def __init__(self):
|
|
self.call_trees = []
|
|
self.function_samples = collections.defaultdict(int)
|
|
|
|
def collect(self, stack_frames):
|
|
for thread_id, frames in stack_frames:
|
|
if frames:
|
|
# Store the complete call stack (reverse order - root first)
|
|
call_tree = list(reversed(frames))
|
|
self.call_trees.append(call_tree)
|
|
|
|
# Count samples per function
|
|
for frame in frames:
|
|
self.function_samples[frame] += 1
|
|
|
|
|
|
class CollapsedStackCollector(StackTraceCollector):
|
|
def export(self, filename):
|
|
stack_counter = collections.Counter()
|
|
for call_tree in self.call_trees:
|
|
# Call tree is already in root->leaf order
|
|
stack_str = ";".join(
|
|
f"{os.path.basename(f[0])}:{f[2]}:{f[1]}" for f in call_tree
|
|
)
|
|
stack_counter[stack_str] += 1
|
|
|
|
with open(filename, "w") as f:
|
|
for stack, count in stack_counter.items():
|
|
f.write(f"{stack} {count}\n")
|
|
print(f"Collapsed stack output written to {filename}")
|