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

Side by Side Diff: snapshot/win/end_to_end_test.py

Issue 1412243005: win: Validate readability of memory ranges added to minidump (Closed) Base URL: https://chromium.googlesource.com/crashpad/crashpad@master
Patch Set: . Created 5 years, 1 month 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 unified diff | Download patch
« no previous file with comments | « handler/win/self_destroying_test_program.cc ('k') | snapshot/win/process_snapshot_win.cc » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 #!/usr/bin/env python 1 #!/usr/bin/env python
2 2
3 # Copyright 2015 The Crashpad Authors. All rights reserved. 3 # Copyright 2015 The Crashpad Authors. All rights reserved.
4 # 4 #
5 # Licensed under the Apache License, Version 2.0 (the "License"); 5 # Licensed under the Apache License, Version 2.0 (the "License");
6 # you may not use this file except in compliance with the License. 6 # you may not use this file except in compliance with the License.
7 # You may obtain a copy of the License at 7 # You may obtain a copy of the License at
8 # 8 #
9 # http://www.apache.org/licenses/LICENSE-2.0 9 # http://www.apache.org/licenses/LICENSE-2.0
10 # 10 #
(...skipping 58 matching lines...) Expand 10 before | Expand all | Expand 10 after
69 'Debugging Tools For Windows (x86)', 69 'Debugging Tools For Windows (x86)',
70 'Debugging Tools For Windows',) 70 'Debugging Tools For Windows',)
71 for possible_path in possible_paths: 71 for possible_path in possible_paths:
72 app_path = os.path.join(possible_path, 'cdb.exe') 72 app_path = os.path.join(possible_path, 'cdb.exe')
73 app_path = FindInstalledWindowsApplication(app_path) 73 app_path = FindInstalledWindowsApplication(app_path)
74 if app_path: 74 if app_path:
75 return app_path 75 return app_path
76 return None 76 return None
77 77
78 78
79 def GetDumpFromCrashyProgram(out_dir, pipe_name): 79 def GetDumpFromProgram(out_dir, pipe_name, executable_name):
80 """Initialize a crash database, run crashpad_handler, run crashy_program 80 """Initialize a crash database, run crashpad_handler, run |executable_name|
81 connecting to the crash_handler. Returns the minidump generated by 81 connecting to the crash_handler. Returns the minidump generated by
82 crash_handler for further testing. 82 crash_handler for further testing.
83 """ 83 """
84 test_database = MakeTempDir() 84 test_database = MakeTempDir()
85 handler = None 85 handler = None
86 86
87 try: 87 try:
88 if subprocess.call( 88 if subprocess.call(
89 [os.path.join(out_dir, 'crashpad_database_util.exe'), '--create', 89 [os.path.join(out_dir, 'crashpad_database_util.exe'), '--create',
90 '--database=' + test_database]) != 0: 90 '--database=' + test_database]) != 0:
91 print 'could not initialize report database' 91 print 'could not initialize report database'
92 return None 92 return None
93 93
94 handler = subprocess.Popen([ 94 handler = subprocess.Popen([
95 os.path.join(out_dir, 'crashpad_handler.exe'), 95 os.path.join(out_dir, 'crashpad_handler.exe'),
96 '--pipe-name=' + pipe_name, 96 '--pipe-name=' + pipe_name,
97 '--database=' + test_database 97 '--database=' + test_database
98 ]) 98 ])
99 99
100 subprocess.call([os.path.join(out_dir, 'crashy_program.exe'), pipe_name]) 100 subprocess.call([os.path.join(out_dir, executable_name), pipe_name])
101 101
102 out = subprocess.check_output([ 102 out = subprocess.check_output([
103 os.path.join(out_dir, 'crashpad_database_util.exe'), 103 os.path.join(out_dir, 'crashpad_database_util.exe'),
104 '--database=' + test_database, 104 '--database=' + test_database,
105 '--show-completed-reports', 105 '--show-completed-reports',
106 '--show-all-report-info', 106 '--show-all-report-info',
107 ]) 107 ])
108 for line in out.splitlines(): 108 for line in out.splitlines():
109 if line.strip().startswith('Path:'): 109 if line.strip().startswith('Path:'):
110 return line.partition(':')[2].strip() 110 return line.partition(':')[2].strip()
111 finally: 111 finally:
112 if handler: 112 if handler:
113 handler.kill() 113 handler.kill()
114 114
115 115
116 def GetDumpFromCrashyProgram(out_dir, pipe_name):
117 return GetDumpFromProgram(out_dir, pipe_name, 'crashy_program.exe')
118
119
120 def GetDumpFromSelfDestroyingProgram(out_dir, pipe_name):
121 return GetDumpFromProgram(out_dir, pipe_name, 'self_destroying_program.exe')
122
123
116 class CdbRun(object): 124 class CdbRun(object):
117 """Run cdb.exe passing it a cdb command and capturing the output. 125 """Run cdb.exe passing it a cdb command and capturing the output.
118 `Check()` searches for regex patterns in sequence allowing verification of 126 `Check()` searches for regex patterns in sequence allowing verification of
119 expected output. 127 expected output.
120 """ 128 """
121 129
122 def __init__(self, cdb_path, dump_path, command): 130 def __init__(self, cdb_path, dump_path, command):
123 # Run a command line that loads the dump, runs the specified cdb command, 131 # Run a command line that loads the dump, runs the specified cdb command,
124 # and then quits, and capturing stdout. 132 # and then quits, and capturing stdout.
125 self.out = subprocess.check_output([ 133 self.out = subprocess.check_output([
(...skipping 14 matching lines...) Expand all
140 print >>sys.stderr, 'FAILED - %s' % message 148 print >>sys.stderr, 'FAILED - %s' % message
141 print >>sys.stderr, '-' * 80 149 print >>sys.stderr, '-' * 80
142 print >>sys.stderr, 'did not match:\n %s' % pattern 150 print >>sys.stderr, 'did not match:\n %s' % pattern
143 print >>sys.stderr, '-' * 80 151 print >>sys.stderr, '-' * 80
144 print >>sys.stderr, 'remaining output was:\n %s' % self.out 152 print >>sys.stderr, 'remaining output was:\n %s' % self.out
145 print >>sys.stderr, '-' * 80 153 print >>sys.stderr, '-' * 80
146 sys.stderr.flush() 154 sys.stderr.flush()
147 sys.exit(1) 155 sys.exit(1)
148 156
149 157
150 def RunTests(cdb_path, dump_path, pipe_name): 158 def RunTests(cdb_path, dump_path, destroyed_dump_path, pipe_name):
151 """Runs various tests in sequence. Runs a new cdb instance on the dump for 159 """Runs various tests in sequence. Runs a new cdb instance on the dump for
152 each block of tests to reduce the chances that output from one command is 160 each block of tests to reduce the chances that output from one command is
153 confused for output from another. 161 confused for output from another.
154 """ 162 """
155 out = CdbRun(cdb_path, dump_path, '.ecxr') 163 out = CdbRun(cdb_path, dump_path, '.ecxr')
156 out.Check('This dump file has an exception of interest stored in it', 164 out.Check('This dump file has an exception of interest stored in it',
157 'captured exception') 165 'captured exception')
158 out.Check( 166 out.Check(
159 'crashy_program!crashpad::`anonymous namespace\'::SomeCrashyFunction', 167 'crashy_program!crashpad::`anonymous namespace\'::SomeCrashyFunction',
160 'exception at correct location') 168 'exception at correct location')
(...skipping 24 matching lines...) Expand all
185 r'g_test_critical_section', 'lock was captured') 193 r'g_test_critical_section', 'lock was captured')
186 if platform.win32_ver()[0] != '7': 194 if platform.win32_ver()[0] != '7':
187 # We can't allocate CRITICAL_SECTIONs with .DebugInfo on Win 7. 195 # We can't allocate CRITICAL_SECTIONs with .DebugInfo on Win 7.
188 out.Check(r'\*\*\* Locked', 'lock debug info was captured, and is locked') 196 out.Check(r'\*\*\* Locked', 'lock debug info was captured, and is locked')
189 197
190 out = CdbRun(cdb_path, dump_path, '!handle') 198 out = CdbRun(cdb_path, dump_path, '!handle')
191 out.Check(r'\d+ Handles', 'captured handles') 199 out.Check(r'\d+ Handles', 'captured handles')
192 out.Check(r'Event\s+\d+', 'capture some event handles') 200 out.Check(r'Event\s+\d+', 'capture some event handles')
193 out.Check(r'File\s+\d+', 'capture some file handles') 201 out.Check(r'File\s+\d+', 'capture some file handles')
194 202
203 out = CdbRun(cdb_path, destroyed_dump_path, '.ecxr;!peb;k 2')
204 out.Check(r'Ldr\.InMemoryOrderModuleList:.*\d+ \. \d+', 'PEB_LDR_DATA saved')
205 out.Check(r'ntdll\.dll', 'ntdll present', re.IGNORECASE)
206
207 # Check that there is no stack trace in the self-destroyed process. Confirm
208 # that the top is where we expect it (that's based only on IP), but subsequent
209 # stack entries will not be available. This confirms that we have a mostly
210 # valid dump, but that the stack was omitted.
211 out.Check(r'self_destroying_program!crashpad::`anonymous namespace\'::'
212 r'FreeOwnStackAndBreak.*\nquit:',
213 'at correct location, no additional stack entries')
214
195 def main(args): 215 def main(args):
196 try: 216 try:
197 if len(args) != 1: 217 if len(args) != 1:
198 print >>sys.stderr, 'must supply binary dir' 218 print >>sys.stderr, 'must supply binary dir'
199 return 1 219 return 1
200 220
201 cdb_path = GetCdbPath() 221 cdb_path = GetCdbPath()
202 if not cdb_path: 222 if not cdb_path:
203 print >>sys.stderr, 'could not find cdb' 223 print >>sys.stderr, 'could not find cdb'
204 return 1 224 return 1
205 225
206 # Make sure we can download Windows symbols. 226 # Make sure we can download Windows symbols.
207 if not os.environ.get('_NT_SYMBOL_PATH'): 227 if not os.environ.get('_NT_SYMBOL_PATH'):
208 symbol_dir = MakeTempDir() 228 symbol_dir = MakeTempDir()
209 protocol = 'https' if platform.win32_ver()[0] != 'XP' else 'http' 229 protocol = 'https' if platform.win32_ver()[0] != 'XP' else 'http'
210 os.environ['_NT_SYMBOL_PATH'] = ( 230 os.environ['_NT_SYMBOL_PATH'] = (
211 'SRV*' + symbol_dir + '*' + 231 'SRV*' + symbol_dir + '*' +
212 protocol + '://msdl.microsoft.com/download/symbols') 232 protocol + '://msdl.microsoft.com/download/symbols')
213 233
214 pipe_name = r'\\.\pipe\end-to-end_%s_%s' % ( 234 pipe_name = r'\\.\pipe\end-to-end_%s_%s' % (
215 os.getpid(), str(random.getrandbits(64))) 235 os.getpid(), str(random.getrandbits(64)))
216 236
217 dump_path = GetDumpFromCrashyProgram(args[0], pipe_name) 237 crashy_dump_path = GetDumpFromCrashyProgram(args[0], pipe_name)
218 if not dump_path: 238 if not crashy_dump_path:
219 return 1 239 return 1
220 240
221 RunTests(cdb_path, dump_path, pipe_name) 241 destroyed_dump_path = GetDumpFromSelfDestroyingProgram(args[0], pipe_name)
242 if not destroyed_dump_path:
243 return 1
244
245 RunTests(cdb_path, crashy_dump_path, destroyed_dump_path, pipe_name)
222 246
223 return 0 247 return 0
224 finally: 248 finally:
225 CleanUpTempDirs() 249 CleanUpTempDirs()
226 250
227 251
228 if __name__ == '__main__': 252 if __name__ == '__main__':
229 sys.exit(main(sys.argv[1:])) 253 sys.exit(main(sys.argv[1:]))
OLDNEW
« no previous file with comments | « handler/win/self_destroying_test_program.cc ('k') | snapshot/win/process_snapshot_win.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698