def filter_binary_path(binary_path): """Filters binary path to provide a local copy.""" platform = environment.platform() if platform == 'ANDROID': # Skip symbolization when running it on bad entries like [stack:XYZ]. if not binary_path.startswith('/') or '(deleted)' in binary_path: return '' # Initialize some helper variables. binary_filename = os.path.basename(binary_path) build_directory = environment.get_value('BUILD_DIR') symbols_directory = environment.get_value('SYMBOLS_DIR') # Try to find the library in the build directory first. local_binary_path = utils.find_binary_path(build_directory, binary_path) if local_binary_path: return local_binary_path # We didn't find the library locally in the build directory. # Try finding the library in the local system library cache. download_system_symbols_if_needed(symbols_directory) local_binary_path = utils.find_binary_path(symbols_directory, binary_path) if local_binary_path: return local_binary_path # Try pulling in the binary directly from the device into the # system library cache directory. local_binary_path = os.path.join(symbols_directory, binary_filename) adb.run_command('pull %s %s' % (binary_path, local_binary_path)) if os.path.exists(local_binary_path): return local_binary_path # Unable to find library. logs.log_error('Unable to find library %s for symbolization.' % binary_path) return '' if platform == 'CHROMEOS': # FIXME: Add code to pull binaries from ChromeOS device. return binary_path if environment.is_chromeos_system_job(): # This conditional is True for ChromeOS system fuzzers that are running on # Linux. Ensure that the binary is always looked for in the chroot and not # in system directories. build_dir = environment.get_value('BUILD_DIR') if not binary_path.startswith(build_dir): # Fixup path so |binary_path| points to a binary in the chroot (probably # a system library). return os.path.join(build_dir, binary_path[1:]) # For Linux and Mac, the binary exists locally. No work to do, # just return the same binary path. return binary_path
def _get_binary_from_build_or_device(binary_path): """Look for binary on build server or on device.""" # Initialize some helper variables. symbols_directory = environment.get_value('SYMBOLS_DIR') binary_filename = os.path.basename(binary_path) # We didn't find the library locally in the build directory. # Try finding the library in the local system library cache. download_system_symbols_if_needed(symbols_directory) local_binary_path = utils.find_binary_path(symbols_directory, binary_path) if local_binary_path: return local_binary_path # Try pulling in the binary directly from the device into the # system library cache directory. local_binary_path = os.path.join(symbols_directory, binary_filename) adb.run_command('pull %s %s' % (binary_path, local_binary_path)) if os.path.exists(local_binary_path): return local_binary_path return None
def get_crash_info(output): """Parse crash output to get (local) minidump path and any other information useful for crash uploading, and store in a CrashReportInfo object.""" crash_stacks_directory = environment.get_value('CRASH_STACKTRACES_DIR') platform = environment.platform() output_lines = output.splitlines() num_lines = len(output_lines) for i, line in enumerate(output_lines): if platform == 'ANDROID': # If we are on Android, the dump extraction is more complicated. # The location placed in the crash-stacktrace is of the dump itself but # in fact only the MIME of the dump exists, and will have a different # extension. We need to pull the MIME and process it. match = re.match(CRASH_DUMP_PATH_MARKER, line) if not match: continue minidump_mime_filename_base = None for j in range(i + 1, num_lines): line = output_lines[j] match = re.match(r'(.*)\.dmp', line) if match: minidump_mime_filename_base = os.path.basename( match.group(1).strip()) break if not minidump_mime_filename_base: logs.log_error( 'Minidump marker was found, but no path in stacktrace.') return None # Look for MIME. If none found, bail. # We might not have copied over the crash dumps yet (copying is buffered), # so we want to search both the original directory and the one to which # the minidumps should later be copied. device_directories_to_search = [ constants.CRASH_DUMPS_DIR, os.path.dirname(line.strip()) ] device_minidump_search_paths = [] device_minidump_mime_path = None for device_directory in device_directories_to_search: device_minidump_mime_potential_paths = adb.run_shell_command( ['ls', '"%s"' % device_directory], root=True).splitlines() device_minidump_search_paths += device_minidump_mime_potential_paths for potential_path in device_minidump_mime_potential_paths: # Check that we actually found a file, and the right one (not logcat). if 'No such file or directory' in potential_path: continue if minidump_mime_filename_base not in potential_path: continue if '.up' in potential_path or '.dmp' in potential_path: device_minidump_mime_path = os.path.join( device_directory, potential_path) break # Break if we found a path. if device_minidump_mime_path is not None: break # If we still didn't find a minidump path, bail. if device_minidump_mime_path is None: logs.log_error('Could not get MIME path from ls:\n%s' % str(device_minidump_search_paths)) return None # Pull out MIME and parse to minidump file and MIME parameters. minidump_mime_filename = '%s.mime' % minidump_mime_filename_base local_minidump_mime_path = os.path.join(crash_stacks_directory, minidump_mime_filename) adb.run_command([ 'pull', '"%s"' % device_minidump_mime_path, local_minidump_mime_path ]) if not os.path.exists(local_minidump_mime_path): logs.log_error( 'Could not pull MIME from %s to %s.' % (device_minidump_mime_path, local_minidump_mime_path)) return None crash_info = parse_mime_to_crash_report_info( local_minidump_mime_path) if crash_info is None: return None crash_info.unsymbolized_stacktrace = output return crash_info else: # Other platforms are not currently supported. logs.log_error( 'Unable to fetch crash information for this platform.') return None # Could not find dump location, bail out. This could also happen when we don't # have a minidump location in stack at all, e.g. when testcase does not crash # during minimization. return None