Movatterモバイル変換


[0]ホーム

URL:


Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Commit4a94a22

Browse files
committed
feat: detect sanitizer instrumentation in build
1 parent476df47 commit4a94a22

File tree

4 files changed

+82
-15
lines changed

4 files changed

+82
-15
lines changed

‎src/ffpuppet/core.py‎

Lines changed: 16 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,7 @@
2525
from .checksimportCheckLogContents,CheckLogSize,CheckMemoryUsage
2626
from .displayimportDISPLAYS,DisplayMode
2727
from .exceptionsimportBrowserExecutionError,InvalidPrefs,LaunchError
28-
from .helpersimportprepare_environment,wait_on_files
28+
from .helpersimportdetect_sanitizer,prepare_environment,wait_on_files
2929
from .minidump_parserimportMDSW_URL,MinidumpParser
3030
from .process_treeimportProcessTree
3131
from .profileimportProfile
@@ -292,7 +292,10 @@ def available_logs(self) -> frozenset[str]:
292292
returnself._logs.available_logs()
293293

294294
defbuild_launch_cmd(
295-
self,bin_path:str,additional_args:Sequence[str]|None=None
295+
self,
296+
bin_path:str,
297+
additional_args:Sequence[str]|None=None,
298+
sanitizer:str|None=None,
296299
)->list[str]:
297300
"""Build a command that can be used to launch the browser.
298301
@@ -402,9 +405,9 @@ def build_launch_cmd(
402405
"rr",
403406
"record",
404407
]
405-
ifgetenv("RR_ASAN")=="1":
408+
ifsanitizer=="asan"orgetenv("RR_ASAN")=="1":
406409
rr_cmd.append("--asan")
407-
ifgetenv("RR_TSAN")=="1":
410+
ifsanitizer=="tsan"orgetenv("RR_TSAN")=="1":
408411
rr_cmd.append("--tsan")
409412
ifgetenv("RR_CHAOS")=="1":
410413
rr_cmd.append("--chaos")
@@ -730,6 +733,9 @@ def launch(
730733
bin_path=bin_path.resolve()
731734
ifnotbin_path.is_file()ornotaccess(bin_path,X_OK):
732735
raiseOSError(f"{bin_path} is not an executable")
736+
detected_sanitizer=detect_sanitizer(bin_path)
737+
LOG.debug("detected sanitizer: %s",detected_sanitizer)
738+
733739
# need the path to help find symbols
734740
self._bin_path=bin_path.parent
735741

@@ -805,7 +811,11 @@ def launch(
805811

806812
self.profile.add_prefs(prefs)
807813

808-
cmd=self.build_launch_cmd(str(bin_path),additional_args=launch_args)
814+
cmd=self.build_launch_cmd(
815+
str(bin_path),
816+
additional_args=launch_args,
817+
sanitizer=detected_sanitizer,
818+
)
809819

810820
# open logs
811821
self._logs.add_log("stdout")
@@ -827,6 +837,7 @@ def launch(
827837
env=prepare_environment(
828838
self._logs.path/self._logs.PREFIX_SAN,
829839
env_mod=env_mod,
840+
sanitizer=detected_sanitizer,
830841
),
831842
shell=False,
832843
stderr=stderr,

‎src/ffpuppet/helpers.py‎

Lines changed: 40 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@
88
importsys
99
fromcontextlibimportsuppress
1010
fromloggingimportgetLogger
11+
frommmapimportACCESS_READ,mmap
1112
fromosimportenviron
1213
frompathlibimportPath
1314
fromsubprocessimportSTDOUT,CalledProcessError,check_output
@@ -28,14 +29,16 @@
2829
else:
2930
IS_WINDOWS=False
3031

32+
__author__="Tyson Smith"
33+
3134
CERTUTIL="certutil.exe"ifIS_WINDOWSelse"certutil"
3235
LOG=getLogger(__name__)
3336

34-
__author__="Tyson Smith"
35-
3637

3738
def_configure_sanitizers(
38-
orig_env:Mapping[str,str],log_path:Path
39+
orig_env:Mapping[str,str],
40+
log_path:Path,
41+
symbolize:bool=False,
3942
)->dict[str,str]:
4043
"""Copy environment and update default values in *SAN_OPTIONS entries.
4144
These values are only updated if they are not provided, with the exception of
@@ -44,13 +47,15 @@ def _configure_sanitizers(
4447
Args:
4548
orig_env: Current environment.
4649
log_path: Location to write sanitizer logs to.
50+
symbolize: Enable automatic symbolizing. This should only used when required to
51+
minimize memory usage.
4752
4853
Returns:
4954
Environment with *SAN_OPTIONS defaults set.
5055
"""
5156
env=dict(orig_env)
5257
# https://github.com/google/sanitizers/wiki/SanitizerCommonFlags
53-
common_flags=[
58+
common_flags=(
5459
("abort_on_error","false"),
5560
("allocator_may_return_null","true"),
5661
("disable_coredump","true"),
@@ -64,10 +69,7 @@ def _configure_sanitizers(
6469
("handle_sigfpe","true"),
6570
# set to be safe
6671
("handle_sigill","true"),
67-
# do not automatically symbolize
68-
# this should be done after to avoid hitting memory limitations
69-
("symbolize","false"),
70-
]
72+
)
7173

7274
# setup Address Sanitizer options ONLY if not set manually in environment
7375
# https://github.com/google/sanitizers/wiki/AddressSanitizerFlags
@@ -99,6 +101,7 @@ def _configure_sanitizers(
99101
asan_config.add("strict_init_order","true")
100102
# temporarily revert to default (false) until https://bugzil.la/1767068 is fixed
101103
# asan_config.add("strict_string_checks", "true")
104+
asan_config.add("symbolize","1"ifsymbolizeelse"0")
102105
env["ASAN_OPTIONS"]=str(asan_config)
103106

104107
# setup Leak Sanitizer options ONLY if not set manually in environment
@@ -126,6 +129,7 @@ def _configure_sanitizers(
126129
tsan_config.add("log_path",f"'{log_path}'",overwrite=True)
127130
# This is an experimental feature added in Bug 1792757
128131
tsan_config.add("rss_limit_heap_profile","true")
132+
tsan_config.add("symbolize","1"ifsymbolizeelse"0")
129133
env["TSAN_OPTIONS"]=str(tsan_config)
130134

131135
# setup Undefined Behavior Sanitizer options ONLY if not set manually in environment
@@ -140,6 +144,7 @@ def _configure_sanitizers(
140144
ubsan_config.add("log_path",f"'{log_path}'",overwrite=True)
141145
ubsan_config.add("print_stacktrace","1")
142146
ubsan_config.add("report_error_type","1")
147+
ubsan_config.add("symbolize","1"ifsymbolizeelse"0")
143148
env["UBSAN_OPTIONS"]=str(ubsan_config)
144149

145150
returnenv
@@ -186,6 +191,28 @@ def certutil_find(browser_bin: Path | None = None) -> str:
186191
returnCERTUTIL
187192

188193

194+
defdetect_sanitizer(binary:Path)->str|None:
195+
"""Detect sanitizer instrumentation in browser build.
196+
197+
Args:
198+
binary: Location of browser binary.
199+
200+
Returns:
201+
Name of sanitizer in use or None.
202+
"""
203+
with (
204+
binary.open("rb")asbin_fp,
205+
mmap(bin_fp.fileno(),0,access=ACCESS_READ)asbmm,
206+
):
207+
ifbmm.find(b"__tsan_")!=-1:
208+
return"tsan"
209+
ifbmm.find(b"__asan_")!=-1:
210+
return"asan"
211+
ifbmm.find(b"__ubsan_")!=-1:
212+
return"ubsan"
213+
returnNone
214+
215+
189216
deffiles_in_use(files:Iterable[Path])->Generator[tuple[Path,int,str]]:
190217
"""Check if any of the given files are open.
191218
WARNING: This can be slow on Windows.
@@ -226,6 +253,7 @@ def files_in_use(files: Iterable[Path]) -> Generator[tuple[Path, int, str]]:
226253
defprepare_environment(
227254
sanitizer_log:Path,
228255
env_mod:Mapping[str,str|None]|None=None,
256+
sanitizer:str|None=None,
229257
)->dict[str,str]:
230258
"""Create environment that can be used when launching the browser.
231259
@@ -235,6 +263,7 @@ def prepare_environment(
235263
env_mod: Environment modifier. Add, remove and update entries
236264
in the prepared environment. Add/update by setting
237265
value or remove entry by setting value to None.
266+
sanitizer: Sanitizer in use.
238267
239268
Returns:
240269
Environment to use when launching browser.
@@ -302,7 +331,9 @@ def prepare_environment(
302331
env.pop("MOZ_CRASHREPORTER_NO_REPORT",None)
303332
env.pop("MOZ_CRASHREPORTER_SHUTDOWN",None)
304333

305-
env=_configure_sanitizers(env,sanitizer_log)
334+
# automatically symbolize traces when TSan is in use
335+
# it is required for runtime TSan suppressions
336+
env=_configure_sanitizers(env,sanitizer_log,symbolize=sanitizer=="tsan")
306337
# filter environment to avoid leaking sensitive information
307338
return {k:vfork,vinenv.items()if"_SECRET"notink}
308339

‎src/ffpuppet/test_ffpuppet.py‎

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
# This Source Code Form is subject to the terms of the Mozilla Public
22
# License, v. 2.0. If a copy of the MPL was not distributed with this file,
33
# You can obtain one at http://mozilla.org/MPL/2.0/.
4-
# pylint: disable=invalid-name,missing-docstring,protected-access
4+
# pylint: disable=missing-docstring,protected-access
55
"""ffpuppet tests"""
66

77
importos
@@ -32,6 +32,7 @@
3232

3333

3434
classReqHandler(BaseHTTPRequestHandler):
35+
# pylint: disable=invalid-name
3536
defdo_GET(self):
3637
self.send_response(200)
3738
self.end_headers()

‎src/ffpuppet/test_helpers.py‎

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@
1414
_configure_sanitizers,
1515
certutil_available,
1616
certutil_find,
17+
detect_sanitizer,
1718
files_in_use,
1819
prepare_environment,
1920
wait_on_files,
@@ -33,6 +34,13 @@ def test_helpers_01(tmp_path):
3334
assertopts.get("log_path")==f"'{tmp_path}'"
3435
assert"LSAN_OPTIONS"inenv
3536
assert"UBSAN_OPTIONS"inenv
37+
# test symbolize
38+
env=_configure_sanitizers({},tmp_path,symbolize=False)
39+
assert"symbolize=0"inenv["ASAN_OPTIONS"]
40+
assert"symbolize=0"inenv["TSAN_OPTIONS"]
41+
env=_configure_sanitizers({},tmp_path,symbolize=True)
42+
assert"symbolize=1"inenv["ASAN_OPTIONS"]
43+
assert"symbolize=1"inenv["TSAN_OPTIONS"]
3644
# test with presets environment
3745
env=_configure_sanitizers(
3846
{
@@ -239,3 +247,19 @@ def test_certutil_find_01(tmp_path):
239247
certutil_bin.parent.mkdir()
240248
certutil_bin.touch()
241249
assertcertutil_find(browser_bin)==str(certutil_bin)
250+
251+
252+
@mark.parametrize(
253+
"bin_content, result",
254+
[
255+
(b"_foo",None),
256+
(b"foo __asan_foo","asan"),
257+
(b"foo __tsan_foo","tsan"),
258+
(b"foo __ubsan_foo","ubsan"),
259+
],
260+
)
261+
deftest_detect_sanitizer_01(tmp_path,bin_content,result):
262+
"""test detect_sanitizer()"""
263+
binary=tmp_path/"file.bin"
264+
binary.write_bytes(bin_content)
265+
assertdetect_sanitizer(binary)==result

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp