OLD | NEW |
1 # Copyright (c) 2010 The Chromium OS Authors. All rights reserved. | 1 # Copyright (c) 2010 The Chromium OS Authors. All rights reserved. |
2 # Use of this source code is governed by a BSD-style license that can be | 2 # Use of this source code is governed by a BSD-style license that can be |
3 # found in the LICENSE file. | 3 # found in the LICENSE file. |
4 | 4 |
5 import grp, logging, os, pwd, re, stat, subprocess | 5 import grp, logging, os, pwd, re, stat, subprocess |
6 from signal import SIGSEGV | 6 from signal import SIGSEGV |
7 from autotest_lib.client.bin import site_crash_test, site_utils, test | 7 from autotest_lib.client.bin import site_crash_test, site_utils, test |
8 from autotest_lib.client.common_lib import error, utils | 8 from autotest_lib.client.common_lib import error, utils |
9 | 9 |
10 _CORE_PATTERN = '/proc/sys/kernel/core_pattern' | 10 _CORE_PATTERN = '/proc/sys/kernel/core_pattern' |
(...skipping 13 matching lines...) Expand all Loading... |
24 """Test that the core_pattern is set up by crash reporter.""" | 24 """Test that the core_pattern is set up by crash reporter.""" |
25 output = utils.read_file(_CORE_PATTERN).rstrip() | 25 output = utils.read_file(_CORE_PATTERN).rstrip() |
26 expected_core_pattern = ('|%s --signal=%%s --pid=%%p' % | 26 expected_core_pattern = ('|%s --signal=%%s --pid=%%p' % |
27 self._CRASH_REPORTER_PATH) | 27 self._CRASH_REPORTER_PATH) |
28 if output != expected_core_pattern: | 28 if output != expected_core_pattern: |
29 raise error.TestFail('core pattern should have been %s, not %s' % | 29 raise error.TestFail('core pattern should have been %s, not %s' % |
30 (expected_core_pattern, output)) | 30 (expected_core_pattern, output)) |
31 | 31 |
32 self._log_reader.set_start_by_reboot(-1) | 32 self._log_reader.set_start_by_reboot(-1) |
33 | 33 |
34 if not self._log_reader.can_find('Enabling crash handling'): | 34 if not self._log_reader.can_find('Enabling user crash handling'): |
35 raise error.TestFail( | 35 raise error.TestFail( |
36 'user space crash handling was not started during last boot') | 36 'user space crash handling was not started during last boot') |
37 | 37 |
38 | 38 |
39 def _test_reporter_shutdown(self): | 39 def _test_reporter_shutdown(self): |
40 """Test the crash_reporter shutdown code works.""" | 40 """Test the crash_reporter shutdown code works.""" |
41 self._log_reader.set_start_by_current() | 41 self._log_reader.set_start_by_current() |
42 utils.system('%s --clean_shutdown' % self._CRASH_REPORTER_PATH) | 42 utils.system('%s --clean_shutdown' % self._CRASH_REPORTER_PATH) |
43 output = utils.read_file(_CORE_PATTERN).rstrip() | 43 output = utils.read_file(_CORE_PATTERN).rstrip() |
44 if output != 'core': | 44 if output != 'core': |
(...skipping 172 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
217 | 217 |
218 def _check_minidump_stackwalk(self, minidump_path, basename, | 218 def _check_minidump_stackwalk(self, minidump_path, basename, |
219 from_crash_reporter): | 219 from_crash_reporter): |
220 # Now stackwalk the minidump | 220 # Now stackwalk the minidump |
221 stack = utils.system_output('/usr/bin/minidump_stackwalk %s %s' % | 221 stack = utils.system_output('/usr/bin/minidump_stackwalk %s %s' % |
222 (minidump_path, self._symbol_dir)) | 222 (minidump_path, self._symbol_dir)) |
223 self._verify_stack(stack, basename, from_crash_reporter) | 223 self._verify_stack(stack, basename, from_crash_reporter) |
224 | 224 |
225 | 225 |
226 def _check_generated_minidump_sending(self, minidump_path, | 226 def _check_generated_minidump_sending(self, minidump_path, |
227 username, crasher_basename): | 227 username, crasher_basename, |
| 228 will_syslog_give_name): |
228 # Now check that the sending works | 229 # Now check that the sending works |
229 self._set_sending(True) | 230 self._set_sending(True) |
230 result = self._call_sender_one_crash( | 231 result = self._call_sender_one_crash( |
231 username=username, | 232 username=username, |
232 minidump=os.path.basename(minidump_path)) | 233 report=os.path.basename(minidump_path)) |
233 if (not result['send_attempt'] or not result['send_success'] or | 234 if (not result['send_attempt'] or not result['send_success'] or |
234 result['minidump_exists']): | 235 result['report_exists']): |
235 raise error.TestFail('Minidump not sent properly') | 236 raise error.TestFail('Minidump not sent properly') |
236 if not crasher_basename in result['output']: | 237 if will_syslog_give_name: |
237 raise error.TestFail('Log did not contain crashing executable name') | 238 if result['exec_name'] != crasher_basename: |
| 239 raise error.TestFail('Executable name incorrect') |
| 240 if result['report_kind'] != 'minidump': |
| 241 raise error.TestFail('Expected a minidump report') |
| 242 if result['report_name'] != minidump_path: |
| 243 raise error.TestFail('Sent the wrong minidump report') |
238 | 244 |
239 | 245 |
240 def _check_crashing_process(self, username, with_breakpad): | 246 def _check_crashing_process(self, username, with_breakpad): |
241 self._log_reader.set_start_by_current() | 247 self._log_reader.set_start_by_current() |
242 | 248 |
243 result = self._run_crasher_process(username, with_breakpad) | 249 result = self._run_crasher_process(username, with_breakpad) |
244 | 250 |
245 if not result['crashed']: | 251 if not result['crashed']: |
246 raise error.TestFail('crasher did not do its job of crashing: %d' % | 252 raise error.TestFail('crasher did not do its job of crashing: %d' % |
247 result['returncode']) | 253 result['returncode']) |
(...skipping 45 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
293 raise error.TestFail('crash reporter did not announce minidump') | 299 raise error.TestFail('crash reporter did not announce minidump') |
294 | 300 |
295 # By default test sending the crash_reporter minidump unless there | 301 # By default test sending the crash_reporter minidump unless there |
296 # is a breakpad minidump, and then we test sending it instead. | 302 # is a breakpad minidump, and then we test sending it instead. |
297 send_minidump = crash_reporter_minidump | 303 send_minidump = crash_reporter_minidump |
298 | 304 |
299 if crash_reporter_minidump: | 305 if crash_reporter_minidump: |
300 self._check_minidump_stackwalk(crash_reporter_minidump, | 306 self._check_minidump_stackwalk(crash_reporter_minidump, |
301 basename, | 307 basename, |
302 from_crash_reporter=True) | 308 from_crash_reporter=True) |
| 309 will_syslog_give_name = True |
303 | 310 |
304 if breakpad_minidump: | 311 if breakpad_minidump: |
305 self._check_minidump_stackwalk(breakpad_minidump, | 312 self._check_minidump_stackwalk(breakpad_minidump, |
306 basename, | 313 basename, |
307 from_crash_reporter=False) | 314 from_crash_reporter=False) |
308 send_minidump = breakpad_minidump | 315 send_minidump = breakpad_minidump |
309 os.unlink(crash_reporter_minidump) | 316 os.unlink(crash_reporter_minidump) |
| 317 # If you link against -lcrash, upon sending the syslog will |
| 318 # just say exec_name: <very-long-guid>, where that GUID is the |
| 319 # GUID generated during breakpad. Since -lcrash is going away, |
| 320 # it seems ok to have the syslog be a little more opaque for |
| 321 # these crashes. They'll be next to sends for the real crash |
| 322 # anyway. |
| 323 will_syslog_give_name = False |
310 | 324 |
311 self._check_generated_minidump_sending(send_minidump, | 325 self._check_generated_minidump_sending(send_minidump, |
312 username, | 326 username, |
313 basename) | 327 basename, |
| 328 will_syslog_give_name) |
314 | 329 |
315 def _test_no_crash(self): | 330 def _test_no_crash(self): |
316 """Test a program linked against libcrash_dumper can exit normally.""" | 331 """Test a program linked against libcrash_dumper can exit normally.""" |
317 self._log_reader.set_start_by_current() | 332 self._log_reader.set_start_by_current() |
318 result = self._run_crasher_process(username='root', | 333 result = self._run_crasher_process(username='root', |
319 with_breakpad=True, | 334 with_breakpad=True, |
320 cause_crash=False) | 335 cause_crash=False) |
321 if (result['crashed'] or | 336 if (result['crashed'] or |
322 result['crash_reporter_caught'] or | 337 result['crash_reporter_caught'] or |
323 result['returncode'] != 0): | 338 result['returncode'] != 0): |
(...skipping 77 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
401 raise error.TestFail('.leave_core file did not disappear') | 416 raise error.TestFail('.leave_core file did not disappear') |
402 self._check_core_file_persisting(False) | 417 self._check_core_file_persisting(False) |
403 finally: | 418 finally: |
404 os.system('umount /root') | 419 os.system('umount /root') |
405 | 420 |
406 | 421 |
407 # TODO(kmixter): Test crashing a process as ntp or some other | 422 # TODO(kmixter): Test crashing a process as ntp or some other |
408 # non-root, non-chronos user. | 423 # non-root, non-chronos user. |
409 | 424 |
410 def run_once(self): | 425 def run_once(self): |
411 self.run_crash_tests([ | 426 self.run_crash_tests(['reporter_startup', |
412 'reporter_startup', | 427 'reporter_shutdown', |
413 'reporter_shutdown', | 428 'no_crash', |
414 'no_crash', | 429 'chronos_breakpad_crasher', |
415 'chronos_breakpad_crasher', | 430 'chronos_nobreakpad_crasher', |
416 'chronos_nobreakpad_crasher', | 431 'root_breakpad_crasher', |
417 'root_breakpad_crasher', | 432 'root_nobreakpad_crasher', |
418 'root_nobreakpad_crasher', | 433 'core_file_persists_in_debug', |
419 'core_file_persists_in_debug', | 434 'core_file_removed_in_production'], |
420 'core_file_removed_in_production', | 435 initialize_crash_reporter = True) |
421 ]) | |
OLD | NEW |