// Copyright (c) 2013 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/chrome_collector.h"

#include <fstream>
#include <glib.h>
#define __STDC_FORMAT_MACROS
#include <inttypes.h>
#include <pcrecpp.h>
#include <string>
#include <vector>

#include <base/file_util.h>
#include <base/logging.h>
#include <base/rand_util.h>
#include <base/string_number_conversions.h>
#include <base/string_util.h>
#include <base/stringprintf.h>
#include "chromeos/process.h"
#include "chromeos/syslog_logging.h"
#include "chromeos/dbus/dbus.h"
#include "chromeos/dbus/service_constants.h"

const char kDefaultMinidumpName[] = "upload_file_minidump";
const char kTarPath[] = "/bin/tar";
// From //net/crash/collector/collector.h
const int kDefaultMaxUploadBytes = 1024 * 1024;

const char kHeader[] = "kernel_task_states";
const char kEnter[] = "enter";
const char kLeave[] = "leave";
const char kSyslogPath[] = "/var/log/messages";
const char kFirstTwoColumnsRE[] = "\\S+\\s+\\S+\\s+";
const char kIdent[] = "crash_reporter";
const char kSpacesRE[] = "\\s+";
const char kKernelIdentRE[] = "kernel:";
const char kKernelTimestampRE[] = "\\[\\s*\\d+\\.\\d+\\]";
const char kTaskNameRE[] = "(.{15})";
// kernel's TASK_STATE_TO_CHAR_STR + '?'
const char kTaskStateRE[] = "([RSDTtZXxKW?])";
const char kHexNumRE[] = "([[:xdigit:]]+)";
const char kNumRE[] = "([[:digit:]]+)";
const char kRunning32[] = "running ";
const char kRunning64[] = " running task   ";
// This regex matches symbol+offset as printed by printk(%pB) or (%pS).
// See https://www.kernel.org/doc/Documentation/printk-formats.txt
// As noted in http://sourceware.org/binutils/docs-2.23.1/as/Symbol-Names.html
// symbols may contain periods and dollars, like "scm_recv.isra.18+0x61/0xdf".
// Strangely, occasionally there is an additional string following the symbol,
// like "qcusbnet_get+0x3e4/0x1e46 [gobi]".
// Those lines will be missing in the output, as parsing them is troublesome.
// Sometimes the address is printed and not the symbol. Those are ignored too.
const char kSymbolAndOffsetRE[] =
    "([[:alpha:]._$][[:alnum:]._$]*)\\+0x([[:xdigit:]]+)/0x([[:xdigit:]]+)";

