| 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 |