Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(3500)

Unified Diff: snapshot/win/end_to_end_test.py

Issue 1397833004: win: Test some basic ! windbg commands (Closed) Base URL: https://chromium.googlesource.com/crashpad/crashpad@add-pexpect
Patch Set: rebase Created 5 years, 2 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
« no previous file with comments | « build/run_tests.py ('k') | no next file » | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: snapshot/win/end_to_end_test.py
diff --git a/snapshot/win/end_to_end_test.py b/snapshot/win/end_to_end_test.py
index 0a13befd1b76fddc42bfe96c1dfc1a7512490138..07ff557feb1496f56be687299fc450313891b8ab 100644
--- a/snapshot/win/end_to_end_test.py
+++ b/snapshot/win/end_to_end_test.py
@@ -15,12 +15,29 @@
# limitations under the License.
import os
+import re
+import subprocess
import sys
+import tempfile
+
+g_temp_dirs = []
+
+
+def MakeTempDir():
+ global g_temp_dirs
+ new_dir = tempfile.mkdtemp()
+ g_temp_dirs.append(new_dir)
+ return new_dir
+
+
+def CleanUpTempDirs():
+ global g_temp_dirs
+ for d in g_temp_dirs:
+ subprocess.call(['rmdir', '/s', '/q', d], shell=True)
def FindInstalledWindowsApplication(app_path):
- search_paths = [os.getenv('PROGRAMFILES(X86)'),
- os.getenv('PROGRAMFILES'),
+ search_paths = [os.getenv('PROGRAMFILES(X86)'), os.getenv('PROGRAMFILES'),
Mark Mentovai 2015/10/09 18:34:04 I liked this better before, one element per line.
scottmg 2015/10/09 18:49:28 Yeah, I started using https://github.com/google/ya
os.getenv('LOCALAPPDATA')]
search_paths += os.getenv('PATH', '').split(os.pathsep)
@@ -35,6 +52,9 @@ def FindInstalledWindowsApplication(app_path):
def GetCdbPath():
+ """Search in some reasonable places to find cdb.exe. Searches x64 before x86
+ and newer versions before older versions.
+ """
possible_paths = (
os.path.join('Windows Kits', '10', 'Debuggers', 'x64'),
os.path.join('Windows Kits', '10', 'Debuggers', 'x86'),
@@ -42,14 +62,8 @@ def GetCdbPath():
os.path.join('Windows Kits', '8.1', 'Debuggers', 'x86'),
os.path.join('Windows Kits', '8.0', 'Debuggers', 'x64'),
os.path.join('Windows Kits', '8.0', 'Debuggers', 'x86'),
- 'Debugging Tools For Windows (x64)',
- 'Debugging Tools For Windows (x86)',
- 'Debugging Tools For Windows',
- os.path.join('win_toolchain', 'vs2013_files', 'win8sdk', 'Debuggers',
- 'x64'),
- os.path.join('win_toolchain', 'vs2013_files', 'win8sdk', 'Debuggers',
- 'x86'),
- )
+ 'Debugging Tools For Windows (x64)', 'Debugging Tools For Windows (x86)',
+ 'Debugging Tools For Windows',)
for possible_path in possible_paths:
app_path = os.path.join(possible_path, 'cdb.exe')
app_path = FindInstalledWindowsApplication(app_path)
@@ -58,10 +72,132 @@ def GetCdbPath():
return None
+def GetDumpFromCrashyProgram(out_dir):
+ """Initialize a crash database, run crashpad_handler, run crashy_program
+ connecting to the crash_handler. Returns the minidump generated by
+ crash_handler for further testing.
+ """
+ pipe_name = r'\\.\pipe\end-to-end'
Mark Mentovai 2015/10/09 18:34:05 Should this be a little more random? pid + 64 rand
scottmg 2015/10/09 18:49:28 Done.
+
+ test_database = MakeTempDir()
+
+ try:
+ if subprocess.call(
+ [os.path.join(out_dir, 'crashpad_database_util.exe'), '--create',
+ '--database=' + test_database]) != 0:
+ print 'could not initialize report database'
+ return None
+
+ handler = subprocess.Popen([
+ os.path.join(out_dir, 'crashpad_handler.exe'), '--pipe-name=' +
+ pipe_name, '--database=' + test_database
Mark Mentovai 2015/10/09 18:34:05 'pipe_name=' and pipe_name should at least be on t
scottmg 2015/10/09 18:49:28 Done.
+ ])
+
+ subprocess.call([os.path.join(out_dir, 'crashy_program.exe'), pipe_name])
+
+ out = subprocess.check_output([
+ os.path.join(out_dir, 'crashpad_database_util.exe'),
+ '--database=' + test_database,
+ '--show-completed-reports',
+ '--show-all-report-info',
+ ])
+ for line in out.splitlines():
+ if line.strip().startswith('Path:'):
+ return line.partition(':')[2].strip()
+
+ finally:
+ if handler:
+ handler.kill()
+
+
+class CdbRun(object):
+ """Run cdb.exe passing it the given commands and capturing the output.
+ `Check()` searchs for regex patterns in sequence allowing verification of
Mark Mentovai 2015/10/09 18:34:05 searches
scottmg 2015/10/09 18:49:28 Done.
+ expected output.
+ """
+ def __init__(self, cdb_path, dump_path, *commands):
+ # Run a command line that loads the dump, runs the specified commands, and
+ # then quits, and capture the stdout.
+ self.out = subprocess.check_output([cdb_path, '-z', dump_path, '-c',
+ ';'.join(commands) + ';q'])
Mark Mentovai 2015/10/09 18:34:05 Dunno about how cdb command lines should be escape
Mark Mentovai 2015/10/09 18:34:05 '-c' next to this, since this whole thing applies
scottmg 2015/10/09 18:49:28 Switched to just 'command'.
scottmg 2015/10/09 18:49:28 Done.
+
+ def Check(self, pattern, message):
+ print ' ... ' + message,
+ sys.stdout.flush()
+ match_obj = re.search(pattern, self.out)
+ if match_obj:
+ # Matched. Consume up to end of match.
+ self.out = self.out[match_obj.end(0):]
+ print '\rok - '
Mark Mentovai 2015/10/09 18:34:04 '\rok - ' Not really sure what you’re going for h
scottmg 2015/10/09 18:49:28 I wanted the "ok"s before the names so they're eas
+ sys.stdout.flush()
+ else:
+ print
+ print '-'*80
Mark Mentovai 2015/10/09 18:34:05 Errors to stderr?
scottmg 2015/10/09 18:49:28 Done.
+ print 'did not match:\n %s' % pattern
+ print '-'*80
+ print 'remaining output was:\n %s' % self.out
+ print '-'*80
+ sys.exit(1)
+
+
+def RunTests(cdb_path, dump_path):
+ """Runs various tests in sequence. Runs a new cdb instance on the dump for
+ each block of tests to reduce the chances that output from one command is
+ confused for output from another.
+ """
+ out = CdbRun(cdb_path, dump_path, '.ecxr')
+ out.Check('This dump file has an exception of interest stored in it',
+ 'captured exception')
+ out.Check(
+ 'crashy_program!crashpad::`anonymous namespace\'::SomeCrashyFunction',
+ 'exception at correct location')
+
+ out = CdbRun(cdb_path, dump_path, '!peb')
+ out.Check(r'PEB at', 'found the PEB')
+ out.Check(r'Ldr\.InMemoryOrderModuleList:.*\d+ \. \d+', 'PEB_LDR_DATA saved')
+ out.Check(r'Base TimeStamp Module', 'module list present')
+ out.Check(r'CommandLine: *\'.*crashy_program.exe *\\\\.\\pipe\\end-to-end',
+ 'some PEB data is correct')
+ out.Check(r'SystemRoot=C:\\Windows', 'some of environment captured')
+
+ out = CdbRun(cdb_path, dump_path, '!teb')
+ out.Check(r'TEB at', 'found the TEB')
+ out.Check(r'ExceptionList:\s+[0-9a-fA-F]+', 'some valid teb data')
+ out.Check(r'LastErrorValue:\s+2', 'correct LastErrorValue')
+
+ out = CdbRun(cdb_path, dump_path, '!gle')
+ out.Check('LastErrorValue: \(Win32\) 0x2 \(2\) - The system cannot find the '
+ 'file specified.', '!gle gets last error')
+ out.Check('LastStatusValue: \(NTSTATUS\) 0xc000000f - {File Not Found} The '
+ 'file %hs does not exist.', '!gle gets last ntstatus')
+
+ # Locks.
+ out = CdbRun(cdb_path, dump_path, '!locks')
+ out.Check(r'CritSec crashy_program!crashpad::`anonymous namespace\'::'
+ r'g_test_critical_section', 'lock was captured')
+ out.Check(r'\*\*\* Locked', 'lock debug info was captured, and is locked')
+
+
def main(args):
- cdb_path = GetCdbPath()
- print 'cdb_path:', cdb_path
- return 0
+ try:
+ if len(args) != 1:
+ print 'must supply out dir'
Mark Mentovai 2015/10/09 18:34:05 stderr for these
scottmg 2015/10/09 18:49:28 Done.
+ return 1
+
+ cdb_path = GetCdbPath()
+ if not cdb_path:
+ print 'could not find cdb'
+ return 1
+
+ dump_path = GetDumpFromCrashyProgram(args[0])
+ if not dump_path:
+ return 1
+
+ RunTests(cdb_path, dump_path)
+
+ return 0
+ finally:
+ CleanUpTempDirs()
if __name__ == '__main__':
« no previous file with comments | « build/run_tests.py ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698