xref: /aosp_15_r20/external/libchrome/build/android/pylib/valgrind_tools.py (revision 635a864187cb8b6c713ff48b7e790a6b21769273)
1*635a8641SAndroid Build Coastguard Worker# Copyright (c) 2012 The Chromium Authors. All rights reserved.
2*635a8641SAndroid Build Coastguard Worker# Use of this source code is governed by a BSD-style license that can be
3*635a8641SAndroid Build Coastguard Worker# found in the LICENSE file.
4*635a8641SAndroid Build Coastguard Worker
5*635a8641SAndroid Build Coastguard Worker# pylint: disable=R0201
6*635a8641SAndroid Build Coastguard Worker
7*635a8641SAndroid Build Coastguard Workerimport glob
8*635a8641SAndroid Build Coastguard Workerimport logging
9*635a8641SAndroid Build Coastguard Workerimport os.path
10*635a8641SAndroid Build Coastguard Workerimport subprocess
11*635a8641SAndroid Build Coastguard Workerimport sys
12*635a8641SAndroid Build Coastguard Worker
13*635a8641SAndroid Build Coastguard Workerfrom devil.android import device_errors
14*635a8641SAndroid Build Coastguard Workerfrom devil.android.valgrind_tools import base_tool
15*635a8641SAndroid Build Coastguard Workerfrom pylib.constants import DIR_SOURCE_ROOT
16*635a8641SAndroid Build Coastguard Worker
17*635a8641SAndroid Build Coastguard Worker
18*635a8641SAndroid Build Coastguard Workerdef SetChromeTimeoutScale(device, scale):
19*635a8641SAndroid Build Coastguard Worker  """Sets the timeout scale in /data/local/tmp/chrome_timeout_scale to scale."""
20*635a8641SAndroid Build Coastguard Worker  path = '/data/local/tmp/chrome_timeout_scale'
21*635a8641SAndroid Build Coastguard Worker  if not scale or scale == 1.0:
22*635a8641SAndroid Build Coastguard Worker    # Delete if scale is None/0.0/1.0 since the default timeout scale is 1.0
23*635a8641SAndroid Build Coastguard Worker    device.RemovePath(path, force=True, as_root=True)
24*635a8641SAndroid Build Coastguard Worker  else:
25*635a8641SAndroid Build Coastguard Worker    device.WriteFile(path, '%f' % scale, as_root=True)
26*635a8641SAndroid Build Coastguard Worker
27*635a8641SAndroid Build Coastguard Worker
28*635a8641SAndroid Build Coastguard Worker
29*635a8641SAndroid Build Coastguard Workerclass AddressSanitizerTool(base_tool.BaseTool):
30*635a8641SAndroid Build Coastguard Worker  """AddressSanitizer tool."""
31*635a8641SAndroid Build Coastguard Worker
32*635a8641SAndroid Build Coastguard Worker  WRAPPER_NAME = '/system/bin/asanwrapper'
33*635a8641SAndroid Build Coastguard Worker  # Disable memcmp overlap check.There are blobs (gl drivers)
34*635a8641SAndroid Build Coastguard Worker  # on some android devices that use memcmp on overlapping regions,
35*635a8641SAndroid Build Coastguard Worker  # nothing we can do about that.
36*635a8641SAndroid Build Coastguard Worker  EXTRA_OPTIONS = 'strict_memcmp=0,use_sigaltstack=1'
37*635a8641SAndroid Build Coastguard Worker
38*635a8641SAndroid Build Coastguard Worker  def __init__(self, device):
39*635a8641SAndroid Build Coastguard Worker    super(AddressSanitizerTool, self).__init__()
40*635a8641SAndroid Build Coastguard Worker    self._device = device
41*635a8641SAndroid Build Coastguard Worker
42*635a8641SAndroid Build Coastguard Worker  @classmethod
43*635a8641SAndroid Build Coastguard Worker  def CopyFiles(cls, device):
44*635a8641SAndroid Build Coastguard Worker    """Copies ASan tools to the device."""
45*635a8641SAndroid Build Coastguard Worker    libs = glob.glob(os.path.join(DIR_SOURCE_ROOT,
46*635a8641SAndroid Build Coastguard Worker                                  'third_party/llvm-build/Release+Asserts/',
47*635a8641SAndroid Build Coastguard Worker                                  'lib/clang/*/lib/linux/',
48*635a8641SAndroid Build Coastguard Worker                                  'libclang_rt.asan-arm-android.so'))
49*635a8641SAndroid Build Coastguard Worker    assert len(libs) == 1
50*635a8641SAndroid Build Coastguard Worker    subprocess.call(
51*635a8641SAndroid Build Coastguard Worker        [os.path.join(
52*635a8641SAndroid Build Coastguard Worker             DIR_SOURCE_ROOT,
53*635a8641SAndroid Build Coastguard Worker             'tools/android/asan/third_party/asan_device_setup.sh'),
54*635a8641SAndroid Build Coastguard Worker         '--device', str(device),
55*635a8641SAndroid Build Coastguard Worker         '--lib', libs[0],
56*635a8641SAndroid Build Coastguard Worker         '--extra-options', AddressSanitizerTool.EXTRA_OPTIONS])
57*635a8641SAndroid Build Coastguard Worker    device.WaitUntilFullyBooted()
58*635a8641SAndroid Build Coastguard Worker
59*635a8641SAndroid Build Coastguard Worker  def GetTestWrapper(self):
60*635a8641SAndroid Build Coastguard Worker    return AddressSanitizerTool.WRAPPER_NAME
61*635a8641SAndroid Build Coastguard Worker
62*635a8641SAndroid Build Coastguard Worker  def GetUtilWrapper(self):
63*635a8641SAndroid Build Coastguard Worker    """Returns the wrapper for utilities, such as forwarder.
64*635a8641SAndroid Build Coastguard Worker
65*635a8641SAndroid Build Coastguard Worker    AddressSanitizer wrapper must be added to all instrumented binaries,
66*635a8641SAndroid Build Coastguard Worker    including forwarder and the like. This can be removed if such binaries
67*635a8641SAndroid Build Coastguard Worker    were built without instrumentation. """
68*635a8641SAndroid Build Coastguard Worker    return self.GetTestWrapper()
69*635a8641SAndroid Build Coastguard Worker
70*635a8641SAndroid Build Coastguard Worker  def SetupEnvironment(self):
71*635a8641SAndroid Build Coastguard Worker    try:
72*635a8641SAndroid Build Coastguard Worker      self._device.EnableRoot()
73*635a8641SAndroid Build Coastguard Worker    except device_errors.CommandFailedError as e:
74*635a8641SAndroid Build Coastguard Worker      # Try to set the timeout scale anyway.
75*635a8641SAndroid Build Coastguard Worker      # TODO(jbudorick) Handle this exception appropriately after interface
76*635a8641SAndroid Build Coastguard Worker      #                 conversions are finished.
77*635a8641SAndroid Build Coastguard Worker      logging.error(str(e))
78*635a8641SAndroid Build Coastguard Worker    SetChromeTimeoutScale(self._device, self.GetTimeoutScale())
79*635a8641SAndroid Build Coastguard Worker
80*635a8641SAndroid Build Coastguard Worker  def CleanUpEnvironment(self):
81*635a8641SAndroid Build Coastguard Worker    SetChromeTimeoutScale(self._device, None)
82*635a8641SAndroid Build Coastguard Worker
83*635a8641SAndroid Build Coastguard Worker  def GetTimeoutScale(self):
84*635a8641SAndroid Build Coastguard Worker    # Very slow startup.
85*635a8641SAndroid Build Coastguard Worker    return 20.0
86*635a8641SAndroid Build Coastguard Worker
87*635a8641SAndroid Build Coastguard Worker
88*635a8641SAndroid Build Coastguard WorkerTOOL_REGISTRY = {
89*635a8641SAndroid Build Coastguard Worker    'asan': AddressSanitizerTool,
90*635a8641SAndroid Build Coastguard Worker}
91*635a8641SAndroid Build Coastguard Worker
92*635a8641SAndroid Build Coastguard Worker
93*635a8641SAndroid Build Coastguard Workerdef CreateTool(tool_name, device):
94*635a8641SAndroid Build Coastguard Worker  """Creates a tool with the specified tool name.
95*635a8641SAndroid Build Coastguard Worker
96*635a8641SAndroid Build Coastguard Worker  Args:
97*635a8641SAndroid Build Coastguard Worker    tool_name: Name of the tool to create.
98*635a8641SAndroid Build Coastguard Worker    device: A DeviceUtils instance.
99*635a8641SAndroid Build Coastguard Worker  Returns:
100*635a8641SAndroid Build Coastguard Worker    A tool for the specified tool_name.
101*635a8641SAndroid Build Coastguard Worker  """
102*635a8641SAndroid Build Coastguard Worker  if not tool_name:
103*635a8641SAndroid Build Coastguard Worker    return base_tool.BaseTool()
104*635a8641SAndroid Build Coastguard Worker
105*635a8641SAndroid Build Coastguard Worker  ctor = TOOL_REGISTRY.get(tool_name)
106*635a8641SAndroid Build Coastguard Worker  if ctor:
107*635a8641SAndroid Build Coastguard Worker    return ctor(device)
108*635a8641SAndroid Build Coastguard Worker  else:
109*635a8641SAndroid Build Coastguard Worker    print('Unknown tool %s, available tools: %s' % (
110*635a8641SAndroid Build Coastguard Worker        tool_name, ', '.join(sorted(TOOL_REGISTRY.keys()))))
111*635a8641SAndroid Build Coastguard Worker    sys.exit(1)
112*635a8641SAndroid Build Coastguard Worker
113*635a8641SAndroid Build Coastguard Workerdef PushFilesForTool(tool_name, device):
114*635a8641SAndroid Build Coastguard Worker  """Pushes the files required for |tool_name| to |device|.
115*635a8641SAndroid Build Coastguard Worker
116*635a8641SAndroid Build Coastguard Worker  Args:
117*635a8641SAndroid Build Coastguard Worker    tool_name: Name of the tool to create.
118*635a8641SAndroid Build Coastguard Worker    device: A DeviceUtils instance.
119*635a8641SAndroid Build Coastguard Worker  """
120*635a8641SAndroid Build Coastguard Worker  if not tool_name:
121*635a8641SAndroid Build Coastguard Worker    return
122*635a8641SAndroid Build Coastguard Worker
123*635a8641SAndroid Build Coastguard Worker  clazz = TOOL_REGISTRY.get(tool_name)
124*635a8641SAndroid Build Coastguard Worker  if clazz:
125*635a8641SAndroid Build Coastguard Worker    clazz.CopyFiles(device)
126*635a8641SAndroid Build Coastguard Worker  else:
127*635a8641SAndroid Build Coastguard Worker    print('Unknown tool %s, available tools: %s' % (
128*635a8641SAndroid Build Coastguard Worker        tool_name, ', '.join(sorted(TOOL_REGISTRY.keys()))))
129*635a8641SAndroid Build Coastguard Worker    sys.exit(1)
130*635a8641SAndroid Build Coastguard Worker
131