blob: 2a2f538661ace43f3e54f4daa34d4d56811dbc2d [file] [log] [blame]
// Copyright 2018 The Chromium OS Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include "crash-reporter/anomaly_collector.h"
#include <pwd.h>
#include <unistd.h>
#include <string>
#include <base/at_exit.h>
#include <base/memory/ref_counted.h>
#include <base/message_loop/message_loop.h>
#include <brillo/flag_helper.h>
#include <brillo/process.h>
#include <brillo/syslog_logging.h>
#include <chromeos/dbus/service_constants.h>
#include <dbus/bus.h>
#include <dbus/exported_object.h>
#include <dbus/message.h>
#include "metrics_event/proto_bindings/metrics_event.pb.h"
namespace {
// D-Bus handle for sending OOM-kill signals. This is owned by |dbus| in
// main().
dbus::ExportedObject* g_dbus_exported_object = nullptr;
// Path to crash_reporter.
const char* crash_reporter_path = "/sbin/crash_reporter";
// Prepares for sending D-Bus signals. Returns a D-Bus object, which provides
// a handle for sending signals.
scoped_refptr<dbus::Bus> SetUpDBus(void) {
// Connect the bus.
dbus::Bus::Options options;
options.bus_type = dbus::Bus::SYSTEM;
scoped_refptr<dbus::Bus> dbus(new dbus::Bus(options));
CHECK(dbus);
CHECK(dbus->Connect()) << "Failed to connect to D-Bus";
// Export a bus object so that other processes can register signal handlers
// (this service only sends signals, no methods are exported).
g_dbus_exported_object = dbus->GetExportedObject(
dbus::ObjectPath(anomaly_collector::kAnomalyEventServicePath));
CHECK(g_dbus_exported_object);
return dbus;
}
} // namespace
// Callback to run crash-reporter.
void RunCrashReporter(int filter, const char* flag, const char* input_path) {
brillo::ProcessImpl cmd;
cmd.RedirectInput(input_path);
cmd.AddArg(crash_reporter_path);
if (!filter)
cmd.AddArg(flag);
CHECK_EQ(0, cmd.Run());
}
void CDBusSendOomSignal(const int64_t oom_timestamp_ms) {
dbus::Signal signal(anomaly_collector::kAnomalyEventServiceInterface,
anomaly_collector::kAnomalyEventSignalName);
dbus::MessageWriter writer(&signal);
metrics_event::Event payload;
payload.set_type(metrics_event::Event_Type_OOM_KILL_KERNEL);
payload.set_timestamp(oom_timestamp_ms);
writer.AppendProtoAsArrayOfBytes(payload);
CHECK(g_dbus_exported_object);
g_dbus_exported_object->SendSignal(&signal);
}
int main(int argc, char* argv[]) {
// Sim sala bim! These are needed to send D-Bus signals. Even though they
// are not used directly, they set up some global state needed by the D-Bus
// library.
base::MessageLoop message_loop;
base::AtExitManager at_exit_manager;
DEFINE_bool(filter, false, "Input is stdin and output is stdout");
DEFINE_bool(test, false, "Run self-tests");
brillo::FlagHelper::Init(argc, argv, "Crash Helper: Anomaly Collector");
brillo::OpenLog("anomaly_collector", true);
brillo::InitLog(brillo::kLogToSyslog | brillo::kLogToStderrIfTty);
if (FLAGS_filter)
crash_reporter_path = "/bin/cat";
else if (FLAGS_test)
crash_reporter_path = "./anomaly_collector_test_reporter.sh";
scoped_refptr<dbus::Bus> dbus;
if (!FLAGS_test)
dbus = SetUpDBus();
return AnomalyLexer(FLAGS_filter, FLAGS_test);
}