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: |
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 37 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
148 print >>sys.stderr, 'FAILED - %s' % message | 155 print >>sys.stderr, 'FAILED - %s' % message |
149 print >>sys.stderr, '-' * 80 | 156 print >>sys.stderr, '-' * 80 |
150 print >>sys.stderr, 'did not match:\n %s' % pattern | 157 print >>sys.stderr, 'did not match:\n %s' % pattern |
151 print >>sys.stderr, '-' * 80 | 158 print >>sys.stderr, '-' * 80 |
152 print >>sys.stderr, 'remaining output was:\n %s' % self.out | 159 print >>sys.stderr, 'remaining output was:\n %s' % self.out |
153 print >>sys.stderr, '-' * 80 | 160 print >>sys.stderr, '-' * 80 |
154 sys.stderr.flush() | 161 sys.stderr.flush() |
155 sys.exit(1) | 162 sys.exit(1) |
156 | 163 |
157 | 164 |
158 def RunTests(cdb_path, dump_path, destroyed_dump_path, pipe_name): | 165 def RunTests(cdb_path, |
166 dump_path, | |
167 start_handler_dump_path, | |
168 destroyed_dump_path, | |
169 pipe_name): | |
159 """Runs various tests in sequence. Runs a new cdb instance on the dump for | 170 """Runs various tests in sequence. Runs a new cdb instance on the dump for |
160 each block of tests to reduce the chances that output from one command is | 171 each block of tests to reduce the chances that output from one command is |
161 confused for output from another. | 172 confused for output from another. |
162 """ | 173 """ |
163 out = CdbRun(cdb_path, dump_path, '.ecxr') | 174 out = CdbRun(cdb_path, dump_path, '.ecxr') |
164 out.Check('This dump file has an exception of interest stored in it', | 175 out.Check('This dump file has an exception of interest stored in it', |
165 'captured exception') | 176 'captured exception') |
166 out.Check( | 177 out.Check( |
167 'crashy_program!crashpad::`anonymous namespace\'::SomeCrashyFunction', | 178 'crashy_program!crashpad::`anonymous namespace\'::SomeCrashyFunction', |
168 'exception at correct location') | 179 'exception at correct location') |
169 | 180 |
181 out = CdbRun(cdb_path, start_handler_dump_path, '.ecxr') | |
182 out.Check('This dump file has an exception of interest stored in it', | |
183 'captured exception (using StartHandler())') | |
184 out.Check( | |
185 'crashy_program!crashpad::`anonymous namespace\'::SomeCrashyFunction', | |
186 'exception at correct location (using StartHandler())') | |
187 | |
170 out = CdbRun(cdb_path, dump_path, '!peb') | 188 out = CdbRun(cdb_path, dump_path, '!peb') |
171 out.Check(r'PEB at', 'found the PEB') | 189 out.Check(r'PEB at', 'found the PEB') |
172 out.Check(r'Ldr\.InMemoryOrderModuleList:.*\d+ \. \d+', 'PEB_LDR_DATA saved') | 190 out.Check(r'Ldr\.InMemoryOrderModuleList:.*\d+ \. \d+', 'PEB_LDR_DATA saved') |
173 out.Check(r'Base TimeStamp Module', 'module list present') | 191 out.Check(r'Base TimeStamp Module', 'module list present') |
174 pipe_name_escaped = pipe_name.replace('\\', '\\\\') | 192 pipe_name_escaped = pipe_name.replace('\\', '\\\\') |
175 out.Check(r'CommandLine: *\'.*crashy_program.exe *' + pipe_name_escaped, | 193 out.Check(r'CommandLine: *\'.*crashy_program.exe *' + pipe_name_escaped, |
176 'some PEB data is correct') | 194 'some PEB data is correct') |
177 out.Check(r'SystemRoot=C:\\Windows', 'some of environment captured', | 195 out.Check(r'SystemRoot=C:\\Windows', 'some of environment captured', |
178 re.IGNORECASE) | 196 re.IGNORECASE) |
179 | 197 |
(...skipping 51 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
231 'SRV*' + symbol_dir + '*' + | 249 'SRV*' + symbol_dir + '*' + |
232 protocol + '://msdl.microsoft.com/download/symbols') | 250 protocol + '://msdl.microsoft.com/download/symbols') |
233 | 251 |
234 pipe_name = r'\\.\pipe\end-to-end_%s_%s' % ( | 252 pipe_name = r'\\.\pipe\end-to-end_%s_%s' % ( |
235 os.getpid(), str(random.getrandbits(64))) | 253 os.getpid(), str(random.getrandbits(64))) |
236 | 254 |
237 crashy_dump_path = GetDumpFromCrashyProgram(args[0], pipe_name) | 255 crashy_dump_path = GetDumpFromCrashyProgram(args[0], pipe_name) |
238 if not crashy_dump_path: | 256 if not crashy_dump_path: |
239 return 1 | 257 return 1 |
240 | 258 |
259 start_handler_dump_path = GetDumpFromCrashyProgram(args[0], '') | |
scottmg
2015/10/30 23:16:31
I think None rather than '' would be better.
| |
260 if not start_handler_dump_path: | |
261 return 1 | |
262 | |
241 destroyed_dump_path = GetDumpFromSelfDestroyingProgram(args[0], pipe_name) | 263 destroyed_dump_path = GetDumpFromSelfDestroyingProgram(args[0], pipe_name) |
242 if not destroyed_dump_path: | 264 if not destroyed_dump_path: |
243 return 1 | 265 return 1 |
244 | 266 |
245 RunTests(cdb_path, crashy_dump_path, destroyed_dump_path, pipe_name) | 267 RunTests(cdb_path, |
268 crashy_dump_path, | |
269 start_handler_dump_path, | |
270 destroyed_dump_path, | |
271 pipe_name) | |
246 | 272 |
247 return 0 | 273 return 0 |
248 finally: | 274 finally: |
249 CleanUpTempDirs() | 275 CleanUpTempDirs() |
250 | 276 |
251 | 277 |
252 if __name__ == '__main__': | 278 if __name__ == '__main__': |
253 sys.exit(main(sys.argv[1:])) | 279 sys.exit(main(sys.argv[1:])) |
OLD | NEW |