131 lines
		
	
	
		
			3.8 KiB
		
	
	
	
		
			Python
		
	
	
	
			
		
		
	
	
			131 lines
		
	
	
		
			3.8 KiB
		
	
	
	
		
			Python
		
	
	
	
| # Copyright (c) 2012 The Chromium Authors. All rights reserved.
 | |
| # Use of this source code is governed by a BSD-style license that can be
 | |
| # found in the LICENSE file.
 | |
| 
 | |
| # pylint: disable=R0201
 | |
| 
 | |
| import glob
 | |
| import logging
 | |
| import os.path
 | |
| import subprocess
 | |
| import sys
 | |
| 
 | |
| from devil.android import device_errors
 | |
| from devil.android.valgrind_tools import base_tool
 | |
| from pylib.constants import DIR_SOURCE_ROOT
 | |
| 
 | |
| 
 | |
| def SetChromeTimeoutScale(device, scale):
 | |
|   """Sets the timeout scale in /data/local/tmp/chrome_timeout_scale to scale."""
 | |
|   path = '/data/local/tmp/chrome_timeout_scale'
 | |
|   if not scale or scale == 1.0:
 | |
|     # Delete if scale is None/0.0/1.0 since the default timeout scale is 1.0
 | |
|     device.RemovePath(path, force=True, as_root=True)
 | |
|   else:
 | |
|     device.WriteFile(path, '%f' % scale, as_root=True)
 | |
| 
 | |
| 
 | |
| 
 | |
| class AddressSanitizerTool(base_tool.BaseTool):
 | |
|   """AddressSanitizer tool."""
 | |
| 
 | |
|   WRAPPER_NAME = '/system/bin/asanwrapper'
 | |
|   # Disable memcmp overlap check.There are blobs (gl drivers)
 | |
|   # on some android devices that use memcmp on overlapping regions,
 | |
|   # nothing we can do about that.
 | |
|   EXTRA_OPTIONS = 'strict_memcmp=0,use_sigaltstack=1'
 | |
| 
 | |
|   def __init__(self, device):
 | |
|     super(AddressSanitizerTool, self).__init__()
 | |
|     self._device = device
 | |
| 
 | |
|   @classmethod
 | |
|   def CopyFiles(cls, device):
 | |
|     """Copies ASan tools to the device."""
 | |
|     libs = glob.glob(os.path.join(DIR_SOURCE_ROOT,
 | |
|                                   'third_party/llvm-build/Release+Asserts/',
 | |
|                                   'lib/clang/*/lib/linux/',
 | |
|                                   'libclang_rt.asan-arm-android.so'))
 | |
|     assert len(libs) == 1
 | |
|     subprocess.call(
 | |
|         [os.path.join(
 | |
|              DIR_SOURCE_ROOT,
 | |
|              'tools/android/asan/third_party/asan_device_setup.sh'),
 | |
|          '--device', str(device),
 | |
|          '--lib', libs[0],
 | |
|          '--extra-options', AddressSanitizerTool.EXTRA_OPTIONS])
 | |
|     device.WaitUntilFullyBooted()
 | |
| 
 | |
|   def GetTestWrapper(self):
 | |
|     return AddressSanitizerTool.WRAPPER_NAME
 | |
| 
 | |
|   def GetUtilWrapper(self):
 | |
|     """Returns the wrapper for utilities, such as forwarder.
 | |
| 
 | |
|     AddressSanitizer wrapper must be added to all instrumented binaries,
 | |
|     including forwarder and the like. This can be removed if such binaries
 | |
|     were built without instrumentation. """
 | |
|     return self.GetTestWrapper()
 | |
| 
 | |
|   def SetupEnvironment(self):
 | |
|     try:
 | |
|       self._device.EnableRoot()
 | |
|     except device_errors.CommandFailedError as e:
 | |
|       # Try to set the timeout scale anyway.
 | |
|       # TODO(jbudorick) Handle this exception appropriately after interface
 | |
|       #                 conversions are finished.
 | |
|       logging.error(str(e))
 | |
|     SetChromeTimeoutScale(self._device, self.GetTimeoutScale())
 | |
| 
 | |
|   def CleanUpEnvironment(self):
 | |
|     SetChromeTimeoutScale(self._device, None)
 | |
| 
 | |
|   def GetTimeoutScale(self):
 | |
|     # Very slow startup.
 | |
|     return 20.0
 | |
| 
 | |
| 
 | |
| TOOL_REGISTRY = {
 | |
|     'asan': AddressSanitizerTool,
 | |
| }
 | |
| 
 | |
| 
 | |
| def CreateTool(tool_name, device):
 | |
|   """Creates a tool with the specified tool name.
 | |
| 
 | |
|   Args:
 | |
|     tool_name: Name of the tool to create.
 | |
|     device: A DeviceUtils instance.
 | |
|   Returns:
 | |
|     A tool for the specified tool_name.
 | |
|   """
 | |
|   if not tool_name:
 | |
|     return base_tool.BaseTool()
 | |
| 
 | |
|   ctor = TOOL_REGISTRY.get(tool_name)
 | |
|   if ctor:
 | |
|     return ctor(device)
 | |
|   else:
 | |
|     print 'Unknown tool %s, available tools: %s' % (
 | |
|         tool_name, ', '.join(sorted(TOOL_REGISTRY.keys())))
 | |
|     sys.exit(1)
 | |
| 
 | |
| def PushFilesForTool(tool_name, device):
 | |
|   """Pushes the files required for |tool_name| to |device|.
 | |
| 
 | |
|   Args:
 | |
|     tool_name: Name of the tool to create.
 | |
|     device: A DeviceUtils instance.
 | |
|   """
 | |
|   if not tool_name:
 | |
|     return
 | |
| 
 | |
|   clazz = TOOL_REGISTRY.get(tool_name)
 | |
|   if clazz:
 | |
|     clazz.CopyFiles(device)
 | |
|   else:
 | |
|     print 'Unknown tool %s, available tools: %s' % (
 | |
|         tool_name, ', '.join(sorted(TOOL_REGISTRY.keys())))
 | |
|     sys.exit(1)
 | |
| 
 |