diff options
author | jochen@chromium.org <jochen@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2013-10-20 06:17:26 +0000 |
---|---|---|
committer | jochen@chromium.org <jochen@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2013-10-20 06:17:26 +0000 |
commit | 3d40ab040113f38d29fd17442d787558dcd82d40 (patch) | |
tree | a4bd06f0b3f72d5251207a38c6944a822a319698 /chrome/tools | |
parent | 58d6ae77f229dbaf518b18e3756452b21c7b4212 (diff) | |
download | chromium_src-3d40ab040113f38d29fd17442d787558dcd82d40.zip chromium_src-3d40ab040113f38d29fd17442d787558dcd82d40.tar.gz chromium_src-3d40ab040113f38d29fd17442d787558dcd82d40.tar.bz2 |
Move process_dumps_linux.py to breakpad component
Currently, there's nothing that programmatically invokes this script, so
we can just move it.
R=thakis@chromium.org, rsesek@chromium.org
BUG=247431
Review URL: https://codereview.chromium.org/27893003
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@229678 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'chrome/tools')
-rwxr-xr-x | chrome/tools/process_dumps/process_dumps_linux.py | 300 |
1 files changed, 0 insertions, 300 deletions
diff --git a/chrome/tools/process_dumps/process_dumps_linux.py b/chrome/tools/process_dumps/process_dumps_linux.py deleted file mode 100755 index 1f0ba9d..0000000 --- a/chrome/tools/process_dumps/process_dumps_linux.py +++ /dev/null @@ -1,300 +0,0 @@ -#!/usr/bin/env python -# Copyright (c) 2011 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. - -"""A tool to collect crash signatures for Chrome builds on Linux.""" - -import fnmatch -import optparse -import os -import shutil -import subprocess -import struct -import sys -import tempfile - - -def VerifySymbolAndCopyToTempDir(symbol_file, temp_dir, sym_module_name): - """Verify the symbol file looks correct and copy it to the right place - in temp_dir. - - Args: - symbol_file: the path to the symbol file. - temp_dir: the base of the temp directory where the symbol file will reside. - Returns: - True on success. - """ - symbol = open(symbol_file) - signature_line = symbol.readline().strip().split() - symbol.close() - # signature_line should look like: - # MODULE Linux x86 28D8A79A426807B5462CBA24F56746750 chrome - if (len(signature_line) == 5 and signature_line[0] == 'MODULE' and - signature_line[1] == 'Linux' and signature_line[4] == sym_module_name and - len(signature_line[3]) == 33): - dest = os.path.join(temp_dir, signature_line[4], signature_line[3]) - os.makedirs(dest) - dest_file = os.path.join(dest, '%s.sym' % signature_line[4]) - shutil.copyfile(symbol_file, dest_file) - return True - return False - - -def GetCommandOutput(command): - """Runs the command list, returning its output. - - Prints the given command (which should be a list of one or more strings), - then runs it and returns its output (stdout and stderr) as a string. - - If the command exits with an error, raises OSError. - - From chromium_utils. - """ - proc = subprocess.Popen(command, stdout=subprocess.PIPE, - stderr=subprocess.STDOUT, bufsize=1) - output = proc.communicate()[0] - if proc.returncode: - raise OSError('%s: %s' % (subprocess.list2cmdline(command), output)) - return output - - -def GetCrashDumpDir(): - """Returns the default crash dump directory used by Chromium.""" - config_home = os.environ.get('XDG_CONFIG_HOME') - if not config_home: - home = os.path.expanduser('~') - if not home: - return '' - config_home = os.path.join(home, '.config') - return os.path.join(config_home, 'chromium', 'Crash Reports') - - -def GetStackTrace(processor_bin, symbol_path, dump_file): - """Gets and prints the stack trace from a crash dump file. - - Args: - processor_bin: the path to the processor. - symbol_path: root dir for the symbols. - dump_file: the path to the dump file. - Returns: - A string representing the stack trace. - """ - # Run processor to analyze crash dump. - cmd = [processor_bin, '-m', dump_file, symbol_path] - - try: - output = GetCommandOutput(cmd) - except OSError: - return 'Cannot get stack trace.' - - # Retrieve stack trace from processor output. Processor output looks like: - # ---------------- - # Debug output - # ... - # Debug output - # Module ... - # ... - # Module ... - # - # N|... <--+ - # ... |--- crashed thread stack trace - # N|... <--+ - # M|... - # ... - # ---------------- - # where each line of the stack trace looks like: - # ThreadNumber|FrameNumber|ExeName|Function|SourceFile|LineNo|Offset - - stack_trace_frames = [] - idx = output.find('\nModule') - if idx >= 0: - output = output[idx+1:] - idx = output.find('\n\n') - if idx >= 0: - output = output[idx+2:].splitlines() - if output: - first_line = output[0].split('|') - if first_line: - crashed_thread = first_line[0] - for line in output: - line_split = line.split('|') - if not line_split: - break - if line_split[0] != crashed_thread: - break - stack_trace_frames.append(line_split) - if not stack_trace_frames: - return 'Cannot get stack trace.' - stack_trace = [] - for frame in stack_trace_frames: - if len(frame) != 7: - continue - (exe, func, source, line, offset) = frame[2:] - if not exe or not source or not line or not offset: - continue - idx = func.find('(') - if idx >= 0: - func = func[:idx] - if not func: - continue - frame_output = '%s!%s+%s [%s @ %s]' % (exe, func, offset, source, line) - stack_trace.append(frame_output) - return '\n'.join(stack_trace) - - -def LocateFiles(pattern, root=os.curdir): - """Yields files matching pattern found in root and its subdirectories. - - An exception is thrown if root doesn't exist. - - From chromium_utils.""" - root = os.path.expanduser(root) - for path, dirs, files in os.walk(os.path.abspath(root)): - for filename in fnmatch.filter(files, pattern): - yield os.path.join(path, filename) - - -def ProcessDump(dump_file, temp_dir): - """Extracts the part of the dump file that minidump_stackwalk can read. - - Args: - dump_file: the dump file that needs to be processed. - temp_dir: the temp directory to put the dump file in. - Returns: - path of the processed dump file. - """ - dump = open(dump_file, 'rb') - dump_data = dump.read() - dump.close() - idx = dump_data.find('MDMP') - if idx < 0: - return '' - - dump_data = dump_data[idx:] - if not dump_data: - return '' - (dump_fd, dump_name) = tempfile.mkstemp(suffix='chromedump', dir=temp_dir) - os.write(dump_fd, dump_data) - os.close(dump_fd) - return dump_name - - -def main_linux(options, args): - # minidump_stackwalk is part of Google Breakpad. You may need to checkout - # the code and build your own copy. http://google-breakpad.googlecode.com/ - LINUX_PROCESSOR = 'minidump_stackwalk' - processor_bin = None - if options.processor_dir: - bin = os.path.join(os.path.expanduser(options.processor_dir), - LINUX_PROCESSOR) - if os.access(bin, os.X_OK): - processor_bin = bin - else: - for path in os.environ['PATH'].split(':'): - bin = os.path.join(path, LINUX_PROCESSOR) - if os.access(bin, os.X_OK): - processor_bin = bin - break - if not processor_bin: - print 'Cannot find minidump_stackwalk.' - return 1 - - if options.symbol_filename: - symbol_file = options.symbol_filename - else: - if options.architecture: - bits = options.architecture - else: - bits = struct.calcsize('P') * 8 - if bits == 32: - symbol_file = 'chrome.breakpad.ia32' - elif bits == 64: - symbol_file = 'chrome.breakpad.x64' - else: - print 'Unknown architecture' - return 1 - - symbol_dir = options.symbol_dir - if not options.symbol_dir: - symbol_dir = os.curdir - symbol_dir = os.path.abspath(os.path.expanduser(symbol_dir)) - symbol_file = os.path.join(symbol_dir, symbol_file) - if not os.path.exists(symbol_file): - print 'Cannot find symbols.' - return 1 - symbol_time = os.path.getmtime(symbol_file) - - dump_files = [] - if options.dump_file: - dump_files.append(options.dump_file) - else: - dump_dir = options.dump_dir - if not dump_dir: - dump_dir = GetCrashDumpDir() - if not dump_dir: - print 'Cannot find dump files.' - return 1 - for dump_file in LocateFiles(pattern='*.dmp', root=dump_dir): - file_time = os.path.getmtime(dump_file) - if file_time < symbol_time: - # Ignore dumps older than symbol file. - continue - dump_files.append(dump_file) - - temp_dir = tempfile.mkdtemp(suffix='chromedump') - if not VerifySymbolAndCopyToTempDir(symbol_file, temp_dir, - options.sym_module_name): - print 'Cannot parse symbols.' - shutil.rmtree(temp_dir) - return 1 - - dump_count = 0 - for dump_file in dump_files: - processed_dump_file = ProcessDump(dump_file, temp_dir) - if not processed_dump_file: - continue - print '-------------------------' - print GetStackTrace(processor_bin, temp_dir, processed_dump_file) - print - os.remove(processed_dump_file) - dump_count += 1 - - shutil.rmtree(temp_dir) - print '%s dumps found' % dump_count - return 0 - - -def main(): - if not sys.platform.startswith('linux'): - return 1 - parser = optparse.OptionParser() - parser.add_option('', '--processor-dir', type='string', default='', - help='The directory where the processor is installed. ' - 'The processor is used to get stack trace from dumps. ' - 'Searches $PATH by default') - parser.add_option('', '--dump-file', type='string', default='', - help='The path of the dump file to be processed. ' - 'Overwrites dump-path.') - parser.add_option('', '--dump-dir', type='string', default='', - help='The directory where dump files are stored. ' - 'Searches this directory if dump-file is not ' - 'specified. Default is the Chromium crash directory.') - parser.add_option('', '--symbol-dir', default='', - help='The directory with the symbols file. [Required]') - parser.add_option('', '--symbol-filename', default='', - help='The name of the symbols file to use. ' - 'This argument overrides --architecture.') - parser.add_option('', '--architecture', type='int', default=None, - help='Override automatic x86/x86-64 detection. ' - 'Valid values are 32 and 64') - parser.add_option('', '--sym-module-name', type='string', default='chrome', - help='The module name for the symbol file. ' - 'Default: chrome') - - (options, args) = parser.parse_args() - return main_linux(options, args) - - -if '__main__' == __name__: - sys.exit(main()) |