// Copyright (c) 2011, Google Inc.
// All rights reserved.
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are
// met:
//
//     * Redistributions of source code must retain the above copyright
// notice, this list of conditions and the following disclaimer.
//     * Redistributions in binary form must reproduce the above
// copyright notice, this list of conditions and the following disclaimer
// in the documentation and/or other materials provided with the
// distribution.
//     * Neither the name of Google Inc. nor the names of its
// contributors may be used to endorse or promote products derived from
// this software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

// crash_generator.cc: Implement google_breakpad::CrashGenerator.
// See crash_generator.h for details.

#include "common/linux/tests/crash_generator.h"

#include <pthread.h>
#include <signal.h>
#include <stdio.h>
#include <sys/mman.h>
#include <sys/resource.h>
#include <sys/syscall.h>
#include <sys/wait.h>
#include <unistd.h>

#include <string>

#if defined(__ANDROID__)
#include "common/android/testing/pthread_fixes.h"
#endif
#include "common/linux/eintr_wrapper.h"
#include "common/tests/auto_tempdir.h"
#include "common/tests/file_utils.h"
#include "common/using_std_string.h"

namespace {

struct ThreadData {
  pthread_t thread;
  pthread_barrier_t* barrier;
  pid_t* thread_id_ptr;
};

const char* const kProcFilesToCopy[] = {
  "auxv", "cmdline", "environ", "maps", "status"
};
const size_t kNumProcFilesToCopy =
    sizeof(kProcFilesToCopy) / sizeof(kProcFilesToCopy[0]);

int gettid() {
  // Glibc does not provide a wrapper for this.
  return syscall(__NR_gettid);
}

int tkill(pid_t tid, int sig) {
  // Glibc does not provide a wrapper for this.
  return syscall(__NR_tkill, tid, sig);
}

// Core file size limit set to 1 MB, which is big enough for test purposes.
const rlim_t kCoreSizeLimit = 1024 * 1024;

void *thread_function(void *data) {
  ThreadData* thread_data = reinterpret_cast<ThreadData*>(data);
  volatile pid_t thread_id = gettid();
  *(thread_data->thread_id_ptr) = thread_id;
  int result = pthread_barrier_wait(thread_data->barrier);
  if (result != 0 && result != PTHREAD_BARRIER_SERIAL_THREAD) {
    perror("Failed to wait for sync barrier");
    exit(1);
  }
  while (true) {
    pthread_yield();
  }
}

}  // namespace

