blob: 2c09ad0782d8e78a20f73840e43e12960d92aea1 [file] [log] [blame]
Darin Petkovf0136cd2012-11-07 16:18:02 +01001// Copyright (c) 2012 The Chromium OS Authors. All rights reserved.
2// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
4
5#include "shill/diagnostics_reporter.h"
6
7#include <sys/types.h>
8#include <sys/wait.h>
9#include <unistd.h>
10
11#include <base/bind.h>
12
13#include "shill/event_dispatcher.h"
14
15using base::Bind;
16
17namespace shill {
18
19namespace {
20
21base::LazyInstance<DiagnosticsReporter> g_reporter = LAZY_INSTANCE_INITIALIZER;
22
23} // namespace
24
25DiagnosticsReporter::DiagnosticsReporter()
26 : dispatcher_(NULL),
27 weak_ptr_factory_(this) {}
28
29DiagnosticsReporter::~DiagnosticsReporter() {}
30
31// static
32DiagnosticsReporter *DiagnosticsReporter::GetInstance() {
33 return g_reporter.Pointer();
34}
35
36void DiagnosticsReporter::Init(EventDispatcher *dispatcher) {
37 dispatcher_ = dispatcher;
38}
39
40void DiagnosticsReporter::Report() {
41 // Trigger the crash from the main event loop to try to ensure minimal and
42 // consistent stack trace. TODO(petkov): Look into invoking crash_reporter
43 // directly without actually triggering a crash.
44 dispatcher_->PostTask(Bind(&DiagnosticsReporter::TriggerCrash,
45 weak_ptr_factory_.GetWeakPtr()));
46}
47
48bool DiagnosticsReporter::IsReportingEnabled() {
49 // TODO(petkov): Implement this when there's a way to control reporting
50 // through policy. crosbug.com/35946.
51 return false;
52}
53
54void DiagnosticsReporter::TriggerCrash() {
55 if (!IsReportingEnabled()) {
56 return;
57 }
58 pid_t pid = fork();
59 if (pid < 0) {
60 PLOG(ERROR) << "fork() failed.";
61 NOTREACHED();
62 return;
63 }
64 if (pid == 0) {
65 // Crash the child.
66 abort();
67 }
68 // The parent waits for the child to terminate.
69 pid_t result = waitpid(pid, NULL, 0);
70 PLOG_IF(ERROR, result < 0) << "waitpid() failed.";
71}
72
73} // namespace shill