| 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 103 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 114 | 114 |
| 115 | 115 |
| 116 def GetDumpFromCrashyProgram(out_dir, pipe_name): | 116 def GetDumpFromCrashyProgram(out_dir, pipe_name): |
| 117 return GetDumpFromProgram(out_dir, pipe_name, 'crashy_program.exe') | 117 return GetDumpFromProgram(out_dir, pipe_name, 'crashy_program.exe') |
| 118 | 118 |
| 119 | 119 |
| 120 def GetDumpFromSelfDestroyingProgram(out_dir, pipe_name): | 120 def GetDumpFromSelfDestroyingProgram(out_dir, pipe_name): |
| 121 return GetDumpFromProgram(out_dir, pipe_name, 'self_destroying_program.exe') | 121 return GetDumpFromProgram(out_dir, pipe_name, 'self_destroying_program.exe') |
| 122 | 122 |
| 123 | 123 |
| 124 def GetDumpFromZ7Program(out_dir, pipe_name): |
| 125 return GetDumpFromProgram(out_dir, pipe_name, 'crashy_z7_loader.exe') |
| 126 |
| 127 |
| 124 class CdbRun(object): | 128 class CdbRun(object): |
| 125 """Run cdb.exe passing it a cdb command and capturing the output. | 129 """Run cdb.exe passing it a cdb command and capturing the output. |
| 126 `Check()` searches for regex patterns in sequence allowing verification of | 130 `Check()` searches for regex patterns in sequence allowing verification of |
| 127 expected output. | 131 expected output. |
| 128 """ | 132 """ |
| 129 | 133 |
| 130 def __init__(self, cdb_path, dump_path, command): | 134 def __init__(self, cdb_path, dump_path, command): |
| 131 # Run a command line that loads the dump, runs the specified cdb command, | 135 # Run a command line that loads the dump, runs the specified cdb command, |
| 132 # and then quits, and capturing stdout. | 136 # and then quits, and capturing stdout. |
| 133 self.out = subprocess.check_output([ | 137 self.out = subprocess.check_output([ |
| (...skipping 14 matching lines...) Expand all Loading... |
| 148 print >>sys.stderr, 'FAILED - %s' % message | 152 print >>sys.stderr, 'FAILED - %s' % message |
| 149 print >>sys.stderr, '-' * 80 | 153 print >>sys.stderr, '-' * 80 |
| 150 print >>sys.stderr, 'did not match:\n %s' % pattern | 154 print >>sys.stderr, 'did not match:\n %s' % pattern |
| 151 print >>sys.stderr, '-' * 80 | 155 print >>sys.stderr, '-' * 80 |
| 152 print >>sys.stderr, 'remaining output was:\n %s' % self.out | 156 print >>sys.stderr, 'remaining output was:\n %s' % self.out |
| 153 print >>sys.stderr, '-' * 80 | 157 print >>sys.stderr, '-' * 80 |
| 154 sys.stderr.flush() | 158 sys.stderr.flush() |
| 155 sys.exit(1) | 159 sys.exit(1) |
| 156 | 160 |
| 157 | 161 |
| 158 def RunTests(cdb_path, dump_path, destroyed_dump_path, pipe_name): | 162 def RunTests(cdb_path, dump_path, destroyed_dump_path, z7_dump_path, pipe_name): |
| 159 """Runs various tests in sequence. Runs a new cdb instance on the dump for | 163 """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 | 164 each block of tests to reduce the chances that output from one command is |
| 161 confused for output from another. | 165 confused for output from another. |
| 162 """ | 166 """ |
| 163 out = CdbRun(cdb_path, dump_path, '.ecxr') | 167 out = CdbRun(cdb_path, dump_path, '.ecxr') |
| 164 out.Check('This dump file has an exception of interest stored in it', | 168 out.Check('This dump file has an exception of interest stored in it', |
| 165 'captured exception') | 169 'captured exception') |
| 166 out.Check( | 170 out.Check( |
| 167 'crashy_program!crashpad::`anonymous namespace\'::SomeCrashyFunction', | 171 'crashy_program!crashpad::`anonymous namespace\'::SomeCrashyFunction', |
| 168 'exception at correct location') | 172 'exception at correct location') |
| (...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 205 out.Check(r'ntdll\.dll', 'ntdll present', re.IGNORECASE) | 209 out.Check(r'ntdll\.dll', 'ntdll present', re.IGNORECASE) |
| 206 | 210 |
| 207 # Check that there is no stack trace in the self-destroyed process. Confirm | 211 # 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 | 212 # 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 | 213 # stack entries will not be available. This confirms that we have a mostly |
| 210 # valid dump, but that the stack was omitted. | 214 # valid dump, but that the stack was omitted. |
| 211 out.Check(r'self_destroying_program!crashpad::`anonymous namespace\'::' | 215 out.Check(r'self_destroying_program!crashpad::`anonymous namespace\'::' |
| 212 r'FreeOwnStackAndBreak.*\nquit:', | 216 r'FreeOwnStackAndBreak.*\nquit:', |
| 213 'at correct location, no additional stack entries') | 217 'at correct location, no additional stack entries') |
| 214 | 218 |
| 219 if z7_dump_path: |
| 220 out = CdbRun(cdb_path, z7_dump_path, '.ecxr;lm') |
| 221 out.Check('This dump file has an exception of interest stored in it', |
| 222 'captured exception in z7 module') |
| 223 out.Check(r'z7_test\+0x[0-8a-f]+:', 'exception in z7 at correct location') |
| 224 out.Check(r'z7_test C \(codeview symbols\) z7_test.dll', |
| 225 'expected non-pdb symbol format') |
| 226 |
| 227 |
| 215 def main(args): | 228 def main(args): |
| 216 try: | 229 try: |
| 217 if len(args) != 1: | 230 if len(args) != 1: |
| 218 print >>sys.stderr, 'must supply binary dir' | 231 print >>sys.stderr, 'must supply binary dir' |
| 219 return 1 | 232 return 1 |
| 220 | 233 |
| 221 cdb_path = GetCdbPath() | 234 cdb_path = GetCdbPath() |
| 222 if not cdb_path: | 235 if not cdb_path: |
| 223 print >>sys.stderr, 'could not find cdb' | 236 print >>sys.stderr, 'could not find cdb' |
| 224 return 1 | 237 return 1 |
| (...skipping 10 matching lines...) Expand all Loading... |
| 235 os.getpid(), str(random.getrandbits(64))) | 248 os.getpid(), str(random.getrandbits(64))) |
| 236 | 249 |
| 237 crashy_dump_path = GetDumpFromCrashyProgram(args[0], pipe_name) | 250 crashy_dump_path = GetDumpFromCrashyProgram(args[0], pipe_name) |
| 238 if not crashy_dump_path: | 251 if not crashy_dump_path: |
| 239 return 1 | 252 return 1 |
| 240 | 253 |
| 241 destroyed_dump_path = GetDumpFromSelfDestroyingProgram(args[0], pipe_name) | 254 destroyed_dump_path = GetDumpFromSelfDestroyingProgram(args[0], pipe_name) |
| 242 if not destroyed_dump_path: | 255 if not destroyed_dump_path: |
| 243 return 1 | 256 return 1 |
| 244 | 257 |
| 245 RunTests(cdb_path, crashy_dump_path, destroyed_dump_path, pipe_name) | 258 z7_dump_path = None |
| 259 if not args[0].endswith('x64'): |
| 260 z7_dump_path = GetDumpFromZ7Program(args[0], pipe_name) |
| 261 if not z7_dump_path: |
| 262 return 1 |
| 263 |
| 264 RunTests(cdb_path, crashy_dump_path, destroyed_dump_path, z7_dump_path, |
| 265 pipe_name) |
| 246 | 266 |
| 247 return 0 | 267 return 0 |
| 248 finally: | 268 finally: |
| 249 CleanUpTempDirs() | 269 CleanUpTempDirs() |
| 250 | 270 |
| 251 | 271 |
| 252 if __name__ == '__main__': | 272 if __name__ == '__main__': |
| 253 sys.exit(main(sys.argv[1:])) | 273 sys.exit(main(sys.argv[1:])) |
| OLD | NEW |