// Copyright (c) 2017, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

#include "lib/stacktrace.h"
#include "vm/compiler/assembler/disassembler.h"
#include "vm/heap/safepoint.h"
#include "vm/object.h"
#include "vm/os_thread.h"
#include "vm/stack_frame.h"

namespace dart {

#if !defined(PRODUCT)

#if defined(__GNUC__)
// Older toolchains don't know about "retain"
#pragma GCC diagnostic ignored "-Wattributes"
#define GDB_HELPER extern "C" __attribute__((used, retain))
#else
#define GDB_HELPER extern "C"
#endif

GDB_HELPER
void* _currentThread() {
  return OSThread::CurrentVMThread();
}

GDB_HELPER
void _printObjectPtr(uword object) {
  OS::PrintErr("%s\n",
               Object::Handle(static_cast<ObjectPtr>(object)).ToCString());
}

GDB_HELPER
Object* _handle(uword object) {
  return &Object::Handle(static_cast<ObjectPtr>(object));
}

GDB_HELPER
void _disassemble(uword pc) {
  Code& code = Code::Handle(Code::FindCodeUnsafe(pc));
  if (code.IsNull()) {
    OS::PrintErr("No code found\n");
  } else {
    Object& owner = Object::Handle(code.owner());
    if (owner.IsFunction()) {
      Disassembler::DisassembleCode(Function::Cast(owner), code,
                                    code.is_optimized());
    } else {
      Disassembler::DisassembleStub(code.Name(), code);
    }
  }
}

// An utility method for convenient printing of dart stack traces when
// inside 'gdb'. Note: This function will only work when there is a
// valid exit frame information. It will not work when a breakpoint is
// set in dart code and control is got inside 'gdb' without going through
// the runtime or native transition stub.
GDB_HELPER
void _printDartStackTrace() {
  const StackTrace& stacktrace = GetCurrentStackTrace(0);
  OS::PrintErr("=== Current Trace:\n%s===\n", stacktrace.ToCString());
}

// Like _printDartStackTrace, but works in a NoSafepointScope. Use it if you're
// in the middle of a GC or interested in stub frames.
GDB_HELPER
void _printStackTrace() {
  StackFrame::DumpCurrentTrace();
}

// Like _printDartStackTrace, but works when stopped in generated code.
// Must be called with the current fp, sp, and pc. I.e.,
//
// (gdb) print _printGeneratedStackTrace($rbp, $rsp, $rip)
GDB_HELPER
void _printGeneratedStackTrace(uword fp, uword sp, uword pc) {
  StackFrameIterator frames(fp, sp, pc, ValidationPolicy::kDontValidateFrames,
                            Thread::Current(),
                            StackFrameIterator::kNoCrossThreadIteration);
  StackFrame* frame = frames.NextFrame();
  while (frame != nullptr) {
    OS::PrintErr("%s\n", frame->ToCString());
    frame = frames.NextFrame();
  }
}

class PrintObjectPointersVisitor : public ObjectPointerVisitor {
 public:
  PrintObjectPointersVisitor()
      : ObjectPointerVisitor(IsolateGroup::Current()) {}

  void VisitPointers(ObjectPtr* first, ObjectPtr* last) override {
    for (ObjectPtr* p = first; p <= last; p++) {
      Object& obj = Object::Handle(*p);
      OS::PrintErr("%p: %s\n", p, obj.ToCString());
    }
  }

#if defined(DART_COMPRESSED_POINTERS)
  void VisitCompressedPointers(uword heap_base,
                               CompressedObjectPtr* first,
                               CompressedObjectPtr* last) override {
    for (CompressedObjectPtr* p = first; p <= last; p++) {
      Object& obj = Object::Handle(p->Decompress(heap_base));
      OS::PrintErr("%p: %s\n", p, obj.ToCString());
    }
  }
#endif
};

GDB_HELPER
void _printStackTraceWithLocals() {
  PrintObjectPointersVisitor visitor;
  StackFrameIterator frames(ValidationPolicy::kDontValidateFrames,
                            Thread::Current(),
                            StackFrameIterator::kNoCrossThreadIteration);
  StackFrame* frame = frames.NextFrame();
  while (frame != nullptr) {
    OS::PrintErr("%s\n", frame->ToCString());
    frame->VisitObjectPointers(&visitor);
    frame = frames.NextFrame();
  }
}

#endif  // !PRODUCT

}  // namespace dart
