/*
 * Copyright (C) 2013 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.
 */

/*
 * Contributed by: Intel Corporation
 */

#include <gtest/gtest.h>

#include <dlfcn.h>
#include <signal.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/types.h>
#include <unistd.h>
#include <unwind.h>

#include "SignalUtils.h"

#define noinline __attribute__((__noinline__))
#define __unused __attribute__((__unused__))

_Unwind_Reason_Code FrameCounter(_Unwind_Context* ctx __unused, void* arg) {
  int* count_ptr = reinterpret_cast<int*>(arg);

#if SHOW_FRAME_LOCATIONS
  void* ip = reinterpret_cast<void*>(_Unwind_GetIP(ctx));

  const char* symbol = "<unknown>";
  int offset = 0;

  Dl_info info;
  memset(&info, 0, sizeof(info));
  if (dladdr(ip, &info) != 0) {
    symbol = info.dli_sname;
    if (info.dli_saddr != nullptr) {
      offset = static_cast<int>(reinterpret_cast<char*>(ip) - reinterpret_cast<char*>(info.dli_saddr));
    }
  }

  fprintf(stderr, " #%02d %p %s%+d (%s)\n", *count_ptr, ip, symbol, offset, info.dli_fname ? info.dli_fname : "??");
  fflush(stderr);
#endif

  ++*count_ptr;
  return _URC_NO_REASON;
}

static int noinline unwind_one_frame_deeper() {
  int count = 0;
  _Unwind_Backtrace(FrameCounter, &count);
  return count;
}

static void UnwindTest() {
  int count = 0;
  _Unwind_Backtrace(FrameCounter, &count);
  int deeper_count = unwind_one_frame_deeper();
  ASSERT_EQ(count + 1, deeper_count);
}

TEST(stack_unwinding, easy) {
  UnwindTest();
}

TEST(stack_unwinding, thread) {
  pthread_t thread;
  ASSERT_EQ(0, pthread_create(&thread, nullptr, [](void*) -> void* {
    UnwindTest();
    return nullptr;
  }, nullptr));
  void *retval;
  ASSERT_EQ(0, pthread_join(thread, &retval));
  EXPECT_EQ(nullptr, retval);
}

struct UnwindData {
  volatile bool signal_handler_complete = false;
  int expected_frame_count = 0;
  int handler_frame_count = 0;
  int handler_one_deeper_frame_count = 0;
};

static UnwindData g_unwind_data;

static void noinline UnwindSignalHandler(int) {
  _Unwind_Backtrace(FrameCounter, &g_unwind_data.handler_frame_count);

  g_unwind_data.handler_one_deeper_frame_count = unwind_one_frame_deeper();
  g_unwind_data.signal_handler_complete = true;
}

static void verify_unwind_data(const UnwindData& unwind_data) {
  // In order to avoid a false positive, the caller must have at least 2 frames
  // outside of the signal handler. This avoids a case where the only frame
  // right after the signal handler winds up being garbage.
  EXPECT_GT(unwind_data.handler_frame_count, unwind_data.expected_frame_count + 1);

  EXPECT_EQ(unwind_data.handler_frame_count + 1, unwind_data.handler_one_deeper_frame_count);
}

static void noinline SignalUnwindTest() {
  g_unwind_data = {};

  _Unwind_Backtrace(FrameCounter, &g_unwind_data.expected_frame_count);
  ASSERT_LE(2, g_unwind_data.expected_frame_count)
      << "The current call must contain at least 2 frames for the test to be valid.";

  ASSERT_EQ(0, kill(getpid(), SIGUSR1));
  while (!g_unwind_data.signal_handler_complete) {}

  verify_unwind_data(g_unwind_data);
}

TEST(stack_unwinding, unwind_through_signal_frame) {
  ScopedSignalHandler ssh(SIGUSR1, UnwindSignalHandler);

  SignalUnwindTest();
}

// On LP32, the SA_SIGINFO flag gets you __restore_rt instead of __restore.
TEST(stack_unwinding, unwind_through_signal_frame_SA_SIGINFO) {
  ScopedSignalHandler ssh(SIGUSR1, UnwindSignalHandler, SA_SIGINFO);

  SignalUnwindTest();
}