namespace {

// Extract a string delimited by the given character, from the given offset
// into a source string. Returns false if the string is zero-sized or no
// delimiter was found.
bool GetDelimitedString(const std::string &str, char ch, size_t offset,
                        std::string *substr) {
  size_t at = str.find_first_of(ch, offset);
  if (at == std::string::npos || at == offset)
    return false;
  *substr = str.substr(offset, at - offset);
  return true;
}

bool GetDriErrorState(const chromeos::dbus::Proxy &proxy,
                      const FilePath &error_state_path) {
  chromeos::glib::ScopedError error;
  gchar *error_state = NULL;
  if (!dbus_g_proxy_call(proxy.gproxy(), debugd::kGetLog,
                         &chromeos::Resetter(&error).lvalue(),
                         G_TYPE_STRING, "i915_error_state", G_TYPE_INVALID,
                         G_TYPE_STRING, &error_state, G_TYPE_INVALID)) {
    LOG(ERROR) << "Error performing D-Bus proxy call "
               << "'" << debugd::kGetLog << "'"
               << ": " << (error ? error->message : "");
    g_free(error_state);
    return false;
  }

  std::string error_state_str(error_state);
  g_free(error_state);

  if (error_state_str == "<empty>")
    return false;

  const char kBase64Header[] = "<base64>: ";
  const size_t kBase64HeaderLength = sizeof(kBase64Header) - 1;
  if (error_state_str.compare(0, kBase64HeaderLength, kBase64Header)) {
    LOG(ERROR) << "i915_error_state is missing base64 header";
    return false;
  }

  gsize len;
  guchar *decoded_error_state =
      g_base64_decode(error_state_str.c_str() + kBase64HeaderLength, &len);

  int written;
  written = file_util::WriteFile(error_state_path,
      reinterpret_cast<const char*>(decoded_error_state), len);
  g_free(decoded_error_state);

  if (written < 0 || (gsize)written != len) {
    LOG(ERROR) << "Could not write file " << error_state_path.value();
    file_util::Delete(error_state_path, false);
    return false;
  }

  return true;
}

bool LogKernelTaskStates(const chromeos::dbus::Proxy &proxy,
                         const std::string &task_states_id) {
  // Wrap task states with unique id - header
  LOG(INFO) << kHeader << " " << task_states_id.c_str() << " " << kEnter;

  // Trigger asynchronous logging of task states
  chromeos::glib::ScopedError error;
  if (!dbus_g_proxy_call(proxy.gproxy(), debugd::kLogKernelTaskStates,
                         &chromeos::Resetter(&error).lvalue(),
                         G_TYPE_INVALID, G_TYPE_INVALID)) {
    LOG(ERROR) << "Error performing D-Bus proxy call "
               << "'" << debugd::kLogKernelTaskStates << "'"
               << ": " << (error ? error->message : "");
    return false;
  }

  // Give kernel a second to finish the asynchronous logging
  sleep(1);
  // Wrap task states with unique id - footer
  LOG(INFO) << kHeader << " " << task_states_id.c_str() << " " << kLeave;

  return true;
}

bool GetKernelTaskStates(const chromeos::dbus::Proxy &proxy,
                         std::vector<std::string> *output) {
  std::string task_states_id = StringPrintf("%016"PRIX64, base::RandUint64());

  if (!LogKernelTaskStates(proxy, task_states_id))
    return false;

  std::ifstream syslog_stream(kSyslogPath, std::ios::in);
  if (!syslog_stream.is_open()) {
    LOG(ERROR) << "Couldn't open syslog for reading";
    return false;
  }

  std::string ident_re = StringPrintf("%s\\[%d\\]:\\s+", kIdent, getpid());
  // 2013-07-05T11:52:55.530503-07:00 localhost crash_reporter[9349]:
  // kernel_task_states 33F114E753768B70 enter
  pcrecpp::RE enter_re(kFirstTwoColumnsRE + ident_re + kHeader + " " +
                       task_states_id + " " + kEnter);
  // 2013-07-05T11:52:56.556177-07:00 localhost crash_reporter[9349]:
  // kernel_task_states 33F114E753768B70 leave
  pcrecpp::RE leave_re(kFirstTwoColumnsRE + ident_re + kHeader + " " +
                       task_states_id + " " + kLeave);
  // 2013-06-21T21:18:14.855071+00:00 localhost kernel: [362142.027766]
  // NSS SSL ThreadW S 804f8e28     0  5995   1016 0x00000000
  pcrecpp::RE task_header_re(std::string(kFirstTwoColumnsRE) +
                             kKernelIdentRE + kSpacesRE +
                             kKernelTimestampRE + kSpacesRE +
                             kTaskNameRE + kSpacesRE +
                             kTaskStateRE + kSpacesRE +
                             kHexNumRE + kSpacesRE +
                             kNumRE + kSpacesRE +
                             kNumRE + kSpacesRE +
                             kNumRE + kSpacesRE +
                             "0x" + kHexNumRE);
  // 2013-06-21T21:18:14.815190+00:00 localhost kernel: [362142.016915]
  // rsyslogd        R running      0   340      1 0x00000000
  pcrecpp::RE task_header_run32_re(std::string(kFirstTwoColumnsRE) +
                                   kKernelIdentRE + kSpacesRE +
                                   kKernelTimestampRE + kSpacesRE +
                                   kTaskNameRE + kSpacesRE +
                                   kTaskStateRE + kSpacesRE +
                                   kRunning32 + kSpacesRE +
                                   kNumRE + kSpacesRE +
                                   kNumRE + kSpacesRE +
                                   kNumRE + kSpacesRE +
                                   "0x" + kHexNumRE);
  // 2013-06-21T14:11:18.718810-07:00 localhost kernel: [  656.217932]
  // kworker/2:1     R  running task        0    54      2 0x00000000
  pcrecpp::RE task_header_run64_re(std::string(kFirstTwoColumnsRE) +
                                   kKernelIdentRE + kSpacesRE +
                                   kKernelTimestampRE + kSpacesRE +
                                   kTaskNameRE + kSpacesRE +
                                   kTaskStateRE + kSpacesRE +
                                   kRunning64 + kSpacesRE +
                                   kNumRE + kSpacesRE +
                                   kNumRE + kSpacesRE +
                                   kNumRE + kSpacesRE +
                                   "0x" + kHexNumRE);
  std::string address_re = std::string("\\[<") + kHexNumRE + ">\\]";
  std::string braced_sym_re = std::string("\\(") + kSymbolAndOffsetRE + "\\)";
  // 2013-07-05T11:53:20.141355-07:00 localhost kernel: [  169.476749]
  // [<8002fb74>] (do_wait+0x1a8/0x248) from [<80030c48>] (sys_wait4+0xbc/0xf8)
  pcrecpp::RE arm_stack_re(std::string(kFirstTwoColumnsRE) +
                           kKernelIdentRE + kSpacesRE +
                           kKernelTimestampRE + kSpacesRE +
                           address_re + kSpacesRE +
                           braced_sym_re + kSpacesRE +
                           "from" + kSpacesRE +
                           address_re + kSpacesRE +
                           braced_sym_re);
  // 2013-06-21T14:12:34.457315-07:00 localhost kernel: [  731.965907]
  // [<ffffffff814aa602>] ? system_call_fastpath+0x16/0x1b
  pcrecpp::RE x86_stack_re(std::string(kFirstTwoColumnsRE) +
                           kKernelIdentRE + kSpacesRE +
                           kKernelTimestampRE + kSpacesRE +
                           address_re + kSpacesRE +
                           "(\\?\\s+)?" +
                           kSymbolAndOffsetRE);

  bool enter_matched = false;
  bool leave_matched = false;
  uint64 prev_address = 0;
  std::string line;
  while (std::getline(syslog_stream, line)) {
    if (leave_re.FullMatch(line)) {
      if (!enter_matched) {
        LOG(ERROR) << "Task states header not found before footer";
        return false;
      }
      leave_matched = true;
      break;  // Stop processing input after footer
    }

    if (enter_re.FullMatch(line)) {
      if (enter_matched) {
        LOG(ERROR) << "Task states header encountered twice";
        return false;
      }
      enter_matched = true;
      continue;
    }

    if(!enter_matched)
      continue;  // Skip lines before header

    std::string task_name, task_state;
    uint64 address1, address2;
    unsigned long free_stack;
    pid_t pid, ppid;
    unsigned long flags;
    std::string sym1, sym2;
    uint64 offset1a, offset1b, offset2a, offset2b;
    std::string question;

    if (task_header_re.FullMatch(line, &task_name, &task_state,
                                 pcrecpp::Hex(&address1), &free_stack, &pid,
                                 &ppid, pcrecpp::Hex(&flags))) {
      prev_address = 0;
      output->push_back(StringPrintf("%s %s %016"PRIx64" %5lu %5d %6d 0x%08lx",
                                     task_name.c_str(), task_state.c_str(),
                                     address1, free_stack, pid, ppid, flags));
    } else if (task_header_run32_re.FullMatch(line, &task_name, &task_state,
                                              &free_stack, &pid, &ppid,
                                              pcrecpp::Hex(&flags)) ||
        task_header_run64_re.FullMatch(line, &task_name, &task_state,
                                       &free_stack, &pid, &ppid,
                                       pcrecpp::Hex(&flags))) {
      prev_address = 0;
      output->push_back(StringPrintf("%s %s %s %5lu %5d %6d 0x%08lx",
                                     task_name.c_str(), task_state.c_str(),
                                     kRunning64, free_stack, pid, ppid, flags));
    } else if (arm_stack_re.FullMatch(line, pcrecpp::Hex(&address1), &sym1,
                                      pcrecpp::Hex(&offset1a),
                                      pcrecpp::Hex(&offset1b),
                                      pcrecpp::Hex(&address2), &sym2,
                                      pcrecpp::Hex(&offset2a),
                                      pcrecpp::Hex(&offset2b))) {
      if (prev_address != address1) {
        output->push_back(StringPrintf("%s+0x%"PRIx64"/0x%"PRIx64,
                                       sym1.c_str(), offset1a, offset1b));
      }
      output->push_back(StringPrintf("%s+0x%"PRIx64"/0x%"PRIx64,
                                     sym2.c_str(), offset2a, offset2b));
      prev_address = address2;
    } else if (x86_stack_re.FullMatch(line, pcrecpp::Hex(&address1), &question,
                                      &sym1, pcrecpp::Hex(&offset1a),
                                      pcrecpp::Hex(&offset1b))) {
      output->push_back(StringPrintf("%s%s+0x%"PRIx64"/0x%"PRIx64,
                                     question.c_str(), sym1.c_str(),
                                     offset1a, offset1b));
    }
  }
  syslog_stream.close();

  if(!enter_matched || !leave_matched) {
    LOG(ERROR) << "Task states header or footer not found";
    return false;
  }

  return true;
}

bool WriteKernelTaskStates(const chromeos::dbus::Proxy &proxy,
                           const FilePath &task_states_path) {
  std::ofstream task_states_stream(task_states_path.value().c_str(),
                                   std::ios::out);
  if (!task_states_stream.is_open()) {
    LOG(ERROR) << "Could not write file " << task_states_path.value();
    return false;
  }

  std::vector<std::string> task_sates;
  if (!GetKernelTaskStates(proxy, &task_sates)) {
    file_util::Delete(task_states_path, false);
    return false;
  }

  for (std::vector<std::string>::iterator it = task_sates.begin();
      it != task_sates.end(); ++it) {
    task_states_stream << *it << std::endl;
  }
  task_states_stream.close();

  return true;
}

bool GetAdditionalLogs(const FilePath &log_path) {
  chromeos::dbus::BusConnection dbus = chromeos::dbus::GetSystemBusConnection();
  if (!dbus.HasConnection()) {
    LOG(ERROR) << "Error connecting to system D-Bus";
    return false;
  }

  chromeos::dbus::Proxy proxy(dbus,
                              debugd::kDebugdServiceName,
                              debugd::kDebugdServicePath,
                              debugd::kDebugdInterface);
  if (!proxy) {
    LOG(ERROR) << "Error creating D-Bus proxy to interface "
               << "'" << debugd::kDebugdServiceName << "'";
    return false;
  }

  FilePath error_state_path =
      log_path.DirName().Append("i915_error_state.log.xz");
  bool has_dri_error_state = false;
  if (GetDriErrorState(proxy, error_state_path))
    has_dri_error_state = true;

  FilePath task_states_path = log_path.DirName().Append("task_states.log");
  bool has_task_states = false;
  if (WriteKernelTaskStates(proxy, task_states_path)) {
    has_task_states = true;
  }

  if (!has_dri_error_state && !has_task_states)
    return false;

  chromeos::ProcessImpl tar_process;
  tar_process.AddArg(kTarPath);
  tar_process.AddArg("cfJ");
  tar_process.AddArg(log_path.value());
  tar_process.AddStringOption("-C", log_path.DirName().value());
  if (has_dri_error_state)
    tar_process.AddArg(error_state_path.BaseName().value());
  if (has_task_states)
    tar_process.AddArg(task_states_path.BaseName().value());
  int res = tar_process.Run();

  file_util::Delete(error_state_path, false);
  file_util::Delete(task_states_path, false);

  if (res || !file_util::PathExists(log_path)) {
    LOG(ERROR) << "Could not tar file " << log_path.value();
    return false;
  }

  return true;
}
} //namespace


