// Copyright 2019 The Fuchsia 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 "src/developer/debug/zxdb/client/stack.h"

#include <lib/syslog/cpp/macros.h>

#include <map>

#include <gtest/gtest.h>

#include "llvm/BinaryFormat/Dwarf.h"
#include "src/developer/debug/shared/message_loop.h"
#include "src/developer/debug/zxdb/client/frame_fingerprint.h"
#include "src/developer/debug/zxdb/client/mock_frame.h"
#include "src/developer/debug/zxdb/client/mock_stack_delegate.h"
#include "src/developer/debug/zxdb/client/session.h"
#include "src/developer/debug/zxdb/common/err.h"
#include "src/developer/debug/zxdb/common/test_with_loop.h"
#include "src/developer/debug/zxdb/expr/eval_context.h"
#include "src/developer/debug/zxdb/expr/expr.h"
#include "src/developer/debug/zxdb/symbols/function.h"
#include "src/developer/debug/zxdb/symbols/type_test_support.h"
#include "src/developer/debug/zxdb/symbols/variable.h"

namespace zxdb {

namespace {

class StackTest : public TestWithLoop {};

// Stack pointers used by MakeInlineStackFrames.
constexpr uint64_t kTopSP = 0x2000;
constexpr uint64_t kMiddleSP = 0x2020;
constexpr uint64_t kBottomSP = 0x2040;

// Returns a set of stack frames:
//   [0] =   inline #2 from frame 2
//   [1] =   inline #1 from frame 2
//   [2] = physical frame at kTopSP
//   [3] =   inline from frame 4
//   [4] = physical frame at kMiddleSP
//   [5] = physical frame at kBottomSP
std::vector<std::unique_ptr<Frame>> MakeInlineStackFrames() {
  // Create three physical frames.
  Location top_location(Location::State::kSymbolized, 0x1000);
  Location middle_location(Location::State::kSymbolized, 0x1010);
  Location bottom_location(Location::State::kSymbolized, 0x1020);

  auto phys_top = std::make_unique<MockFrame>(nullptr, nullptr, top_location, kTopSP, kMiddleSP);
  auto phys_middle =
      std::make_unique<MockFrame>(nullptr, nullptr, middle_location, kMiddleSP, kBottomSP);
  auto phys_bottom = std::make_unique<MockFrame>(nullptr, nullptr, bottom_location, kBottomSP, 0);

  std::vector<std::unique_ptr<Frame>> frames;

  // Top frame has two inline functions expanded on top of it. This uses the same Location object
  // for simplicity, in real life these will be different.
  frames.push_back(std::make_unique<MockFrame>(nullptr, nullptr, top_location, kTopSP, kMiddleSP,
                                               std::vector<debug::RegisterValue>(), kTopSP,
                                               phys_top.get()));
  frames.push_back(std::make_unique<MockFrame>(nullptr, nullptr, top_location, kTopSP, kMiddleSP,
                                               std::vector<debug::RegisterValue>(), kTopSP,
                                               phys_top.get()));

  // Physical top frame below those.
  frames.push_back(std::move(phys_top));

  // Middle frame has one inline function expanded on top of it.
  frames.push_back(std::make_unique<MockFrame>(nullptr, nullptr, middle_location, kMiddleSP,
                                               kBottomSP, std::vector<debug::RegisterValue>(),
                                               kMiddleSP, phys_middle.get()));
  frames.push_back(std::move(phys_middle));

  // Bottom frame has no inline frame.
  frames.push_back(std::move(phys_bottom));

  return frames;
}

}  // namespace

// IndexForFrame is trivial when there's no inline frame, but when there is, the returned index
// must take this into account.
TEST_F(StackTest, IndexForFrame) {
  Session session;
  MockStackDelegate delegate(&session);
  Stack stack(&delegate);
  delegate.set_stack(&stack);

  // Set some stack frames with inline frames. Nothing should start out as hidden.
  auto frames = MakeInlineStackFrames();

  // Make a function for the top stack frame. It needs this to get the ranges for the ambiguity
  // comuptation.
  auto func = fxl::MakeRefCounted<Function>(DwarfTag::kInlinedSubroutine);
  func->set_assigned_name("Inline");
  // Must start exactly at kBottomAddr for the location to be ambiguous.
  uint64_t ambiguous_address = frames[0]->GetLocation().address();
  func->set_code_ranges(AddressRanges(AddressRange(ambiguous_address, ambiguous_address + 8)));

  // Force the top frame to be ambiguous. For this it needs an inline function that starts at the
  // current address.
  Location ambig_loc(ambiguous_address, FileLine("file", 10), 0,
                     SymbolContext::ForRelativeAddresses(), func);
  auto new_top_frame = std::make_unique<MockFrame>(nullptr, nullptr, ambig_loc, kTopSP, kMiddleSP,
                                                   std::vector<debug::RegisterValue>(), kTopSP,
                                                   frames[0]->GetPhysicalFrame());
  new_top_frame->set_is_ambiguous_inline(true);
  frames[0] = std::move(new_top_frame);

  stack.SetFramesForTest(std::move(frames), true);
  ASSERT_EQ(1u, stack.GetAmbiguousInlineFrameCount());
  EXPECT_EQ(0u, stack.hide_ambiguous_inline_frame_count());

  // The operator[] and the IndexForFrame results should match.
  for (size_t i = 0; i < stack.size(); i++)
    EXPECT_EQ(i, stack.IndexForFrame(stack[i])) << i;

  // Hide some inline frames, the indices should still match.
  stack.SetHideAmbiguousInlineFrameCount(1);
  for (size_t i = 0; i < stack.size(); i++)
    EXPECT_EQ(i, stack.IndexForFrame(stack[i])) << i;
}

// Tests fingerprint computations involving inline frames.
TEST_F(StackTest, InlineFingerprint) {
  Session session;
  MockStackDelegate delegate(&session);
  Stack stack(&delegate);
  delegate.set_stack(&stack);
  stack.SetFramesForTest(MakeInlineStackFrames(), true);

  // The top frames (physical and inline) have the middle frame's SP as their fingerprint, along
  // with the inline count.
  EXPECT_EQ(FrameFingerprint(kMiddleSP, 2), stack.GetFrameFingerprint(0));
  EXPECT_EQ(2u, stack.InlineDepthForIndex(0));
  EXPECT_EQ(FrameFingerprint(kMiddleSP, 1), stack.GetFrameFingerprint(1));
  EXPECT_EQ(1u, stack.InlineDepthForIndex(1));
  EXPECT_EQ(FrameFingerprint(kMiddleSP, 0), stack.GetFrameFingerprint(2));
  EXPECT_EQ(0u, stack.InlineDepthForIndex(2));

  // Middle frames have the bottom frame's SP.
  EXPECT_EQ(FrameFingerprint(kBottomSP, 1), stack.GetFrameFingerprint(3));
  EXPECT_EQ(1u, stack.InlineDepthForIndex(3));
  EXPECT_EQ(FrameFingerprint(kBottomSP, 0), stack.GetFrameFingerprint(4));
  EXPECT_EQ(0u, stack.InlineDepthForIndex(4));

  // Bottom frame reports the 0 CFA.
  EXPECT_EQ(FrameFingerprint(0, 0), stack.GetFrameFingerprint(5));
  EXPECT_EQ(0u, stack.InlineDepthForIndex(5));
}

// Tests that stack frames inside inline functions are expanded so that the inline functions have
// their own "inline" frames.
//
// This tests a bottom function calling an inline function which calls a top function. The tricky
// part is the IP of the bottom frame is actually in a different inline function (the "ambiguous"
// one) because the address in the bottom frame is immediately following the TopFunc() call and this
// happens to fall in range of an inlined function. This should be omitted from the stack.
//
//   void TopFunc() {
//     ...                          // <- top_line
//   }
//
//   // Not actually on the stack but looks like it.
//   inline void bottom_ambig_inline_func() {
//     ...                          // <- inline_exec_line
//   }
//
//   inline void bottom_inline_func() {
//     ...
//     TopFunc();                   // Non-inline
//     bottom_ambig_inline_func();  // <- inline_ambig_call_line
//   }
//
//   void bottom() {
//     ...
//     bottom_inline_func();       // <- inline_call_line
//     ...
//   }
TEST_F(StackTest, InlineExpansion) {
  constexpr uint64_t kBottomAddr = 0x127365;  // IP for bottom stack frame.
  constexpr uint64_t kTopAddr = 0x893746123;  // IP for top stack frale.

  const char kFileName[] = "file.cc";
  FileLine inline_ambig_call_line(kFileName, 5);
  FileLine inline_call_line(kFileName, 10);
  FileLine inline_exec_line(kFileName, 20);
  FileLine top_line(kFileName, 30);

  Session session;
  MockStackDelegate delegate(&session);
  SymbolContext symbol_context = SymbolContext::ForRelativeAddresses();

  // Non-inline location for the top stack frame.
  auto top_func = fxl::MakeRefCounted<Function>(DwarfTag::kSubprogram);
  top_func->set_assigned_name("Top");
  Location top_location(kTopAddr, top_line, 0, symbol_context, top_func);
  delegate.AddLocation(top_location);

  // Bottom stack frame has a real function, an inline function, and an ambiguous inline location
  // (at the start of an inline range).
  auto bottom_ambig_inline_func = fxl::MakeRefCounted<Function>(DwarfTag::kInlinedSubroutine);
  bottom_ambig_inline_func->set_assigned_name("Inline");
  // Must start exactly at kBottomAddr for the location to be ambiguous.
  bottom_ambig_inline_func->set_code_ranges(
      AddressRanges(AddressRange(kBottomAddr, kBottomAddr + 8)));
  bottom_ambig_inline_func->set_call_line(inline_ambig_call_line);

  auto bottom_inline_func = fxl::MakeRefCounted<Function>(DwarfTag::kInlinedSubroutine);
  bottom_inline_func->set_assigned_name("Inline");
  // Must start before at kBottomAddr for the location to not be ambiguous.
  bottom_inline_func->set_code_ranges(
      AddressRanges(AddressRange(kBottomAddr - 8, kBottomAddr + 8)));
  bottom_inline_func->set_call_line(inline_call_line);

  auto bottom_func = fxl::MakeRefCounted<Function>(DwarfTag::kSubprogram);
  bottom_func->set_assigned_name("Bottom");
  bottom_func->set_code_ranges(AddressRanges(AddressRange(kBottomAddr - 8, kBottomAddr + 16)));

  // Our containing functions don't have references to the contained functions so we don't have to
  // worry about a reference cycle here (hence "unsafe").
  bottom_ambig_inline_func->set_containing_block(
      UncachedLazySymbol::MakeUnsafe(bottom_inline_func));
  bottom_inline_func->set_containing_block(UncachedLazySymbol::MakeUnsafe(bottom_func));

  // The location returned by the symbol function will have the file/line inside the inline
  // function.
  Location bottom_location(kBottomAddr, inline_exec_line, 0, symbol_context,
                           bottom_ambig_inline_func);
  delegate.AddLocation(bottom_location);

  Stack stack(&delegate);
  delegate.set_stack(&stack);

  // Send IPs that will map to the bottom and top addresses.
  constexpr uint64_t kTopSP = 0x100;
  constexpr uint64_t kBottomSP = 0x200;

  stack.SetFrames(debug_ipc::ThreadRecord::StackAmount::kFull,
                  {debug_ipc::StackFrame(kTopAddr, kTopSP, kBottomSP),
                   debug_ipc::StackFrame(kBottomAddr, kBottomSP, 0)});

  // This should expand to tree stack entries, the one in the middle should be the inline function
  // expanded from the "bottom".
  EXPECT_EQ(3u, stack.size());

  // Bottom stack frame should be the non-inline bottom function.
  EXPECT_FALSE(stack[2]->IsInline());
  EXPECT_EQ(stack[2], stack[2]->GetPhysicalFrame());
  EXPECT_EQ(kBottomAddr, stack[2]->GetAddress());
  Location loc = stack[2]->GetLocation();
  EXPECT_EQ(kBottomAddr, loc.address());
  EXPECT_EQ(inline_call_line, loc.file_line());
  EXPECT_EQ(bottom_func.get(), loc.symbol().Get()->As<Function>());

  // Middle stack frame should be the inline bottom function, referencing the bottom one as the
  // physical frame. The location should be the call line of the ambiguous inline function because
  // it's next, even though that function was omitted from the stack.
  EXPECT_TRUE(stack[1]->IsInline());
  EXPECT_EQ(stack[2], stack[1]->GetPhysicalFrame());
  EXPECT_EQ(kBottomAddr, stack[1]->GetAddress());
  loc = stack[1]->GetLocation();
  EXPECT_EQ(kBottomAddr, loc.address());
  EXPECT_EQ(inline_ambig_call_line, loc.file_line());
  EXPECT_EQ(bottom_inline_func.get(), loc.symbol().Get()->As<Function>());

  // The bottom_ambig_inline_func should be skipped because it's at the beginning of an inline call
  // and it's not at the top physical frame of the stack.

  // Top stack frame.
  EXPECT_FALSE(stack[0]->IsInline());
  EXPECT_EQ(stack[0], stack[0]->GetPhysicalFrame());
  EXPECT_EQ(kTopAddr, stack[0]->GetAddress());
  loc = stack[0]->GetLocation();
  EXPECT_EQ(kTopAddr, loc.address());
  EXPECT_EQ(top_line, loc.file_line());
  EXPECT_EQ(top_func.get(), loc.symbol().Get()->As<Function>());
}

TEST_F(StackTest, InlineHiding) {
  constexpr uint64_t kTopSP = 0x2000;
  constexpr uint64_t kBottomSP = 0x2020;

  // Create two physical frames.
  Location top_location(Location::State::kSymbolized, 0x1000);
  Location bottom_location(Location::State::kSymbolized, 0x1020);

  auto phys_top = std::make_unique<MockFrame>(nullptr, nullptr, top_location, kTopSP);
  auto phys_bottom = std::make_unique<MockFrame>(nullptr, nullptr, bottom_location, kBottomSP);

  std::vector<std::unique_ptr<Frame>> frames;

  // Top frame has two inline functions expanded on top of it.
  frames.push_back(std::make_unique<MockFrame>(nullptr, nullptr, top_location, kTopSP, 0,
                                               std::vector<debug::RegisterValue>(), kTopSP,
                                               phys_top.get(), true));
  frames.push_back(std::make_unique<MockFrame>(nullptr, nullptr, top_location, kTopSP, 0,
                                               std::vector<debug::RegisterValue>(), kTopSP,
                                               phys_top.get(), true));

  // Physical top frame below those.
  frames.push_back(std::move(phys_top));

  // Bottom frame has no inline frame.
  frames.push_back(std::move(phys_bottom));

  Session session;
  MockStackDelegate delegate(&session);
  Stack stack(&delegate);
  delegate.set_stack(&stack);

  // With no frames, there should be no inline frames.
  EXPECT_EQ(0u, stack.GetAmbiguousInlineFrameCount());

  // Setting the frames should give the two inline ones, followed by two physical ones.
  stack.SetFramesForTest(std::move(frames), true);
  EXPECT_EQ(4u, stack.size());
  EXPECT_EQ(2u, stack.GetAmbiguousInlineFrameCount());

  // Hide both inline frames, the top frame should now be the physical one.
  stack.SetHideAmbiguousInlineFrameCount(2);
  EXPECT_EQ(2u, stack.size());
  EXPECT_EQ(2u, stack.GetAmbiguousInlineFrameCount());
}

// Appends stack items to an already existing stack via SetFrames(). The existing frames and the
// inline hide count should be unchanged.
TEST_F(StackTest, UpdateExisting) {
  Session session;
  MockStackDelegate delegate(&session);
  Stack stack(&delegate);
  delegate.set_stack(&stack);

  // Make a stack with one physial frame and one inline frame above it.
  Location top_location(Location::State::kSymbolized, 0x1000);
  auto phys_top = std::make_unique<MockFrame>(nullptr, nullptr, top_location, kTopSP, 0,
                                              std::vector<debug::RegisterValue>(), kTopSP);
  auto inline_top = std::make_unique<MockFrame>(nullptr, nullptr, top_location, kTopSP, 0,
                                                std::vector<debug::RegisterValue>(), kTopSP,
                                                phys_top.get(), true);
  inline_top->set_is_ambiguous_inline(true);

  // Save for verification later.
  const Frame* frame0 = inline_top.get();
  const Frame* frame1 = phys_top.get();

  std::vector<std::unique_ptr<Frame>> input_frames;
  input_frames.push_back(std::move(inline_top));
  input_frames.push_back(std::move(phys_top));
  stack.SetFramesForTest(std::move(input_frames), true);

  // The ambiguous inline frame is hidden so we can check later this is preserved across updates.
  ASSERT_EQ(2u, stack.size());
  ASSERT_EQ(1u, stack.GetAmbiguousInlineFrameCount());
  stack.SetHideAmbiguousInlineFrameCount(1);

  // Synthesize a frame update. The first physical frame matches the first physical frame from
  // above. This uses the non-test update flow which should preserve the frame objects that haven't
  // changed.
  std::vector<debug_ipc::StackFrame> raw_frames;
  debug_ipc::StackFrame phys_top_record(0x1000, kTopSP, kBottomSP);
  raw_frames.push_back(phys_top_record);
  debug_ipc::StackFrame phys_bottom_record(0x1020, kBottomSP);
  raw_frames.push_back(phys_bottom_record);

  stack.SetFrames(debug_ipc::ThreadRecord::StackAmount::kFull, raw_frames);

  // The update should have left the existing top physical frame and the inline frame expanded on
  // top of it, and add the additional physical frame below it.
  EXPECT_EQ(1u, stack.GetAmbiguousInlineFrameCount());
  // Now that we checked it, reset the hidden frame count so we can see them.
  stack.SetHideAmbiguousInlineFrameCount(0);
  ASSERT_EQ(3u, stack.size());
  EXPECT_EQ(frame0, stack[0]);
  EXPECT_EQ(frame1, stack[1]);
  EXPECT_EQ(phys_bottom_record.ip, stack[2]->GetAddress());

  // Now supply a slightly different stack, it should be replaced and the hidden inline frame count
  // reset.
  stack.SetHideAmbiguousInlineFrameCount(0);  // So we can test for reset.
  raw_frames[0].sp++;                         // Modify frame.
  stack.SetFrames(debug_ipc::ThreadRecord::StackAmount::kFull, raw_frames);

  // The inline frame at the top should have gone away because we didn't provide any inline
  // information for the Stack to expand it.
  ASSERT_EQ(2u, stack.size());
  EXPECT_EQ(0u, stack.GetAmbiguousInlineFrameCount());
  EXPECT_EQ(raw_frames[0].ip, stack[0]->GetAddress());
  EXPECT_EQ(raw_frames[0].sp, stack[0]->GetStackPointer());
  EXPECT_EQ(raw_frames[1].ip, stack[1]->GetAddress());
  EXPECT_EQ(raw_frames[1].sp, stack[1]->GetStackPointer());
}

// Tests that variables in inline functions are found during evaluation.
//
// This sets up an inline frame and makes sure we can read a local variable out of it.
TEST_F(StackTest, InlineVars) {
  constexpr uint64_t kInlineAddr = 0x1002;
  constexpr uint64_t kPhysAddr = 0x1000;

  Session session;
  MockStackDelegate delegate(&session);
  SymbolContext symbol_context = SymbolContext::ForRelativeAddresses();

  // Make inline function.
  auto inline_func = fxl::MakeRefCounted<Function>(DwarfTag::kInlinedSubroutine);
  inline_func->set_code_ranges(AddressRanges(AddressRange(kInlineAddr, kInlineAddr + 8)));

  // The inline function has a local variable ("var") that always evaluates to 3.
  VariableLocation var_loc(DwarfExpr({llvm::dwarf::DW_OP_lit3, llvm::dwarf::DW_OP_stack_value}));

  auto int32_type = MakeInt32Type();
  auto inline_var =
      fxl::MakeRefCounted<Variable>(DwarfTag::kVariable, "var", LazySymbol(int32_type), var_loc);
  inline_func->set_variables({LazySymbol(inline_var)});

  // Make physical fuction.
  auto phys_func = fxl::MakeRefCounted<Function>(DwarfTag::kSubprogram);
  phys_func->set_code_ranges(AddressRanges(AddressRange(kPhysAddr, kPhysAddr + 16)));
  inline_func->set_containing_block(UncachedLazySymbol::MakeUnsafe(phys_func));

  // Physical stack frame.
  Location phys_location(kPhysAddr, FileLine("file.cc", 200), 0, symbol_context, phys_func);
  delegate.AddLocation(phys_location);

  // Inline frame on top of that.
  Location inline_location(kInlineAddr, FileLine("file.cc", 100), 0, symbol_context, inline_func);
  delegate.AddLocation(inline_location);

  Stack stack(&delegate);
  delegate.set_stack(&stack);

  stack.SetFrames(debug_ipc::ThreadRecord::StackAmount::kFull,
                  {debug_ipc::StackFrame(kInlineAddr, kTopSP, kBottomSP)});
  ASSERT_EQ(2u, stack.size());  // Should have expanded the inline frame.

  // ACTUAL TEST.

  // Evaluate "var + 1" which should be "4" given var evaluates to 3.
  auto eval_context = stack[0]->GetEvalContext();
  bool called = false;
  EvalExpression("var + 1", eval_context, true, [&called](ErrOrValue value) mutable {
    called = true;
    EXPECT_FALSE(value.has_error());

    int64_t result = 0;
    Err e = value.value().PromoteTo64(&result);
    EXPECT_FALSE(e.has_error());
    EXPECT_EQ(4, result);
  });
  EXPECT_TRUE(called);  // Callback should have been issued.
}

}  // namespace zxdb
