OLD | NEW |
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 59 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
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 GetDumpFromProgram(out_dir, pipe_name, executable_name): | 79 def GetDumpFromProgram(out_dir, pipe_name, executable_name): |
80 """Initialize a crash database, run crashpad_handler, run |executable_name| | 80 """Initialize a crash database, and run |executable_name| connecting to a |
81 connecting to the crash_handler. Returns the minidump generated by | 81 crash handler. If pipe_name is set, crashpad_handler will be started first. If |
82 crash_handler for further testing. | 82 pipe_name is empty, the executable is responsible for starting |
| 83 crashpad_handler. Returns the minidump generated by crashpad_handler for |
| 84 further testing. |
83 """ | 85 """ |
84 test_database = MakeTempDir() | 86 test_database = MakeTempDir() |
85 handler = None | 87 handler = None |
86 | 88 |
87 try: | 89 try: |
88 if subprocess.call( | 90 if subprocess.call( |
89 [os.path.join(out_dir, 'crashpad_database_util.exe'), '--create', | 91 [os.path.join(out_dir, 'crashpad_database_util.exe'), '--create', |
90 '--database=' + test_database]) != 0: | 92 '--database=' + test_database]) != 0: |
91 print 'could not initialize report database' | 93 print 'could not initialize report database' |
92 return None | 94 return None |
93 | 95 |
94 handler = subprocess.Popen([ | 96 if pipe_name is not None: |
95 os.path.join(out_dir, 'crashpad_handler.exe'), | 97 handler = subprocess.Popen([ |
96 '--pipe-name=' + pipe_name, | 98 os.path.join(out_dir, 'crashpad_handler.exe'), |
97 '--database=' + test_database | 99 '--pipe-name=' + pipe_name, |
98 ]) | 100 '--database=' + test_database |
| 101 ]) |
99 | 102 |
100 subprocess.call([os.path.join(out_dir, executable_name), pipe_name]) | 103 subprocess.call([os.path.join(out_dir, executable_name), pipe_name]) |
| 104 else: |
| 105 subprocess.call([os.path.join(out_dir, executable_name), |
| 106 os.path.join(out_dir, 'crashpad_handler.exe'), |
| 107 test_database]) |
101 | 108 |
102 out = subprocess.check_output([ | 109 out = subprocess.check_output([ |
103 os.path.join(out_dir, 'crashpad_database_util.exe'), | 110 os.path.join(out_dir, 'crashpad_database_util.exe'), |
104 '--database=' + test_database, | 111 '--database=' + test_database, |
105 '--show-completed-reports', | 112 '--show-completed-reports', |
106 '--show-all-report-info', | 113 '--show-all-report-info', |
107 ]) | 114 ]) |
108 for line in out.splitlines(): | 115 for line in out.splitlines(): |
109 if line.strip().startswith('Path:'): | 116 if line.strip().startswith('Path:'): |
110 return line.partition(':')[2].strip() | 117 return line.partition(':')[2].strip() |
(...skipping 41 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
152 print >>sys.stderr, 'FAILED - %s' % message | 159 print >>sys.stderr, 'FAILED - %s' % message |
153 print >>sys.stderr, '-' * 80 | 160 print >>sys.stderr, '-' * 80 |
154 print >>sys.stderr, 'did not match:\n %s' % pattern | 161 print >>sys.stderr, 'did not match:\n %s' % pattern |
155 print >>sys.stderr, '-' * 80 | 162 print >>sys.stderr, '-' * 80 |
156 print >>sys.stderr, 'remaining output was:\n %s' % self.out | 163 print >>sys.stderr, 'remaining output was:\n %s' % self.out |
157 print >>sys.stderr, '-' * 80 | 164 print >>sys.stderr, '-' * 80 |
158 sys.stderr.flush() | 165 sys.stderr.flush() |
159 sys.exit(1) | 166 sys.exit(1) |
160 | 167 |
161 | 168 |
162 def RunTests(cdb_path, dump_path, destroyed_dump_path, z7_dump_path, pipe_name): | 169 def RunTests(cdb_path, |
| 170 dump_path, |
| 171 start_handler_dump_path, |
| 172 destroyed_dump_path, |
| 173 z7_dump_path, |
| 174 pipe_name): |
163 """Runs various tests in sequence. Runs a new cdb instance on the dump for | 175 """Runs various tests in sequence. Runs a new cdb instance on the dump for |
164 each block of tests to reduce the chances that output from one command is | 176 each block of tests to reduce the chances that output from one command is |
165 confused for output from another. | 177 confused for output from another. |
166 """ | 178 """ |
167 out = CdbRun(cdb_path, dump_path, '.ecxr') | 179 out = CdbRun(cdb_path, dump_path, '.ecxr') |
168 out.Check('This dump file has an exception of interest stored in it', | 180 out.Check('This dump file has an exception of interest stored in it', |
169 'captured exception') | 181 'captured exception') |
170 out.Check( | 182 out.Check( |
171 'crashy_program!crashpad::`anonymous namespace\'::SomeCrashyFunction', | 183 'crashy_program!crashpad::`anonymous namespace\'::SomeCrashyFunction', |
172 'exception at correct location') | 184 'exception at correct location') |
173 | 185 |
| 186 out = CdbRun(cdb_path, start_handler_dump_path, '.ecxr') |
| 187 out.Check('This dump file has an exception of interest stored in it', |
| 188 'captured exception (using StartHandler())') |
| 189 out.Check( |
| 190 'crashy_program!crashpad::`anonymous namespace\'::SomeCrashyFunction', |
| 191 'exception at correct location (using StartHandler())') |
| 192 |
174 out = CdbRun(cdb_path, dump_path, '!peb') | 193 out = CdbRun(cdb_path, dump_path, '!peb') |
175 out.Check(r'PEB at', 'found the PEB') | 194 out.Check(r'PEB at', 'found the PEB') |
176 out.Check(r'Ldr\.InMemoryOrderModuleList:.*\d+ \. \d+', 'PEB_LDR_DATA saved') | 195 out.Check(r'Ldr\.InMemoryOrderModuleList:.*\d+ \. \d+', 'PEB_LDR_DATA saved') |
177 out.Check(r'Base TimeStamp Module', 'module list present') | 196 out.Check(r'Base TimeStamp Module', 'module list present') |
178 pipe_name_escaped = pipe_name.replace('\\', '\\\\') | 197 pipe_name_escaped = pipe_name.replace('\\', '\\\\') |
179 out.Check(r'CommandLine: *\'.*crashy_program.exe *' + pipe_name_escaped, | 198 out.Check(r'CommandLine: *\'.*crashy_program.exe *' + pipe_name_escaped, |
180 'some PEB data is correct') | 199 'some PEB data is correct') |
181 out.Check(r'SystemRoot=C:\\Windows', 'some of environment captured', | 200 out.Check(r'SystemRoot=C:\\Windows', 'some of environment captured', |
182 re.IGNORECASE) | 201 re.IGNORECASE) |
183 | 202 |
(...skipping 60 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
244 'SRV*' + symbol_dir + '*' + | 263 'SRV*' + symbol_dir + '*' + |
245 protocol + '://msdl.microsoft.com/download/symbols') | 264 protocol + '://msdl.microsoft.com/download/symbols') |
246 | 265 |
247 pipe_name = r'\\.\pipe\end-to-end_%s_%s' % ( | 266 pipe_name = r'\\.\pipe\end-to-end_%s_%s' % ( |
248 os.getpid(), str(random.getrandbits(64))) | 267 os.getpid(), str(random.getrandbits(64))) |
249 | 268 |
250 crashy_dump_path = GetDumpFromCrashyProgram(args[0], pipe_name) | 269 crashy_dump_path = GetDumpFromCrashyProgram(args[0], pipe_name) |
251 if not crashy_dump_path: | 270 if not crashy_dump_path: |
252 return 1 | 271 return 1 |
253 | 272 |
| 273 start_handler_dump_path = GetDumpFromCrashyProgram(args[0], None) |
| 274 if not start_handler_dump_path: |
| 275 return 1 |
| 276 |
254 destroyed_dump_path = GetDumpFromSelfDestroyingProgram(args[0], pipe_name) | 277 destroyed_dump_path = GetDumpFromSelfDestroyingProgram(args[0], pipe_name) |
255 if not destroyed_dump_path: | 278 if not destroyed_dump_path: |
256 return 1 | 279 return 1 |
257 | 280 |
258 z7_dump_path = None | 281 z7_dump_path = None |
259 if not args[0].endswith('x64'): | 282 if not args[0].endswith('x64'): |
260 z7_dump_path = GetDumpFromZ7Program(args[0], pipe_name) | 283 z7_dump_path = GetDumpFromZ7Program(args[0], pipe_name) |
261 if not z7_dump_path: | 284 if not z7_dump_path: |
262 return 1 | 285 return 1 |
263 | 286 |
264 RunTests(cdb_path, crashy_dump_path, destroyed_dump_path, z7_dump_path, | 287 RunTests(cdb_path, |
| 288 crashy_dump_path, |
| 289 start_handler_dump_path, |
| 290 destroyed_dump_path, |
| 291 z7_dump_path, |
265 pipe_name) | 292 pipe_name) |
266 | 293 |
267 return 0 | 294 return 0 |
268 finally: | 295 finally: |
269 CleanUpTempDirs() | 296 CleanUpTempDirs() |
270 | 297 |
271 | 298 |
272 if __name__ == '__main__': | 299 if __name__ == '__main__': |
273 sys.exit(main(sys.argv[1:])) | 300 sys.exit(main(sys.argv[1:])) |
OLD | NEW |