ChromeCollector::ChromeCollector() {}

ChromeCollector::~ChromeCollector() {}

bool ChromeCollector::HandleCrash(const std::string &file_path,
                                  const std::string &pid_string,
                                  const std::string &uid_string,
                                  const std::string &exe_name) {
  if (!is_feedback_allowed_function_())
    return true;

  if (exe_name.find('/') != std::string::npos) {
    LOG(ERROR) << "exe_name contains illegal characters: " << exe_name;
    return false;
  }

  FilePath dir;
  uid_t uid = atoi(uid_string.c_str());
  pid_t pid = atoi(pid_string.c_str());
  if (!GetCreatedCrashDirectoryByEuid(uid, &dir, NULL)) {
    LOG(ERROR) << "Can't create crash directory for uid " << uid;
    return false;
  }

  std::string dump_basename = FormatDumpBasename(exe_name, time(NULL), pid);
  FilePath meta_path = GetCrashPath(dir, dump_basename, "meta");
  FilePath minidump_path = GetCrashPath(dir, dump_basename, "dmp");
  FilePath log_path = GetCrashPath(dir, dump_basename, "log.tar.xz");

  std::string data;
  if (!file_util::ReadFileToString(FilePath(file_path), &data)) {
    LOG(ERROR) << "Can't read crash log: " << file_path.c_str();
    return false;
  }

  if (!ParseCrashLog(data, dir, minidump_path, dump_basename)) {
    LOG(ERROR) << "Failed to parse Chrome's crash log";
    return false;
  }

  if (GetAdditionalLogs(log_path)) {
    int64 minidump_size = 0;
    int64 log_size = 0;
    if (file_util::GetFileSize(minidump_path, &minidump_size) &&
        file_util::GetFileSize(log_path, &log_size) &&
        minidump_size > 0 && log_size > 0 &&
        minidump_size + log_size < kDefaultMaxUploadBytes) {
      AddCrashMetaData("log", log_path.value());
    } else {
      LOG(INFO) << "Skipping logs upload to prevent discarding minidump "
          "because of report size limit < " << minidump_size + log_size;
      file_util::Delete(log_path, false);
    }
  }

  // We're done.
  WriteCrashMetaData(meta_path, exe_name, minidump_path.value());

  return true;
}

