/*
 * Copyright (C) 2015 The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

#if __linux__
#include <errno.h>
#include <signal.h>
#include <string.h>
#include <unistd.h>
#include <sys/ptrace.h>
#include <sys/wait.h>
#endif

#include "jni.h"

#include <backtrace/Backtrace.h>

#include "base/logging.h"
#include "base/macros.h"
#include "gc/heap.h"
#include "gc/space/image_space.h"
#include "oat_file.h"
#include "utils.h"

namespace art {

// For testing debuggerd. We do not have expected-death tests, so can't test this by default.
// Code for this is copied from SignalTest.
static constexpr bool kCauseSegfault = false;
char* go_away_compiler_cfi = nullptr;

static void CauseSegfault() {
#if defined(__arm__) || defined(__i386__) || defined(__x86_64__) || defined(__aarch64__)
  // On supported architectures we cause a real SEGV.
  *go_away_compiler_cfi = 'a';
#else
  // On other architectures we simulate SEGV.
  kill(getpid(), SIGSEGV);
#endif
}

extern "C" JNIEXPORT jboolean JNICALL Java_Main_sleep(JNIEnv*, jobject, jint, jboolean, jdouble) {
  // Keep pausing.
  for (;;) {
    pause();
  }
}

// Helper to look for a sequence in the stack trace.
#if __linux__
static bool CheckStack(Backtrace* bt, const std::vector<std::string>& seq) {
  size_t cur_search_index = 0;  // The currently active index in seq.
  CHECK_GT(seq.size(), 0U);

  for (Backtrace::const_iterator it = bt->begin(); it != bt->end(); ++it) {
    if (BacktraceMap::IsValid(it->map)) {
      LOG(INFO) << "Got " << it->func_name << ", looking for " << seq[cur_search_index];
      if (it->func_name == seq[cur_search_index]) {
        cur_search_index++;
        if (cur_search_index == seq.size()) {
          return true;
        }
      }
    }
  }

  printf("Can not find %s in backtrace:\n", seq[cur_search_index].c_str());
  for (Backtrace::const_iterator it = bt->begin(); it != bt->end(); ++it) {
    if (BacktraceMap::IsValid(it->map)) {
      printf("  %s\n", it->func_name.c_str());
    }
  }

  return false;
}
#endif

// Currently we have to fall back to our own loader for the boot image when it's compiled PIC
// because its base is zero. Thus in-process unwinding through it won't work. This is a helper
// detecting this.
#if __linux__
static bool IsPicImage() {
  gc::space::ImageSpace* image_space = Runtime::Current()->GetHeap()->GetImageSpace();
  CHECK(image_space != nullptr);  // We should be running with an image.
  const OatFile* oat_file = image_space->GetOatFile();
  CHECK(oat_file != nullptr);     // We should have an oat file to go with the image.
  return oat_file->IsPic();
}
#endif

extern "C" JNIEXPORT jboolean JNICALL Java_Main_unwindInProcess(JNIEnv*, jobject, jint, jboolean) {
#if __linux__
  if (IsPicImage()) {
    LOG(INFO) << "Image is pic, in-process unwinding check bypassed.";
    return JNI_TRUE;
  }

  // TODO: What to do on Valgrind?

  std::unique_ptr<Backtrace> bt(Backtrace::Create(BACKTRACE_CURRENT_PROCESS, GetTid()));
  if (!bt->Unwind(0, nullptr)) {
    printf("Can not unwind in process.\n");
    return JNI_FALSE;
  } else if (bt->NumFrames() == 0) {
    printf("No frames for unwind in process.\n");
    return JNI_FALSE;
  }

  // We cannot really parse an exact stack, as the optimizing compiler may inline some functions.
  // This is also risky, as deduping might play a trick on us, so the test needs to make sure that
  // only unique functions are being expected.
  std::vector<std::string> seq = {
      "Java_Main_unwindInProcess",                   // This function.
      "boolean Main.unwindInProcess(int, boolean)",  // The corresponding Java native method frame.
      "int java.util.Arrays.binarySearch(java.lang.Object[], int, int, java.lang.Object, java.util.Comparator)",  // Framework method.
      "void Main.main(java.lang.String[])"           // The Java entry method.
  };

  bool result = CheckStack(bt.get(), seq);
  if (!kCauseSegfault) {
    return result ? JNI_TRUE : JNI_FALSE;
  } else {
    LOG(INFO) << "Result of check-stack: " << result;
  }
#endif

  if (kCauseSegfault) {
    CauseSegfault();
  }

  return JNI_FALSE;
}

#if __linux__
static constexpr int kSleepTimeMicroseconds = 50000;            // 0.05 seconds
static constexpr int kMaxTotalSleepTimeMicroseconds = 1000000;  // 1 second

// Wait for a sigstop. This code is copied from libbacktrace.
int wait_for_sigstop(pid_t tid, int* total_sleep_time_usec, bool* detach_failed ATTRIBUTE_UNUSED) {
  for (;;) {
    int status;
    pid_t n = TEMP_FAILURE_RETRY(waitpid(tid, &status, __WALL | WNOHANG));
    if (n == -1) {
      PLOG(WARNING) << "waitpid failed: tid " << tid;
      break;
    } else if (n == tid) {
      if (WIFSTOPPED(status)) {
        return WSTOPSIG(status);
      } else {
        PLOG(ERROR) << "unexpected waitpid response: n=" << n << ", status=" << std::hex << status;
        break;
      }
    }

    if (*total_sleep_time_usec > kMaxTotalSleepTimeMicroseconds) {
      PLOG(WARNING) << "timed out waiting for stop signal: tid=" << tid;
      break;
    }

    usleep(kSleepTimeMicroseconds);
    *total_sleep_time_usec += kSleepTimeMicroseconds;
  }

  return -1;
}
#endif

extern "C" JNIEXPORT jboolean JNICALL Java_Main_unwindOtherProcess(JNIEnv*, jobject, jint pid_int) {
#if __linux__
  // TODO: What to do on Valgrind?
  pid_t pid = static_cast<pid_t>(pid_int);

  // OK, this is painful. debuggerd uses ptrace to unwind other processes.

  if (ptrace(PTRACE_ATTACH, pid, 0, 0)) {
    // Were not able to attach, bad.
    printf("Failed to attach to other process.\n");
    PLOG(ERROR) << "Failed to attach.";
    kill(pid, SIGKILL);
    return JNI_FALSE;
  }

  kill(pid, SIGSTOP);

  bool detach_failed = false;
  int total_sleep_time_usec = 0;
  int signal = wait_for_sigstop(pid, &total_sleep_time_usec, &detach_failed);
  if (signal == -1) {
    LOG(WARNING) << "wait_for_sigstop failed.";
  }

  std::unique_ptr<Backtrace> bt(Backtrace::Create(pid, BACKTRACE_CURRENT_THREAD));
  bool result = true;
  if (!bt->Unwind(0, nullptr)) {
    printf("Can not unwind other process.\n");
    result = false;
  } else if (bt->NumFrames() == 0) {
    printf("No frames for unwind of other process.\n");
    result = false;
  }

  if (result) {
    // See comment in unwindInProcess for non-exact stack matching.
    std::vector<std::string> seq = {
        // "Java_Main_sleep",                        // The sleep function being executed in the
                                                     // other runtime.
                                                     // Note: For some reason, the name isn't
                                                     // resolved, so don't look for it right now.
        "boolean Main.sleep(int, boolean, double)",  // The corresponding Java native method frame.
        "int java.util.Arrays.binarySearch(java.lang.Object[], int, int, java.lang.Object, java.util.Comparator)",  // Framework method.
        "void Main.main(java.lang.String[])"         // The Java entry method.
    };

    result = CheckStack(bt.get(), seq);
  }

  if (ptrace(PTRACE_DETACH, pid, 0, 0) != 0) {
    PLOG(ERROR) << "Detach failed";
  }

  // Kill the other process once we are done with it.
  kill(pid, SIGKILL);

  return result ? JNI_TRUE : JNI_FALSE;
#else
  return JNI_FALSE;
#endif
}

}  // namespace art
