- Revision
- 102163
- Author
- [email protected]
- Date
- 2011-12-06 12:04:25 -0800 (Tue, 06 Dec 2011)
Log Message
Add a pid parameter to CrashLogs.find_newest_log
When a PID is passed, only crash logs corresponding to a crashed process with that PID are
considered.
Fixes <http://webkit.org/b/73942> webkitpy provides no way to specify the PID of the crashed
process whose crash log you want to find
Reviewed by Dirk Pranke.
* Scripts/webkitpy/common/system/crashlogs.py:
(CrashLogs.find_newest_log): Added an optional pid parameter.
(CrashLogs._find_newest_log_darwin): Added a pid parameter. When specified, we look at each
candidate log's app_description extended attribute to see if that log corresponds to a
crashed process with the specified PID.
* Scripts/webkitpy/common/system/crashlogs_unittest.py:
(CrashLogsTest.test_find_newest_log_darwin): Added a few more mock crash logs with various
contents and PIDs. Added tests that show that the pid parameter to find_newest_log is
respected. Also fixed an erroneous use of assertTrue instead of assertEqual.
* Scripts/webkitpy/common/system/filesystem.py:
(FileSystem.getxattr): Added. On Darwin, calls through to the xattr module. On other
systems, raises a KeyError, mimicking the behavior on Darwin when the given attribute isn't
present.
* Scripts/webkitpy/common/system/filesystem_mock.py:
(MockFileSystem.__init__): Added an optional xattrs parameter. Documented other parameters.
(MockFileSystem.getxattr): Added. Just pulls the given attribute out of the xattrs
dictionary.
* Scripts/webkitpy/tool/commands/queries.py:
(CrashLog): Added help text. Added an optional PID parameter.
(CrashLog.execute): Pass the PID, if any, through to find_newest_log.
Modified Paths
Diff
Modified: trunk/Tools/ChangeLog (102162 => 102163)
--- trunk/Tools/ChangeLog 2011-12-06 20:04:08 UTC (rev 102162)
+++ trunk/Tools/ChangeLog 2011-12-06 20:04:25 UTC (rev 102163)
@@ -1,5 +1,42 @@
2011-12-06 Adam Roben <[email protected]>
+ Add a pid parameter to CrashLogs.find_newest_log
+
+ When a PID is passed, only crash logs corresponding to a crashed process with that PID are
+ considered.
+
+ Fixes <http://webkit.org/b/73942> webkitpy provides no way to specify the PID of the crashed
+ process whose crash log you want to find
+
+ Reviewed by Dirk Pranke.
+
+ * Scripts/webkitpy/common/system/crashlogs.py:
+ (CrashLogs.find_newest_log): Added an optional pid parameter.
+ (CrashLogs._find_newest_log_darwin): Added a pid parameter. When specified, we look at each
+ candidate log's app_description extended attribute to see if that log corresponds to a
+ crashed process with the specified PID.
+
+ * Scripts/webkitpy/common/system/crashlogs_unittest.py:
+ (CrashLogsTest.test_find_newest_log_darwin): Added a few more mock crash logs with various
+ contents and PIDs. Added tests that show that the pid parameter to find_newest_log is
+ respected. Also fixed an erroneous use of assertTrue instead of assertEqual.
+
+ * Scripts/webkitpy/common/system/filesystem.py:
+ (FileSystem.getxattr): Added. On Darwin, calls through to the xattr module. On other
+ systems, raises a KeyError, mimicking the behavior on Darwin when the given attribute isn't
+ present.
+
+ * Scripts/webkitpy/common/system/filesystem_mock.py:
+ (MockFileSystem.__init__): Added an optional xattrs parameter. Documented other parameters.
+ (MockFileSystem.getxattr): Added. Just pulls the given attribute out of the xattrs
+ dictionary.
+
+ * Scripts/webkitpy/tool/commands/queries.py:
+ (CrashLog): Added help text. Added an optional PID parameter.
+ (CrashLog.execute): Pass the PID, if any, through to find_newest_log.
+
+2011-12-06 Adam Roben <[email protected]>
+
Wait for Crash Reporter to finish even when it lets the crashed process die quickly
NRWT was only waiting for Crash Reporter in cases where it was keeping the crashed process
Modified: trunk/Tools/Scripts/webkitpy/common/system/crashlogs.py (102162 => 102163)
--- trunk/Tools/Scripts/webkitpy/common/system/crashlogs.py 2011-12-06 20:04:08 UTC (rev 102162)
+++ trunk/Tools/Scripts/webkitpy/common/system/crashlogs.py 2011-12-06 20:04:25 UTC (rev 102163)
@@ -34,9 +34,9 @@
def __init__(self, filesystem):
self._filesystem = filesystem
- def find_newest_log(self, process_name):
+ def find_newest_log(self, process_name, pid=None):
if sys.platform == "darwin":
- return self._find_newest_log_darwin(process_name)
+ return self._find_newest_log_darwin(process_name, pid)
def _log_directory_darwin(self):
log_directory = self._filesystem.expanduser("~")
@@ -47,7 +47,7 @@
log_directory = self._filesystem.join(log_directory, "CrashReporter")
return log_directory
- def _find_newest_log_darwin(self, process_name):
+ def _find_newest_log_darwin(self, process_name, pid):
def is_crash_log(fs, dirpath, basename):
return basename.startswith(process_name + "_") and basename.endswith(".crash")
@@ -55,4 +55,13 @@
logs = self._filesystem.files_under(log_directory, file_filter=is_crash_log)
if not logs:
return None
- return self._filesystem.read_text_file(sorted(logs)[-1])
+ for path in reversed(sorted(logs)):
+ if pid is not None:
+ try:
+ app_description = self._filesystem.getxattr(path, 'app_description')
+ if not app_description.startswith('%s[%d] version ' % (process_name, pid)):
+ continue
+ except KeyError:
+ # The file doesn't have the app_description extended attribute for some reason.
+ continue
+ return self._filesystem.read_text_file(path)
Modified: trunk/Tools/Scripts/webkitpy/common/system/crashlogs_unittest.py (102162 => 102163)
--- trunk/Tools/Scripts/webkitpy/common/system/crashlogs_unittest.py 2011-12-06 20:04:08 UTC (rev 102162)
+++ trunk/Tools/Scripts/webkitpy/common/system/crashlogs_unittest.py 2011-12-06 20:04:25 UTC (rev 102163)
@@ -33,10 +33,24 @@
def test_find_log_darwin(self):
if sys.platform != "darwin":
return
+ older_mock_crash_report = "Older Mock Crash Report"
mock_crash_report = "Mock Crash Report"
+ newer_mock_crash_report = "Newer Mock Crash Report"
files = {}
+ files['/Users/mock/Library/Logs/DiagnosticReports/TextMate_2011-06-13-150718_quadzen.crash'] = older_mock_crash_report
files['/Users/mock/Library/Logs/DiagnosticReports/TextMate_2011-06-13-150719_quadzen.crash'] = mock_crash_report
- filesystem = MockFileSystem(files)
+ files['/Users/mock/Library/Logs/DiagnosticReports/TextMate_2011-06-13-150720_quadzen.crash'] = newer_mock_crash_report
+ xattrs = {}
+ xattrs['/Users/mock/Library/Logs/DiagnosticReports/TextMate_2011-06-13-150718_quadzen.crash'] = {}
+ xattrs['/Users/mock/Library/Logs/DiagnosticReports/TextMate_2011-06-13-150719_quadzen.crash'] = {'app_description': 'TextMate[28530] version ??? (???)'}
+ xattrs['/Users/mock/Library/Logs/DiagnosticReports/TextMate_2011-06-13-150720_quadzen.crash'] = {'app_description': 'TextMate[28529] version ??? (???)'}
+ filesystem = MockFileSystem(files, xattrs=xattrs)
crash_logs = CrashLogs(filesystem)
log = crash_logs.find_newest_log("TextMate")
- self.assertTrue(log, mock_crash_report)
+ self.assertEqual(log, newer_mock_crash_report)
+ log = crash_logs.find_newest_log("TextMate", 28529)
+ self.assertEqual(log, newer_mock_crash_report)
+ log = crash_logs.find_newest_log("TextMate", 28530)
+ self.assertEqual(log, mock_crash_report)
+ log = crash_logs.find_newest_log("TextMate", 28531)
+ self.assertEqual(log, None)
Modified: trunk/Tools/Scripts/webkitpy/common/system/filesystem.py (102162 => 102163)
--- trunk/Tools/Scripts/webkitpy/common/system/filesystem.py 2011-12-06 20:04:08 UTC (rev 102162)
+++ trunk/Tools/Scripts/webkitpy/common/system/filesystem.py 2011-12-06 20:04:25 UTC (rev 102163)
@@ -119,6 +119,14 @@
def getcwd(self):
return os.getcwd()
+ def getxattr(self, path, attribute_name):
+ if sys.platform != 'darwin':
+ # We only know how to read extended attributes on Darwin. Darwin raises a KeyError when
+ # the attribute doesn't exist, so mimic that.
+ raise KeyError(attribute_name)
+ import xattr
+ return xattr.getxattr(path, attribute_name)
+
def glob(self, path):
return glob.glob(path)
Modified: trunk/Tools/Scripts/webkitpy/common/system/filesystem_mock.py (102162 => 102163)
--- trunk/Tools/Scripts/webkitpy/common/system/filesystem_mock.py 2011-12-06 20:04:08 UTC (rev 102162)
+++ trunk/Tools/Scripts/webkitpy/common/system/filesystem_mock.py 2011-12-06 20:04:25 UTC (rev 102163)
@@ -36,7 +36,7 @@
class MockFileSystem(object):
- def __init__(self, files=None, dirs=None, cwd='/'):
+ def __init__(self, files=None, dirs=None, cwd='/', xattrs=None):
"""Initializes a "mock" filesystem that can be used to completely
stub out a filesystem.
@@ -44,6 +44,9 @@
files: a dict of filenames -> file contents. A file contents
value of None is used to indicate that the file should
not exist.
+ dirs: a sequence of directory names
+ cwd: the path against which relative paths should be resolved.
+ xattrs: a dict of filenames -> dict of attribute names -> values.
"""
self.files = files or {}
self.written_files = {}
@@ -57,6 +60,9 @@
while not d in self.dirs:
self.dirs.add(d)
d = self.dirname(d)
+ self.xattrs = {} if xattrs is None else xattrs
+ for f in self.xattrs:
+ assert f in self.files, f
def _get_sep(self):
return self._sep
@@ -147,6 +153,9 @@
def getcwd(self):
return self.cwd
+ def getxattr(self, path, attribute_name):
+ return self.xattrs[path][attribute_name]
+
def glob(self, glob_string):
# FIXME: This handles '*', but not '?', '[', or ']'.
glob_string = re.escape(glob_string)
Modified: trunk/Tools/Scripts/webkitpy/tool/commands/queries.py (102162 => 102163)
--- trunk/Tools/Scripts/webkitpy/tool/commands/queries.py 2011-12-06 20:04:08 UTC (rev 102162)
+++ trunk/Tools/Scripts/webkitpy/tool/commands/queries.py 2011-12-06 20:04:25 UTC (rev 102163)
@@ -372,11 +372,17 @@
class CrashLog(AbstractDeclarativeCommand):
name = "crash-log"
- argument_names = "PROCESS_NAME"
+ help_text = "Print the newest crash log for the given process"
+ long_help = """Finds the newest crash log matching the given process name
+and PID and prints it to stdout."""
+ argument_names = "PROCESS_NAME [PID]"
def execute(self, options, args, tool):
crash_logs = CrashLogs(tool.filesystem)
- print crash_logs.find_newest_log(args[0])
+ pid = None
+ if len(args) > 1:
+ pid = int(args[1])
+ print crash_logs.find_newest_log(args[0], pid)
class SkippedPorts(AbstractDeclarativeCommand):