namespace google_breakpad {

CrashGenerator::CrashGenerator()
    : shared_memory_(NULL),
      shared_memory_size_(0) {
}

CrashGenerator::~CrashGenerator() {
  UnmapSharedMemory();
}

bool CrashGenerator::HasDefaultCorePattern() const {
  char buffer[8];
  ssize_t buffer_size = sizeof(buffer);
  return ReadFile("/proc/sys/kernel/core_pattern", buffer, &buffer_size) &&
         buffer_size == 5 && memcmp(buffer, "core", 4) == 0;
}

string CrashGenerator::GetCoreFilePath() const {
  return temp_dir_.path() + "/core";
}

string CrashGenerator::GetDirectoryOfProcFilesCopy() const {
  return temp_dir_.path() + "/proc";
}

pid_t CrashGenerator::GetThreadId(unsigned index) const {
  return reinterpret_cast<pid_t*>(shared_memory_)[index];
}

pid_t* CrashGenerator::GetThreadIdPointer(unsigned index) {
  return reinterpret_cast<pid_t*>(shared_memory_) + index;
}

bool CrashGenerator::MapSharedMemory(size_t memory_size) {
  if (!UnmapSharedMemory())
    return false;

  void* mapped_memory = mmap(0, memory_size, PROT_READ | PROT_WRITE,
                             MAP_SHARED | MAP_ANONYMOUS, -1, 0);
  if (mapped_memory == MAP_FAILED) {
    perror("CrashGenerator: Failed to map shared memory");
    return false;
  }

  memset(mapped_memory, 0, memory_size);
  shared_memory_ = mapped_memory;
  shared_memory_size_ = memory_size;
  return true;
}

bool CrashGenerator::UnmapSharedMemory() {
  if (!shared_memory_)
    return true;

  if (munmap(shared_memory_, shared_memory_size_) == 0) {
    shared_memory_ = NULL;
    shared_memory_size_ = 0;
    return true;
  }

  perror("CrashGenerator: Failed to unmap shared memory");
  return false;
}

bool CrashGenerator::SetCoreFileSizeLimit(rlim_t limit) const {
  struct rlimit limits = { limit, limit };
  if (setrlimit(RLIMIT_CORE, &limits) == -1) {
    perror("CrashGenerator: Failed to set core file size limit");
    return false;
  }
  return true;
}

bool CrashGenerator::CreateChildCrash(
    unsigned num_threads, unsigned crash_thread, int crash_signal,
    pid_t* child_pid) {
  if (num_threads == 0 || crash_thread >= num_threads) {
    fprintf(stderr, "CrashGenerator: Invalid thread counts; num_threads=%u"
                    " crash_thread=%u\n", num_threads, crash_thread);
    return false;
  }

  if (!MapSharedMemory(num_threads * sizeof(pid_t))) {
    perror("CrashGenerator: Unable to map shared memory");
    return false;
  }

  pid_t pid = fork();
  if (pid == 0) {
    if (chdir(temp_dir_.path().c_str()) == -1) {
      perror("CrashGenerator: Failed to change directory");
      exit(1);
    }
    if (SetCoreFileSizeLimit(kCoreSizeLimit)) {
      CreateThreadsInChildProcess(num_threads);
      string proc_dir = GetDirectoryOfProcFilesCopy();
      if (mkdir(proc_dir.c_str(), 0755) == -1) {
        perror("CrashGenerator: Failed to create proc directory");
        exit(1);
      }
      if (!CopyProcFiles(getpid(), proc_dir.c_str())) {
        fprintf(stderr, "CrashGenerator: Failed to copy proc files\n");
        exit(1);
      }
      // On Android the signal sometimes doesn't seem to get sent even though
      // tkill returns '0'.  Retry a couple of times if the signal doesn't get
      // through on the first go:
      // https://bugs.chromium.org/p/google-breakpad/issues/detail?id=579
#if defined(__ANDROID__)
      const int kRetries = 60;
      const unsigned int kSleepTimeInSeconds = 1;
#else
      const int kRetries = 1;
      const unsigned int kSleepTimeInSeconds = 600;
#endif
      for (int i = 0; i < kRetries; i++) {
        if (tkill(*GetThreadIdPointer(crash_thread), crash_signal) == -1) {
          perror("CrashGenerator: Failed to kill thread by signal");
        } else {
          // At this point, we've queued the signal for delivery, but there's no
          // guarantee when it'll be delivered.  We don't want the main thread to
          // race and exit before the thread we signaled is processed.  So sleep
          // long enough that we won't flake even under fairly high load.
          // TODO: See if we can't be a bit more deterministic.  There doesn't
          // seem to be an API to check on signal delivery status, so we can't
          // really poll and wait for the kernel to declare the signal has been
          // delivered.  If it has, and things worked, we'd be killed, so the
          // sleep length doesn't really matter.
          sleep(kSleepTimeInSeconds);
        }
      }
    } else {
      perror("CrashGenerator: Failed to set core limit");
    }
    exit(1);
  } else if (pid == -1) {
    perror("CrashGenerator: Failed to create child process");
    return false;
  }

  int status;
  if (HANDLE_EINTR(waitpid(pid, &status, 0)) == -1) {
    perror("CrashGenerator: Failed to wait for child process");
    return false;
  }
  if (!WIFSIGNALED(status) || WTERMSIG(status) != crash_signal) {
    fprintf(stderr, "CrashGenerator: Child process not killed by the expected signal\n"
                    "  exit status=0x%x pid=%u signaled=%s sig=%d expected=%d\n",
                    status, pid, WIFSIGNALED(status) ? "true" : "false",
                    WTERMSIG(status), crash_signal);
    return false;
  }

  if (child_pid)
    *child_pid = pid;
  return true;
}

bool CrashGenerator::CopyProcFiles(pid_t pid, const char* path) const {
  char from_path[PATH_MAX], to_path[PATH_MAX];
  for (size_t i = 0; i < kNumProcFilesToCopy; ++i) {
    int num_chars = snprintf(from_path, PATH_MAX, "/proc/%d/%s",
                             pid, kProcFilesToCopy[i]);
    if (num_chars < 0 || num_chars >= PATH_MAX)
      return false;

    num_chars = snprintf(to_path, PATH_MAX, "%s/%s",
                         path, kProcFilesToCopy[i]);
    if (num_chars < 0 || num_chars >= PATH_MAX)
      return false;

    if (!CopyFile(from_path, to_path))
      return false;
  }
  return true;
}

void CrashGenerator::CreateThreadsInChildProcess(unsigned num_threads) {
  *GetThreadIdPointer(0) = getpid();

  if (num_threads <= 1)
    return;

  // This method does not clean up any pthread resource, as the process
  // is expected to be killed anyway.
  ThreadData* thread_data = new ThreadData[num_threads];

  // Create detached threads so that we do not worry about pthread_join()
  // later being called or not.
  pthread_attr_t thread_attributes;
  if (pthread_attr_init(&thread_attributes) != 0 ||
      pthread_attr_setdetachstate(&thread_attributes,
                                  PTHREAD_CREATE_DETACHED) != 0) {
    fprintf(stderr, "CrashGenerator: Failed to initialize thread attribute\n");
    exit(1);
  }

  pthread_barrier_t thread_barrier;
  if (pthread_barrier_init(&thread_barrier, NULL, num_threads) != 0) {
    fprintf(stderr, "CrashGenerator: Failed to initialize thread barrier\n");
    exit(1);
  }

  for (unsigned i = 1; i < num_threads; ++i) {
    thread_data[i].barrier = &thread_barrier;
    thread_data[i].thread_id_ptr = GetThreadIdPointer(i);
    if (pthread_create(&thread_data[i].thread, &thread_attributes,
                       thread_function, &thread_data[i]) != 0) {
      fprintf(stderr, "CrashGenerator: Failed to create thread %d\n", i);
      exit(1);
    }
  }

  int result = pthread_barrier_wait(&thread_barrier);
  if (result != 0 && result != PTHREAD_BARRIER_SERIAL_THREAD) {
    fprintf(stderr, "CrashGenerator: Failed to wait for thread barrier\n");
    exit(1);
  }

  pthread_barrier_destroy(&thread_barrier);
  pthread_attr_destroy(&thread_attributes);
  delete[] thread_data;
}

}  // namespace google_breakpad