bool ChromeCollector::ParseCrashLog(const std::string &data,
                                    const FilePath &dir,
                                    const FilePath &minidump,
                                    const std::string &basename) {
  size_t at = 0;
  while (at < data.size()) {
    // Look for a : followed by a decimal number, followed by another :
    // followed by N bytes of data.
    std::string name, size_string;
    if (!GetDelimitedString(data, ':', at, &name)) {
      LOG(ERROR) << "Can't find : after name @ offset " << at;
      break;
    }
    at += name.size() + 1; // Skip the name & : delimiter.

    if (!GetDelimitedString(data, ':', at, &size_string)) {
      LOG(ERROR) << "Can't find : after size @ offset " << at;
      break;
    }
    at += size_string.size() + 1; // Skip the size & : delimiter.

    size_t size;
    if (!base::StringToSizeT(size_string, &size)) {
      LOG(ERROR) << "String not convertible to integer: " << size_string;
      break;
    }

    // Data would run past the end, did we get a truncated file?
    if (at + size > data.size()) {
      LOG(ERROR) << "Overrun, expected " << size << " bytes of data, got "
        << (data.size() - at);
      break;
    }

    if (name.find("filename") != std::string::npos) {
      // File.
      // Name will be in a semi-MIME format of
      // <descriptive name>"; filename="<name>"
      // Descriptive name will be upload_file_minidump for the dump.
      std::string desc, filename;
      pcrecpp::RE re("(.*)\" *; *filename=\"(.*)\"");
      if (!re.FullMatch(name.c_str(), &desc, &filename)) {
        LOG(ERROR) << "Filename was not in expected format: " << name;
        break;
      }

      if (desc.compare(kDefaultMinidumpName) == 0) {
        // The minidump.
        WriteNewFile(minidump, data.c_str() + at, size);
      } else {
        // Some other file.
        FilePath path = GetCrashPath(dir, basename + "-" + filename, "other");
        if (WriteNewFile(path, data.c_str() + at, size) >= 0) {
          AddCrashMetaUploadFile(desc, path.value());
        }
      }
    } else {
      // Other attribute.
      std::string value_str;
      value_str.reserve(size);

      // Since metadata is one line/value the values must be escaped properly.
      for (size_t i = at; i < at + size; i++) {
        switch (data[i]) {
          case '"':
          case '\\':
            value_str.push_back('\\');
            value_str.push_back(data[i]);
            break;

          case '\r':
            value_str += "\\r";
            break;

          case '\n':
            value_str += "\\n";
           break;

          case '\t':
            value_str += "\\t";
           break;

          case '\0':
            value_str += "\\0";
           break;

          default:
           value_str.push_back(data[i]);
           break;
        }
      }
      AddCrashMetaUploadData(name, value_str);
    }

    at += size;
  }

  return at == data.size();
}
