viztracer 1.1.1__cp313-cp313-win32.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- viztracer/__init__.py +19 -0
- viztracer/__main__.py +8 -0
- viztracer/attach.py +67 -0
- viztracer/attach_process/LICENSE +203 -0
- viztracer/attach_process/__init__.py +0 -0
- viztracer/attach_process/add_code_to_python_process.py +582 -0
- viztracer/attach_process/attach_x86.dll +0 -0
- viztracer/attach_process/inject_dll_amd64.exe +0 -0
- viztracer/attach_process/linux_and_mac/lldb_prepare.py +54 -0
- viztracer/attach_process/run_code_on_dllmain_amd64.dll +0 -0
- viztracer/attach_process/run_code_on_dllmain_x86.dll +0 -0
- viztracer/cellmagic.py +70 -0
- viztracer/code_monkey.py +353 -0
- viztracer/decorator.py +164 -0
- viztracer/event_base.py +81 -0
- viztracer/functree.py +135 -0
- viztracer/html/flamegraph.html +34 -0
- viztracer/html/trace_viewer_embedder.html +203 -0
- viztracer/html/trace_viewer_full.html +10207 -0
- viztracer/main.py +701 -0
- viztracer/modules/eventnode.c +188 -0
- viztracer/modules/eventnode.h +73 -0
- viztracer/modules/pythoncapi_compat.h +1726 -0
- viztracer/modules/quicktime.c +177 -0
- viztracer/modules/quicktime.h +104 -0
- viztracer/modules/snaptrace.c +2207 -0
- viztracer/modules/snaptrace.h +134 -0
- viztracer/modules/snaptrace_member.c +483 -0
- viztracer/modules/util.c +45 -0
- viztracer/modules/util.h +22 -0
- viztracer/modules/vcompressor/vc_dump.c +1131 -0
- viztracer/modules/vcompressor/vc_dump.h +49 -0
- viztracer/modules/vcompressor/vcompressor.c +396 -0
- viztracer/modules/vcompressor/vcompressor.h +15 -0
- viztracer/patch.py +317 -0
- viztracer/report_builder.py +311 -0
- viztracer/snaptrace.cp313-win32.pyd +0 -0
- viztracer/snaptrace.pyi +77 -0
- viztracer/util.py +196 -0
- viztracer/vcompressor.cp313-win32.pyd +0 -0
- viztracer/vcompressor.pyi +10 -0
- viztracer/viewer.py +529 -0
- viztracer/vizcounter.py +20 -0
- viztracer/vizevent.py +31 -0
- viztracer/vizlogging.py +20 -0
- viztracer/vizobject.py +28 -0
- viztracer/vizplugin.py +143 -0
- viztracer/viztracer.py +472 -0
- viztracer/web_dist/LICENSE +189 -0
- viztracer/web_dist/index.html +127 -0
- viztracer/web_dist/service_worker.js +279 -0
- viztracer/web_dist/trace_processor +300 -0
- viztracer/web_dist/v52.0-6b9586def/assets/MaterialSymbolsOutlined.woff2 +0 -0
- viztracer/web_dist/v52.0-6b9586def/assets/Roboto-100.woff2 +0 -0
- viztracer/web_dist/v52.0-6b9586def/assets/Roboto-300.woff2 +0 -0
- viztracer/web_dist/v52.0-6b9586def/assets/Roboto-400.woff2 +0 -0
- viztracer/web_dist/v52.0-6b9586def/assets/Roboto-500.woff2 +0 -0
- viztracer/web_dist/v52.0-6b9586def/assets/RobotoCondensed-Light.woff2 +0 -0
- viztracer/web_dist/v52.0-6b9586def/assets/RobotoCondensed-Regular.woff2 +0 -0
- viztracer/web_dist/v52.0-6b9586def/assets/RobotoMono-Regular.woff2 +0 -0
- viztracer/web_dist/v52.0-6b9586def/assets/brand.png +0 -0
- viztracer/web_dist/v52.0-6b9586def/assets/catapult_trace_viewer.html +3946 -0
- viztracer/web_dist/v52.0-6b9586def/assets/catapult_trace_viewer.js +7539 -0
- viztracer/web_dist/v52.0-6b9586def/assets/favicon.png +0 -0
- viztracer/web_dist/v52.0-6b9586def/assets/logo-128.png +0 -0
- viztracer/web_dist/v52.0-6b9586def/assets/logo-3d.png +0 -0
- viztracer/web_dist/v52.0-6b9586def/assets/rec_atrace.png +0 -0
- viztracer/web_dist/v52.0-6b9586def/assets/rec_battery_counters.png +0 -0
- viztracer/web_dist/v52.0-6b9586def/assets/rec_board_voltage.png +0 -0
- viztracer/web_dist/v52.0-6b9586def/assets/rec_cpu_coarse.png +0 -0
- viztracer/web_dist/v52.0-6b9586def/assets/rec_cpu_fine.png +0 -0
- viztracer/web_dist/v52.0-6b9586def/assets/rec_cpu_freq.png +0 -0
- viztracer/web_dist/v52.0-6b9586def/assets/rec_cpu_voltage.png +0 -0
- viztracer/web_dist/v52.0-6b9586def/assets/rec_frame_timeline.png +0 -0
- viztracer/web_dist/v52.0-6b9586def/assets/rec_ftrace.png +0 -0
- viztracer/web_dist/v52.0-6b9586def/assets/rec_gpu_mem_total.png +0 -0
- viztracer/web_dist/v52.0-6b9586def/assets/rec_java_heap_dump.png +0 -0
- viztracer/web_dist/v52.0-6b9586def/assets/rec_lmk.png +0 -0
- viztracer/web_dist/v52.0-6b9586def/assets/rec_logcat.png +0 -0
- viztracer/web_dist/v52.0-6b9586def/assets/rec_long_trace.png +0 -0
- viztracer/web_dist/v52.0-6b9586def/assets/rec_mem_hifreq.png +0 -0
- viztracer/web_dist/v52.0-6b9586def/assets/rec_meminfo.png +0 -0
- viztracer/web_dist/v52.0-6b9586def/assets/rec_native_heap_profiler.png +0 -0
- viztracer/web_dist/v52.0-6b9586def/assets/rec_one_shot.png +0 -0
- viztracer/web_dist/v52.0-6b9586def/assets/rec_profiling.png +0 -0
- viztracer/web_dist/v52.0-6b9586def/assets/rec_ps_stats.png +0 -0
- viztracer/web_dist/v52.0-6b9586def/assets/rec_ring_buf.png +0 -0
- viztracer/web_dist/v52.0-6b9586def/assets/rec_syscalls.png +0 -0
- viztracer/web_dist/v52.0-6b9586def/assets/rec_vmstat.png +0 -0
- viztracer/web_dist/v52.0-6b9586def/assets/scheduling_latency.png +0 -0
- viztracer/web_dist/v52.0-6b9586def/assets/vscode-icon.png +0 -0
- viztracer/web_dist/v52.0-6b9586def/engine_bundle.js +3 -0
- viztracer/web_dist/v52.0-6b9586def/frontend_bundle.js +5495 -0
- viztracer/web_dist/v52.0-6b9586def/index.html +127 -0
- viztracer/web_dist/v52.0-6b9586def/manifest.json +52 -0
- viztracer/web_dist/v52.0-6b9586def/perfetto.css +5737 -0
- viztracer/web_dist/v52.0-6b9586def/stdlib_docs.json +1 -0
- viztracer/web_dist/v52.0-6b9586def/trace_config_utils.wasm +0 -0
- viztracer/web_dist/v52.0-6b9586def/trace_processor.wasm +0 -0
- viztracer/web_dist/v52.0-6b9586def/trace_processor_memory64.wasm +0 -0
- viztracer/web_dist/v52.0-6b9586def/traceconv.wasm +0 -0
- viztracer/web_dist/v52.0-6b9586def/traceconv_bundle.js +2 -0
- viztracer-1.1.1.dist-info/METADATA +326 -0
- viztracer-1.1.1.dist-info/RECORD +109 -0
- viztracer-1.1.1.dist-info/WHEEL +5 -0
- viztracer-1.1.1.dist-info/entry_points.txt +3 -0
- viztracer-1.1.1.dist-info/licenses/LICENSE +222 -0
- viztracer-1.1.1.dist-info/licenses/NOTICE.txt +27 -0
- viztracer-1.1.1.dist-info/top_level.txt +1 -0
viztracer/snaptrace.pyi
ADDED
|
@@ -0,0 +1,77 @@
|
|
|
1
|
+
# Licensed under the Apache License: http://www.apache.org/licenses/LICENSE-2.0
|
|
2
|
+
# For details: https://github.com/gaogaotiantian/viztracer/blob/master/NOTICE.txt
|
|
3
|
+
|
|
4
|
+
|
|
5
|
+
from typing import Any, Callable, Literal
|
|
6
|
+
|
|
7
|
+
|
|
8
|
+
class Tracer:
|
|
9
|
+
threadtracefunc: Callable
|
|
10
|
+
|
|
11
|
+
include_files: list[str] | None
|
|
12
|
+
exclude_files: list[str] | None
|
|
13
|
+
|
|
14
|
+
def __init__(self, tracer_entries: int, /) -> None:
|
|
15
|
+
...
|
|
16
|
+
|
|
17
|
+
def start(self) -> None:
|
|
18
|
+
...
|
|
19
|
+
|
|
20
|
+
def stop(self, stop_option: str | None) -> None:
|
|
21
|
+
...
|
|
22
|
+
|
|
23
|
+
def resume(self) -> None:
|
|
24
|
+
...
|
|
25
|
+
|
|
26
|
+
def pause(self) -> None:
|
|
27
|
+
...
|
|
28
|
+
|
|
29
|
+
def clear(self) -> None:
|
|
30
|
+
...
|
|
31
|
+
|
|
32
|
+
def load(self) -> dict[str, Any]:
|
|
33
|
+
...
|
|
34
|
+
|
|
35
|
+
def dump(self, filename: str, sanitize_function_name: bool = False) -> None:
|
|
36
|
+
...
|
|
37
|
+
|
|
38
|
+
def setignorestackcounter(self, value: int) -> int:
|
|
39
|
+
...
|
|
40
|
+
|
|
41
|
+
def reset_stack(self) -> None:
|
|
42
|
+
...
|
|
43
|
+
|
|
44
|
+
def getts(self) -> float:
|
|
45
|
+
...
|
|
46
|
+
|
|
47
|
+
def get_base_time(self) -> int:
|
|
48
|
+
...
|
|
49
|
+
|
|
50
|
+
def setpid(self, pid: int = -1, /) -> None:
|
|
51
|
+
...
|
|
52
|
+
|
|
53
|
+
def add_func_args(self, key: str, value: Any) -> None:
|
|
54
|
+
...
|
|
55
|
+
|
|
56
|
+
def get_func_args(self) -> dict[str, Any] | None:
|
|
57
|
+
...
|
|
58
|
+
|
|
59
|
+
def add_raw(self, raw: dict[str, Any]) -> None:
|
|
60
|
+
...
|
|
61
|
+
|
|
62
|
+
def add_object(self, ph: str, obj_id: str, name: str, args: dict[str, Any] | None = None) -> None:
|
|
63
|
+
...
|
|
64
|
+
|
|
65
|
+
def add_counter(self, name: str, args: dict[str, Any]) -> None:
|
|
66
|
+
...
|
|
67
|
+
|
|
68
|
+
def add_instant(self, name: str, args: Any = None, scope: Literal["g", "p", "t"] = "g") -> None:
|
|
69
|
+
...
|
|
70
|
+
|
|
71
|
+
def set_sync_marker(self) -> None:
|
|
72
|
+
"""set current timestamp to synchronization marker"""
|
|
73
|
+
...
|
|
74
|
+
|
|
75
|
+
def get_sync_marker(self) -> float | None:
|
|
76
|
+
"""get synchronization marker or None if not set"""
|
|
77
|
+
...
|
viztracer/util.py
ADDED
|
@@ -0,0 +1,196 @@
|
|
|
1
|
+
# Licensed under the Apache License: http://www.apache.org/licenses/LICENSE-2.0
|
|
2
|
+
# For details: https://github.com/gaogaotiantian/viztracer/blob/master/NOTICE.txt
|
|
3
|
+
|
|
4
|
+
|
|
5
|
+
import datetime
|
|
6
|
+
import errno
|
|
7
|
+
import os
|
|
8
|
+
import re
|
|
9
|
+
import sys
|
|
10
|
+
|
|
11
|
+
# Windows macros
|
|
12
|
+
STILL_ACTIVE = 0x103
|
|
13
|
+
ERROR_ACCESS_DENIED = 0x5
|
|
14
|
+
PROCESS_QUERY_LIMITED_INFORMATION = 0x1000
|
|
15
|
+
|
|
16
|
+
|
|
17
|
+
def size_fmt(num: int | float, suffix: str = 'B') -> str:
|
|
18
|
+
for unit in ['', 'Ki', 'Mi', 'Gi']:
|
|
19
|
+
if abs(num) < 1024.0:
|
|
20
|
+
return f"{num:3.1f}{unit}{suffix}"
|
|
21
|
+
num /= 1024.0
|
|
22
|
+
return f"{num:.1f}{'Ti'}{suffix}"
|
|
23
|
+
|
|
24
|
+
|
|
25
|
+
class _bcolors:
|
|
26
|
+
HEADER = '\033[95m'
|
|
27
|
+
OKBLUE = '\033[94m'
|
|
28
|
+
OKGREEN = '\033[92m'
|
|
29
|
+
WARNING = '\033[93m'
|
|
30
|
+
FAIL = '\033[91m'
|
|
31
|
+
ENDC = '\033[0m'
|
|
32
|
+
BOLD = '\033[1m'
|
|
33
|
+
UNDERLINE = '\033[4m'
|
|
34
|
+
|
|
35
|
+
|
|
36
|
+
bcolors = _bcolors()
|
|
37
|
+
|
|
38
|
+
|
|
39
|
+
color_support = True
|
|
40
|
+
|
|
41
|
+
|
|
42
|
+
if sys.platform == "win32":
|
|
43
|
+
try:
|
|
44
|
+
# https://stackoverflow.com/questions/36760127/...
|
|
45
|
+
# how-to-use-the-new-support-for-ansi-escape-sequences-in-the-windows-10-console
|
|
46
|
+
from ctypes import windll
|
|
47
|
+
kernel32 = windll.kernel32
|
|
48
|
+
kernel32.SetConsoleMode(kernel32.GetStdHandle(-11), 7)
|
|
49
|
+
except Exception: # pragma: no cover
|
|
50
|
+
color_support = False
|
|
51
|
+
|
|
52
|
+
|
|
53
|
+
def color_print(color, s: str, **kwargs) -> None:
|
|
54
|
+
if color_support:
|
|
55
|
+
print(bcolors.__getattribute__(color) + s + bcolors.ENDC, **kwargs)
|
|
56
|
+
else: # pragma: no cover
|
|
57
|
+
print(s)
|
|
58
|
+
|
|
59
|
+
|
|
60
|
+
def same_line_print(s: str, width: int = 80, **kwargs) -> None:
|
|
61
|
+
print(f"\r{'':<{width}}", end="") # clear the line
|
|
62
|
+
print(f"\r{s}", end="", **kwargs)
|
|
63
|
+
|
|
64
|
+
|
|
65
|
+
def unique_file_name(exec_name: str) -> str:
|
|
66
|
+
# Get the base name of the executable
|
|
67
|
+
filename = os.path.basename(exec_name)
|
|
68
|
+
|
|
69
|
+
# Remove the extension
|
|
70
|
+
filename = filename.split(".")[0]
|
|
71
|
+
|
|
72
|
+
d = datetime.datetime.now()
|
|
73
|
+
return "_".join([
|
|
74
|
+
f"{filename}",
|
|
75
|
+
f"{d.year}{d.month:02d}{d.day:02d}",
|
|
76
|
+
f"{d.hour:02d}{d.minute:02d}{d.second:02d}",
|
|
77
|
+
f"{os.getpid()}.json"
|
|
78
|
+
])
|
|
79
|
+
|
|
80
|
+
|
|
81
|
+
def compare_version(ver1: str, ver2: str) -> int:
|
|
82
|
+
# assuming ver1, ver2 are both str and in a pattern of
|
|
83
|
+
# major.minor.micro with only numbers
|
|
84
|
+
# return 1 if ver1 > ver2
|
|
85
|
+
# return 0 if ver1 == ver2
|
|
86
|
+
# return -1 if ver1 < ver2
|
|
87
|
+
tuple1 = tuple((int(v) for v in ver1.split(".")))
|
|
88
|
+
tuple2 = tuple((int(v) for v in ver2.split(".")))
|
|
89
|
+
|
|
90
|
+
if tuple1 > tuple2:
|
|
91
|
+
return 1
|
|
92
|
+
elif tuple1 == tuple2:
|
|
93
|
+
return 0
|
|
94
|
+
else:
|
|
95
|
+
return -1
|
|
96
|
+
|
|
97
|
+
|
|
98
|
+
def time_str_to_us(t_s: str) -> float:
|
|
99
|
+
# t_s is a string representing a time
|
|
100
|
+
# Should be [0-9\.]+([mun]?s)?
|
|
101
|
+
# ex. 300ns 23.5 .2ms
|
|
102
|
+
# (This is not a perfect match, but enough for us to duck parse)
|
|
103
|
+
# We need to convert it to us
|
|
104
|
+
m = re.match(r"([0-9\.]+)([mun]?s)?", t_s)
|
|
105
|
+
if m:
|
|
106
|
+
try:
|
|
107
|
+
val = float(m.group(1))
|
|
108
|
+
except ValueError:
|
|
109
|
+
raise ValueError(f"Can't convert {t_s} to time")
|
|
110
|
+
unit = m.group(2)
|
|
111
|
+
if unit == "s":
|
|
112
|
+
val *= 1e6
|
|
113
|
+
elif unit == "ms":
|
|
114
|
+
val *= 1e3
|
|
115
|
+
elif unit == "ns":
|
|
116
|
+
val *= 1e-3
|
|
117
|
+
return val
|
|
118
|
+
else:
|
|
119
|
+
raise ValueError(f"Can't convert {t_s} to time")
|
|
120
|
+
|
|
121
|
+
|
|
122
|
+
# https://github.com/giampaolo/psutil
|
|
123
|
+
def pid_exists(pid):
|
|
124
|
+
"""Check whether pid exists in the current process table.
|
|
125
|
+
"""
|
|
126
|
+
if pid < 0:
|
|
127
|
+
return False
|
|
128
|
+
if pid == 0:
|
|
129
|
+
# According to "man 2 kill" PID 0 refers to every process
|
|
130
|
+
# in the process group of the calling process.
|
|
131
|
+
# On certain systems 0 is a valid PID but we have no way
|
|
132
|
+
# to know that in a portable fashion.
|
|
133
|
+
# On Windows, 0 is an idle process buw we don't need to
|
|
134
|
+
# check it here
|
|
135
|
+
raise ValueError('invalid PID 0')
|
|
136
|
+
if sys.platform == "win32":
|
|
137
|
+
# Windows
|
|
138
|
+
import ctypes
|
|
139
|
+
kernel32 = ctypes.windll.kernel32
|
|
140
|
+
|
|
141
|
+
process = kernel32.OpenProcess(PROCESS_QUERY_LIMITED_INFORMATION, 0, pid)
|
|
142
|
+
if not process:
|
|
143
|
+
if kernel32.GetLastError() == ERROR_ACCESS_DENIED:
|
|
144
|
+
# Access is denied, which means there's a process.
|
|
145
|
+
# Usually it's impossible to run here in viztracer.
|
|
146
|
+
return True # pragma: no cover
|
|
147
|
+
else:
|
|
148
|
+
return False
|
|
149
|
+
|
|
150
|
+
exit_code = ctypes.c_ulong()
|
|
151
|
+
out = kernel32.GetExitCodeProcess(process, ctypes.byref(exit_code))
|
|
152
|
+
kernel32.CloseHandle(process)
|
|
153
|
+
# nonzero return value means the funtion succeeds
|
|
154
|
+
if out:
|
|
155
|
+
if exit_code.value == STILL_ACTIVE:
|
|
156
|
+
# According to documents of GetExitCodeProcess.
|
|
157
|
+
# If a thread returns STILL_ACTIVE (259) as an error code,
|
|
158
|
+
# then applications that test for that value could interpret
|
|
159
|
+
# it to mean that the thread is still running, and continue
|
|
160
|
+
# to test for the completion of the thread after the thread
|
|
161
|
+
# has terminated, which could put the application into an
|
|
162
|
+
# infinite loop.
|
|
163
|
+
return True
|
|
164
|
+
else:
|
|
165
|
+
return False
|
|
166
|
+
else: # pragma: no cover
|
|
167
|
+
if kernel32.GetLastError() == ERROR_ACCESS_DENIED:
|
|
168
|
+
# Access is denied, which means there's a process.
|
|
169
|
+
# Usually it's impossible to run here in viztracer.
|
|
170
|
+
return True
|
|
171
|
+
return False # pragma: no cover
|
|
172
|
+
else:
|
|
173
|
+
# UNIX
|
|
174
|
+
try:
|
|
175
|
+
os.kill(pid, 0)
|
|
176
|
+
except OSError as err:
|
|
177
|
+
if err.errno == errno.ESRCH:
|
|
178
|
+
# ESRCH == No such process
|
|
179
|
+
return False
|
|
180
|
+
elif err.errno == errno.EPERM:
|
|
181
|
+
# EPERM clearly means there's a process to deny access to
|
|
182
|
+
return True
|
|
183
|
+
else: # pragma: no cover
|
|
184
|
+
# According to "man 2 kill" possible error values are
|
|
185
|
+
# (EINVAL, EPERM, ESRCH)
|
|
186
|
+
raise
|
|
187
|
+
else:
|
|
188
|
+
return True
|
|
189
|
+
|
|
190
|
+
|
|
191
|
+
def frame_stack_has_func(frame, funcs):
|
|
192
|
+
while frame:
|
|
193
|
+
if any(frame.f_code == func.__code__ for func in funcs):
|
|
194
|
+
return True
|
|
195
|
+
frame = frame.f_back
|
|
196
|
+
return False
|
|
Binary file
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
# Licensed under the Apache License: http://www.apache.org/licenses/LICENSE-2.0
|
|
2
|
+
# For details: https://github.com/gaogaotiantian/viztracer/blob/master/NOTICE.txt
|
|
3
|
+
|
|
4
|
+
|
|
5
|
+
class VCompressor:
|
|
6
|
+
def compress(self, raw_data: dict, filename: str) -> dict:
|
|
7
|
+
...
|
|
8
|
+
|
|
9
|
+
def decompress(self, filename: str) -> dict:
|
|
10
|
+
...
|