-
Notifications
You must be signed in to change notification settings - Fork 2
/
Copy pathimport_system_symbols_from_simulators.py
134 lines (117 loc) · 5.65 KB
/
import_system_symbols_from_simulators.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
import logging
import os
import subprocess
import sys
import tempfile
from dataclasses import dataclass
from typing import List
import sentry_sdk
from import_system_symbols_from_ipsw import has_symbols_in_cloud_storage, symsorter, upload_to_gcs
@dataclass
class SimulatorRuntime:
arch: str
build_number: str
macos_version: str
os_name: str
os_version: str
path: str
@property
def bundle_id(self) -> str:
return f"simulator_{self.macos_version}_{self.os_version}_{self.build_number}_{self.arch}"
_simulator_runtime_prefix = "com.apple.CoreSimulator.SimRuntime."
_dyld_shared_cache_prefix = "dyld_sim_shared_cache_"
def main():
logging.basicConfig(level=logging.INFO, format="[sentry] %(message)s")
caches_path = os.path.expanduser("~/Library/Developer/CoreSimulator/Caches/dyld")
if not os.path.isdir(caches_path):
sys.exit(f"{caches_path} does not exist")
with sentry_sdk.start_transaction(
op="task", name="import symbols from simulators"
) as transaction:
with tempfile.TemporaryDirectory(prefix="_sentry_dyld_shared_cache_") as output_dir:
for runtime in find_simulator_runtimes(caches_path):
with transaction.start_child(
op="task", description="Process runtime"
) as runtime_span:
runtime_span.set_data("runtime", runtime)
for filename in os.listdir(runtime.path):
if not filename.startswith(_dyld_shared_cache_prefix):
continue
if os.path.splitext(filename)[1] == ".map":
continue
with runtime_span.start_child(
op="task", description="Process file"
) as file_span:
runtime.arch = filename.split(_dyld_shared_cache_prefix)[1]
file_span.set_data("file", filename)
file_span.set_data("architecture", runtime.arch)
with file_span.start_child(
op="task", description="Check if version has symbols already"
):
if has_symbols_in_cloud_storage(runtime.os_name, runtime.bundle_id):
logging.info(
f"Already have symbols for {runtime.os_name} {runtime.os_version} {runtime.arch} from macOS {runtime.macos_version}, skipping"
)
continue
logging.info(
f"Extracting symbols for macOS {runtime.macos_version}, {runtime.os_name} {runtime.os_version} {runtime.arch}"
)
with file_span.start_child(op="task", description="Extract symbols"):
extract_system_symbols(runtime, output_dir)
with transaction.start_child(op="task", description="Upload results to GCS"):
upload_to_gcs(output_dir)
def find_simulator_runtimes(caches_path: str) -> List[SimulatorRuntime]:
runtimes: List[SimulatorRuntime] = []
for macos_version in os.listdir(caches_path):
if macos_version == ".DS_Store":
continue
for simruntime_name in os.listdir(os.path.join(caches_path, macos_version)):
if not simruntime_name.startswith(_simulator_runtime_prefix):
continue
splits = simruntime_name.split(".")
build_number = splits[5]
os_info = splits[4].split("-")
os_version = ".".join(os_info[1:3])
os_name = os_info[0].lower()
path = os.path.join(caches_path, macos_version, simruntime_name)
for filename in os.listdir(path):
if not filename.startswith(_dyld_shared_cache_prefix):
continue
arch = filename.split(_dyld_shared_cache_prefix)[1]
runtimes.append(
SimulatorRuntime(
arch=arch,
build_number=build_number,
macos_version=macos_version,
os_name=os_name,
os_version=os_version,
path=path,
)
)
break
return runtimes
def extract_system_symbols(runtime: SimulatorRuntime, output_dir: str) -> None:
span = sentry_sdk.Hub.current.scope.span
for filename in os.listdir(runtime.path):
if not filename.startswith(_dyld_shared_cache_prefix):
continue
if os.path.splitext(filename)[1] == ".map":
continue
with span.start_child(
op="task", description="Extract symbols from runtime file"
) as file_span:
file_span.set_data("runtime_file", filename)
with tempfile.TemporaryDirectory(prefix="_sentry_dyld_output") as dsc_out_dir:
full_path = os.path.join(runtime.path, filename)
with file_span.start_child(
op="task", description="Run dyld-shared-cache-extractor"
):
subprocess.check_call(["dyld-shared-cache-extractor", full_path, dsc_out_dir])
with file_span.start_child(op="task", description="Run symsorter"):
symsorter(output_dir, runtime.os_name, runtime.bundle_id, dsc_out_dir)
if __name__ == "__main__":
sentry_sdk.init(
dsn="https://[email protected]/6418660",
traces_sample_rate=1.0,
)
main()