//===-- Debugger.cpp --------------------------------------------*- C++ -*-===//
//
//                     The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//

#include "lldb/Core/Debugger.h"

#include "lldb/Breakpoint/Breakpoint.h" // for Breakpoint, Brea...
#include "lldb/Core/Event.h"            // for Event, EventData...
#include "lldb/Core/FormatEntity.h"
#include "lldb/Core/Listener.h" // for Listener
#include "lldb/Core/Mangled.h"  // for Mangled
#include "lldb/Core/ModuleList.h"  // for Mangled
#include "lldb/Core/PluginManager.h"
#include "lldb/Core/State.h"
#include "lldb/Core/StreamAsynchronousIO.h"
#include "lldb/Core/StreamFile.h"
#include "lldb/DataFormatters/DataVisualization.h"
#include "lldb/Expression/REPL.h"
#include "lldb/Host/File.h" // for File, File::kInv...
#include "lldb/Host/HostInfo.h"
#include "lldb/Host/Terminal.h"
#include "lldb/Host/ThreadLauncher.h"
#include "lldb/Interpreter/CommandInterpreter.h"
#include "lldb/Interpreter/OptionValue.h" // for OptionValue, Opt...
#include "lldb/Interpreter/OptionValueProperties.h"
#include "lldb/Interpreter/OptionValueSInt64.h"
#include "lldb/Interpreter/OptionValueString.h"
#include "lldb/Interpreter/Property.h"          // for PropertyDefinition
#include "lldb/Interpreter/ScriptInterpreter.h" // for ScriptInterpreter
#include "lldb/Symbol/Function.h"
#include "lldb/Symbol/Symbol.h"
#include "lldb/Symbol/SymbolContext.h" // for SymbolContext
#include "lldb/Target/Language.h"
#include "lldb/Target/Process.h"
#include "lldb/Target/StructuredDataPlugin.h"
#include "lldb/Target/Target.h"
#include "lldb/Target/TargetList.h"
#include "lldb/Target/Thread.h"
#include "lldb/Target/ThreadList.h" // for ThreadList
#include "lldb/Utility/AnsiTerminal.h"
#include "lldb/Utility/Log.h"    // for LLDB_LOG_OPTION_...
#include "lldb/Utility/Stream.h" // for Stream
#include "lldb/Utility/StreamCallback.h"
#include "lldb/Utility/StreamString.h"

#if defined(_WIN32)
#include "lldb/Host/windows/PosixApi.h" // for PATH_MAX
#endif

#include "llvm/ADT/None.h"      // for None
#include "llvm/ADT/STLExtras.h" // for make_unique
#include "llvm/ADT/StringRef.h"
#include "llvm/ADT/iterator.h" // for iterator_facade_...
#include "llvm/Support/DynamicLibrary.h"
#include "llvm/Support/FileSystem.h"
#include "llvm/Support/Threading.h"
#include "llvm/Support/raw_ostream.h" // for raw_fd_ostream

#include <list>   // for list
#include <memory> // for make_shared
#include <mutex>
#include <set>          // for set
#include <stdio.h>      // for size_t, NULL
#include <stdlib.h>     // for getenv
#include <string.h>     // for strcmp
#include <string>       // for string
#include <system_error> // for error_code

namespace lldb_private {
class Address;
}

using namespace lldb;
using namespace lldb_private;

static lldb::user_id_t g_unique_id = 1;
static size_t g_debugger_event_thread_stack_bytes = 8 * 1024 * 1024;

#pragma mark Static Functions

typedef std::vector<DebuggerSP> DebuggerList;
static std::recursive_mutex *g_debugger_list_mutex_ptr =
    nullptr; // NOTE: intentional leak to avoid issues with C++ destructor chain
static DebuggerList *g_debugger_list_ptr =
    nullptr; // NOTE: intentional leak to avoid issues with C++ destructor chain

OptionEnumValueElement g_show_disassembly_enum_values[] = {
    {Debugger::eStopDisassemblyTypeNever, "never",
     "Never show disassembly when displaying a stop context."},
    {Debugger::eStopDisassemblyTypeNoDebugInfo, "no-debuginfo",
     "Show disassembly when there is no debug information."},
    {Debugger::eStopDisassemblyTypeNoSource, "no-source",
     "Show disassembly when there is no source information, or the source file "
     "is missing when displaying a stop context."},
    {Debugger::eStopDisassemblyTypeAlways, "always",
     "Always show disassembly when displaying a stop context."},
    {0, nullptr, nullptr}};

OptionEnumValueElement g_language_enumerators[] = {
    {eScriptLanguageNone, "none", "Disable scripting languages."},
    {eScriptLanguagePython, "python",
     "Select python as the default scripting language."},
    {eScriptLanguageDefault, "default",
     "Select the lldb default as the default scripting language."},
    {0, nullptr, nullptr}};

#define MODULE_WITH_FUNC                                                       \
  "{ "                                                                         \
  "${module.file.basename}{`${function.name-with-args}"                        \
  "{${frame.no-debug}${function.pc-offset}}}}"

#define MODULE_WITH_FUNC_NO_ARGS                                               \
  "{ "                                                                         \
  "${module.file.basename}{`${function.name-without-args}"                     \
  "{${frame.no-debug}${function.pc-offset}}}}"

#define FILE_AND_LINE "{ at ${line.file.basename}:${line.number}}"
#define IS_OPTIMIZED "{${function.is-optimized} [opt]}"

#define DEFAULT_THREAD_FORMAT                                                  \
  "thread #${thread.index}: tid = ${thread.id%tid}"                            \
  "{, ${frame.pc}}" MODULE_WITH_FUNC FILE_AND_LINE                             \
  "{, name = '${thread.name}'}"                                                \
  "{, queue = '${thread.queue}'}"                                              \
  "{, activity = '${thread.info.activity.name}'}"                              \
  "{, ${thread.info.trace_messages} messages}"                                 \
  "{, stop reason = ${thread.stop-reason}}"                                    \
  "{\\nReturn value: ${thread.return-value}}"                                  \
  "{\\nCompleted expression: ${thread.completed-expression}}"                  \
  "\\n"

#define DEFAULT_THREAD_STOP_FORMAT                                             \
  "thread #${thread.index}{, name = '${thread.name}'}"                         \
  "{, queue = '${thread.queue}'}"                                              \
  "{, activity = '${thread.info.activity.name}'}"                              \
  "{, ${thread.info.trace_messages} messages}"                                 \
  "{, stop reason = ${thread.stop-reason}}"                                    \
  "{\\nReturn value: ${thread.return-value}}"                                  \
  "{\\nCompleted expression: ${thread.completed-expression}}"                  \
  "\\n"

#define DEFAULT_FRAME_FORMAT                                                   \
  "frame #${frame.index}: ${frame.pc}" MODULE_WITH_FUNC FILE_AND_LINE          \
      IS_OPTIMIZED "\\n"

#define DEFAULT_FRAME_FORMAT_NO_ARGS                                           \
  "frame #${frame.index}: ${frame.pc}" MODULE_WITH_FUNC_NO_ARGS FILE_AND_LINE  \
      IS_OPTIMIZED "\\n"

// Three parts to this disassembly format specification:
//   1. If this is a new function/symbol (no previous symbol/function), print
//      dylib`funcname:\n
//   2. If this is a symbol context change (different from previous
//   symbol/function), print
//      dylib`funcname:\n
//   3. print
//      address <+offset>:
#define DEFAULT_DISASSEMBLY_FORMAT                                             \
  "{${function.initial-function}{${module.file.basename}`}{${function.name-"   \
  "without-args}}:\n}{${function.changed}\n{${module.file.basename}`}{${"      \
  "function.name-without-args}}:\n}{${current-pc-arrow} "                      \
  "}${addr-file-or-load}{ "                                                    \
  "<${function.concrete-only-addr-offset-no-padding}>}: "

// gdb's disassembly format can be emulated with ${current-pc-arrow}${addr-
// file-or-load}{ <${function.name-without-args}${function.concrete-only-addr-
// offset-no-padding}>}:

// lldb's original format for disassembly would look like this format string -
// {${function.initial-function}{${module.file.basename}`}{${function.name-
// without-
// args}}:\n}{${function.changed}\n{${module.file.basename}`}{${function.name-
// without-args}}:\n}{${current-pc-arrow} }{${addr-file-or-load}}:

#define DEFAULT_STOP_SHOW_COLUMN_ANSI_PREFIX "${ansi.underline}"
#define DEFAULT_STOP_SHOW_COLUMN_ANSI_SUFFIX "${ansi.normal}"

static OptionEnumValueElement s_stop_show_column_values[] = {
    {eStopShowColumnAnsiOrCaret, "ansi-or-caret",
     "Highlight the stop column with ANSI terminal codes when color/ANSI mode "
     "is enabled; otherwise, fall back to using a text-only caret (^) as if "
     "\"caret-only\" mode was selected."},
    {eStopShowColumnAnsi, "ansi", "Highlight the stop column with ANSI "
                                  "terminal codes when running LLDB with "
                                  "color/ANSI enabled."},
    {eStopShowColumnCaret, "caret",
     "Highlight the stop column with a caret character (^) underneath the stop "
     "column. This method introduces a new line in source listings that "
     "display thread stop locations."},
    {eStopShowColumnNone, "none", "Do not highlight the stop column."},
    {0, nullptr, nullptr}};

static PropertyDefinition g_properties[] = {
    {"auto-confirm", OptionValue::eTypeBoolean, true, false, nullptr, nullptr,
     "If true all confirmation prompts will receive their default reply."},
    {"disassembly-format", OptionValue::eTypeFormatEntity, true, 0,
     DEFAULT_DISASSEMBLY_FORMAT, nullptr,
     "The default disassembly format "
     "string to use when disassembling "
     "instruction sequences."},
    {"frame-format", OptionValue::eTypeFormatEntity, true, 0,
     DEFAULT_FRAME_FORMAT, nullptr,
     "The default frame format string to use "
     "when displaying stack frame information "
     "for threads."},
    {"notify-void", OptionValue::eTypeBoolean, true, false, nullptr, nullptr,
     "Notify the user explicitly if an expression returns void (default: "
     "false)."},
    {"prompt", OptionValue::eTypeString, true,
     OptionValueString::eOptionEncodeCharacterEscapeSequences, "(lldb) ",
     nullptr, "The debugger command line prompt displayed for the user."},
    {"script-lang", OptionValue::eTypeEnum, true, eScriptLanguagePython,
     nullptr, g_language_enumerators,
     "The script language to be used for evaluating user-written scripts."},
    {"stop-disassembly-count", OptionValue::eTypeSInt64, true, 4, nullptr,
     nullptr,
     "The number of disassembly lines to show when displaying a "
     "stopped context."},
    {"stop-disassembly-display", OptionValue::eTypeEnum, true,
     Debugger::eStopDisassemblyTypeNoDebugInfo, nullptr,
     g_show_disassembly_enum_values,
     "Control when to display disassembly when displaying a stopped context."},
    {"stop-line-count-after", OptionValue::eTypeSInt64, true, 3, nullptr,
     nullptr,
     "The number of sources lines to display that come after the "
     "current source line when displaying a stopped context."},
    {"stop-line-count-before", OptionValue::eTypeSInt64, true, 3, nullptr,
     nullptr,
     "The number of sources lines to display that come before the "
     "current source line when displaying a stopped context."},
    {"stop-show-column", OptionValue::eTypeEnum, false,
     eStopShowColumnAnsiOrCaret, nullptr, s_stop_show_column_values,
     "If true, LLDB will use the column information from the debug info to "
     "mark the current position when displaying a stopped context."},
    {"stop-show-column-ansi-prefix", OptionValue::eTypeFormatEntity, true, 0,
     DEFAULT_STOP_SHOW_COLUMN_ANSI_PREFIX, nullptr,
     "When displaying the column marker in a color-enabled (i.e. ANSI) "
     "terminal, use the ANSI terminal code specified in this format at the "
     "immediately before the column to be marked."},
    {"stop-show-column-ansi-suffix", OptionValue::eTypeFormatEntity, true, 0,
     DEFAULT_STOP_SHOW_COLUMN_ANSI_SUFFIX, nullptr,
     "When displaying the column marker in a color-enabled (i.e. ANSI) "
     "terminal, use the ANSI terminal code specified in this format "
     "immediately after the column to be marked."},
    {"term-width", OptionValue::eTypeSInt64, true, 80, nullptr, nullptr,
     "The maximum number of columns to use for displaying text."},
    {"thread-format", OptionValue::eTypeFormatEntity, true, 0,
     DEFAULT_THREAD_FORMAT, nullptr,
     "The default thread format string to use "
     "when displaying thread information."},
    {"thread-stop-format", OptionValue::eTypeFormatEntity, true, 0,
     DEFAULT_THREAD_STOP_FORMAT, nullptr,
     "The default thread format  "
     "string to use when displaying thread "
     "information as part of the stop display."},
    {"use-external-editor", OptionValue::eTypeBoolean, true, false, nullptr,
     nullptr, "Whether to use an external editor or not."},
    {"use-color", OptionValue::eTypeBoolean, true, true, nullptr, nullptr,
     "Whether to use Ansi color codes or not."},
    {"auto-one-line-summaries", OptionValue::eTypeBoolean, true, true, nullptr,
     nullptr,
     "If true, LLDB will automatically display small structs in "
     "one-liner format (default: true)."},
    {"auto-indent", OptionValue::eTypeBoolean, true, true, nullptr, nullptr,
     "If true, LLDB will auto indent/outdent code. Currently only supported in "
     "the REPL (default: true)."},
    {"print-decls", OptionValue::eTypeBoolean, true, true, nullptr, nullptr,
     "If true, LLDB will print the values of variables declared in an "
     "expression. Currently only supported in the REPL (default: true)."},
    {"tab-size", OptionValue::eTypeUInt64, true, 4, nullptr, nullptr,
     "The tab size to use when indenting code in multi-line input mode "
     "(default: 4)."},
    {"escape-non-printables", OptionValue::eTypeBoolean, true, true, nullptr,
     nullptr,
     "If true, LLDB will automatically escape non-printable and "
     "escape characters when formatting strings."},
    {"frame-format-unique", OptionValue::eTypeFormatEntity, true, 0,
     DEFAULT_FRAME_FORMAT_NO_ARGS, nullptr,
     "The default frame format string to use when displaying stack frame"
     "information for threads from thread backtrace unique."},
    {nullptr, OptionValue::eTypeInvalid, true, 0, nullptr, nullptr, nullptr}};

enum {
  ePropertyAutoConfirm = 0,
  ePropertyDisassemblyFormat,
  ePropertyFrameFormat,
  ePropertyNotiftVoid,
  ePropertyPrompt,
  ePropertyScriptLanguage,
  ePropertyStopDisassemblyCount,
  ePropertyStopDisassemblyDisplay,
  ePropertyStopLineCountAfter,
  ePropertyStopLineCountBefore,
  ePropertyStopShowColumn,
  ePropertyStopShowColumnAnsiPrefix,
  ePropertyStopShowColumnAnsiSuffix,
  ePropertyTerminalWidth,
  ePropertyThreadFormat,
  ePropertyThreadStopFormat,
  ePropertyUseExternalEditor,
  ePropertyUseColor,
  ePropertyAutoOneLineSummaries,
  ePropertyAutoIndent,
  ePropertyPrintDecls,
  ePropertyTabSize,
  ePropertyEscapeNonPrintables,
  ePropertyFrameFormatUnique,
};

LoadPluginCallbackType Debugger::g_load_plugin_callback = nullptr;

Status Debugger::SetPropertyValue(const ExecutionContext *exe_ctx,
                                  VarSetOperationType op,
                                  llvm::StringRef property_path,
                                  llvm::StringRef value) {
  bool is_load_script = (property_path == "target.load-script-from-symbol-file");
  bool is_escape_non_printables = (property_path == "escape-non-printables");
  TargetSP target_sp;
  LoadScriptFromSymFile load_script_old_value;
  if (is_load_script && exe_ctx->GetTargetSP()) {
    target_sp = exe_ctx->GetTargetSP();
    load_script_old_value =
        target_sp->TargetProperties::GetLoadScriptFromSymbolFile();
  }
  Status error(Properties::SetPropertyValue(exe_ctx, op, property_path, value));
  if (error.Success()) {
    // FIXME it would be nice to have "on-change" callbacks for properties
    if (property_path == g_properties[ePropertyPrompt].name) {
      llvm::StringRef new_prompt = GetPrompt();
      std::string str = lldb_utility::ansi::FormatAnsiTerminalCodes(
          new_prompt, GetUseColor());
      if (str.length())
        new_prompt = str;
      GetCommandInterpreter().UpdatePrompt(new_prompt);
      auto bytes = llvm::make_unique<EventDataBytes>(new_prompt);
      auto prompt_change_event_sp = std::make_shared<Event>(
          CommandInterpreter::eBroadcastBitResetPrompt, bytes.release());
      GetCommandInterpreter().BroadcastEvent(prompt_change_event_sp);
    } else if (property_path == g_properties[ePropertyUseColor].name) {
      // use-color changed. Ping the prompt so it can reset the ansi terminal
      // codes.
      SetPrompt(GetPrompt());
    } else if (is_load_script && target_sp &&
               load_script_old_value == eLoadScriptFromSymFileWarn) {
      if (target_sp->TargetProperties::GetLoadScriptFromSymbolFile() ==
          eLoadScriptFromSymFileTrue) {
        std::list<Status> errors;
        StreamString feedback_stream;
        if (!target_sp->LoadScriptingResources(errors, &feedback_stream)) {
          StreamFileSP stream_sp(GetErrorFile());
          if (stream_sp) {
            for (auto error : errors) {
              stream_sp->Printf("%s\n", error.AsCString());
            }
            if (feedback_stream.GetSize())
              stream_sp->PutCString(feedback_stream.GetString());
          }
        }
      }
    } else if (is_escape_non_printables) {
      DataVisualization::ForceUpdate();
    }
  }
  return error;
}

bool Debugger::GetAutoConfirm() const {
  const uint32_t idx = ePropertyAutoConfirm;
  return m_collection_sp->GetPropertyAtIndexAsBoolean(
      nullptr, idx, g_properties[idx].default_uint_value != 0);
}

const FormatEntity::Entry *Debugger::GetDisassemblyFormat() const {
  const uint32_t idx = ePropertyDisassemblyFormat;
  return m_collection_sp->GetPropertyAtIndexAsFormatEntity(nullptr, idx);
}

const FormatEntity::Entry *Debugger::GetFrameFormat() const {
  const uint32_t idx = ePropertyFrameFormat;
  return m_collection_sp->GetPropertyAtIndexAsFormatEntity(nullptr, idx);
}

const FormatEntity::Entry *Debugger::GetFrameFormatUnique() const {
  const uint32_t idx = ePropertyFrameFormatUnique;
  return m_collection_sp->GetPropertyAtIndexAsFormatEntity(nullptr, idx);
}

bool Debugger::GetNotifyVoid() const {
  const uint32_t idx = ePropertyNotiftVoid;
  return m_collection_sp->GetPropertyAtIndexAsBoolean(
      nullptr, idx, g_properties[idx].default_uint_value != 0);
}

llvm::StringRef Debugger::GetPrompt() const {
  const uint32_t idx = ePropertyPrompt;
  return m_collection_sp->GetPropertyAtIndexAsString(
      nullptr, idx, g_properties[idx].default_cstr_value);
}

void Debugger::SetPrompt(llvm::StringRef p) {
  const uint32_t idx = ePropertyPrompt;
  m_collection_sp->SetPropertyAtIndexAsString(nullptr, idx, p);
  llvm::StringRef new_prompt = GetPrompt();
  std::string str =
      lldb_utility::ansi::FormatAnsiTerminalCodes(new_prompt, GetUseColor());
  if (str.length())
    new_prompt = str;
  GetCommandInterpreter().UpdatePrompt(new_prompt);
}

const FormatEntity::Entry *Debugger::GetThreadFormat() const {
  const uint32_t idx = ePropertyThreadFormat;
  return m_collection_sp->GetPropertyAtIndexAsFormatEntity(nullptr, idx);
}

const FormatEntity::Entry *Debugger::GetThreadStopFormat() const {
  const uint32_t idx = ePropertyThreadStopFormat;
  return m_collection_sp->GetPropertyAtIndexAsFormatEntity(nullptr, idx);
}

lldb::ScriptLanguage Debugger::GetScriptLanguage() const {
  const uint32_t idx = ePropertyScriptLanguage;
  return (lldb::ScriptLanguage)m_collection_sp->GetPropertyAtIndexAsEnumeration(
      nullptr, idx, g_properties[idx].default_uint_value);
}

bool Debugger::SetScriptLanguage(lldb::ScriptLanguage script_lang) {
  const uint32_t idx = ePropertyScriptLanguage;
  return m_collection_sp->SetPropertyAtIndexAsEnumeration(nullptr, idx,
                                                          script_lang);
}

uint32_t Debugger::GetTerminalWidth() const {
  const uint32_t idx = ePropertyTerminalWidth;
  return m_collection_sp->GetPropertyAtIndexAsSInt64(
      nullptr, idx, g_properties[idx].default_uint_value);
}

bool Debugger::SetTerminalWidth(uint32_t term_width) {
  const uint32_t idx = ePropertyTerminalWidth;
  return m_collection_sp->SetPropertyAtIndexAsSInt64(nullptr, idx, term_width);
}

bool Debugger::GetUseExternalEditor() const {
  const uint32_t idx = ePropertyUseExternalEditor;
  return m_collection_sp->GetPropertyAtIndexAsBoolean(
      nullptr, idx, g_properties[idx].default_uint_value != 0);
}

bool Debugger::SetUseExternalEditor(bool b) {
  const uint32_t idx = ePropertyUseExternalEditor;
  return m_collection_sp->SetPropertyAtIndexAsBoolean(nullptr, idx, b);
}

bool Debugger::GetUseColor() const {
  const uint32_t idx = ePropertyUseColor;
  return m_collection_sp->GetPropertyAtIndexAsBoolean(
      nullptr, idx, g_properties[idx].default_uint_value != 0);
}

bool Debugger::SetUseColor(bool b) {
  const uint32_t idx = ePropertyUseColor;
  bool ret = m_collection_sp->SetPropertyAtIndexAsBoolean(nullptr, idx, b);
  SetPrompt(GetPrompt());
  return ret;
}

StopShowColumn Debugger::GetStopShowColumn() const {
  const uint32_t idx = ePropertyStopShowColumn;
  return (lldb::StopShowColumn)m_collection_sp->GetPropertyAtIndexAsEnumeration(
      nullptr, idx, g_properties[idx].default_uint_value);
}

const FormatEntity::Entry *Debugger::GetStopShowColumnAnsiPrefix() const {
  const uint32_t idx = ePropertyStopShowColumnAnsiPrefix;
  return m_collection_sp->GetPropertyAtIndexAsFormatEntity(nullptr, idx);
}

const FormatEntity::Entry *Debugger::GetStopShowColumnAnsiSuffix() const {
  const uint32_t idx = ePropertyStopShowColumnAnsiSuffix;
  return m_collection_sp->GetPropertyAtIndexAsFormatEntity(nullptr, idx);
}

uint32_t Debugger::GetStopSourceLineCount(bool before) const {
  const uint32_t idx =
      before ? ePropertyStopLineCountBefore : ePropertyStopLineCountAfter;
  return m_collection_sp->GetPropertyAtIndexAsSInt64(
      nullptr, idx, g_properties[idx].default_uint_value);
}

Debugger::StopDisassemblyType Debugger::GetStopDisassemblyDisplay() const {
  const uint32_t idx = ePropertyStopDisassemblyDisplay;
  return (Debugger::StopDisassemblyType)
      m_collection_sp->GetPropertyAtIndexAsEnumeration(
          nullptr, idx, g_properties[idx].default_uint_value);
}

uint32_t Debugger::GetDisassemblyLineCount() const {
  const uint32_t idx = ePropertyStopDisassemblyCount;
  return m_collection_sp->GetPropertyAtIndexAsSInt64(
      nullptr, idx, g_properties[idx].default_uint_value);
}

bool Debugger::GetAutoOneLineSummaries() const {
  const uint32_t idx = ePropertyAutoOneLineSummaries;
  return m_collection_sp->GetPropertyAtIndexAsBoolean(nullptr, idx, true);
}

bool Debugger::GetEscapeNonPrintables() const {
  const uint32_t idx = ePropertyEscapeNonPrintables;
  return m_collection_sp->GetPropertyAtIndexAsBoolean(nullptr, idx, true);
}

bool Debugger::GetAutoIndent() const {
  const uint32_t idx = ePropertyAutoIndent;
  return m_collection_sp->GetPropertyAtIndexAsBoolean(nullptr, idx, true);
}

bool Debugger::SetAutoIndent(bool b) {
  const uint32_t idx = ePropertyAutoIndent;
  return m_collection_sp->SetPropertyAtIndexAsBoolean(nullptr, idx, b);
}

bool Debugger::GetPrintDecls() const {
  const uint32_t idx = ePropertyPrintDecls;
  return m_collection_sp->GetPropertyAtIndexAsBoolean(nullptr, idx, true);
}

bool Debugger::SetPrintDecls(bool b) {
  const uint32_t idx = ePropertyPrintDecls;
  return m_collection_sp->SetPropertyAtIndexAsBoolean(nullptr, idx, b);
}

uint32_t Debugger::GetTabSize() const {
  const uint32_t idx = ePropertyTabSize;
  return m_collection_sp->GetPropertyAtIndexAsUInt64(
      nullptr, idx, g_properties[idx].default_uint_value);
}

bool Debugger::SetTabSize(uint32_t tab_size) {
  const uint32_t idx = ePropertyTabSize;
  return m_collection_sp->SetPropertyAtIndexAsUInt64(nullptr, idx, tab_size);
}

#pragma mark Debugger

// const DebuggerPropertiesSP &
// Debugger::GetSettings() const
//{
//    return m_properties_sp;
//}
//

void Debugger::Initialize(LoadPluginCallbackType load_plugin_callback) {
  assert(g_debugger_list_ptr == nullptr &&
         "Debugger::Initialize called more than once!");
  g_debugger_list_mutex_ptr = new std::recursive_mutex();
  g_debugger_list_ptr = new DebuggerList();
  g_load_plugin_callback = load_plugin_callback;
}

void Debugger::Terminate() {
  assert(g_debugger_list_ptr &&
         "Debugger::Terminate called without a matching Debugger::Initialize!");

  if (g_debugger_list_ptr && g_debugger_list_mutex_ptr) {
    // Clear our master list of debugger objects
    {
      std::lock_guard<std::recursive_mutex> guard(*g_debugger_list_mutex_ptr);
      for (const auto &debugger : *g_debugger_list_ptr)
        debugger->Clear();
      g_debugger_list_ptr->clear();
    }
  }
}

void Debugger::SettingsInitialize() { Target::SettingsInitialize(); }

void Debugger::SettingsTerminate() { Target::SettingsTerminate(); }

bool Debugger::LoadPlugin(const FileSpec &spec, Status &error) {
  if (g_load_plugin_callback) {
    llvm::sys::DynamicLibrary dynlib =
        g_load_plugin_callback(shared_from_this(), spec, error);
    if (dynlib.isValid()) {
      m_loaded_plugins.push_back(dynlib);
      return true;
    }
  } else {
    // The g_load_plugin_callback is registered in SBDebugger::Initialize() and
    // if the public API layer isn't available (code is linking against all of
    // the internal LLDB static libraries), then we can't load plugins
    error.SetErrorString("Public API layer is not available");
  }
  return false;
}

static FileSpec::EnumerateDirectoryResult
LoadPluginCallback(void *baton, llvm::sys::fs::file_type ft,
                   const FileSpec &file_spec) {
  Status error;

  static ConstString g_dylibext(".dylib");
  static ConstString g_solibext(".so");

  if (!baton)
    return FileSpec::eEnumerateDirectoryResultQuit;

  Debugger *debugger = (Debugger *)baton;

  namespace fs = llvm::sys::fs;
  // If we have a regular file, a symbolic link or unknown file type, try and
  // process the file. We must handle unknown as sometimes the directory
  // enumeration might be enumerating a file system that doesn't have correct
  // file type information.
  if (ft == fs::file_type::regular_file || ft == fs::file_type::symlink_file ||
      ft == fs::file_type::type_unknown) {
    FileSpec plugin_file_spec(file_spec);
    plugin_file_spec.ResolvePath();

    if (plugin_file_spec.GetFileNameExtension() != g_dylibext &&
        plugin_file_spec.GetFileNameExtension() != g_solibext) {
      return FileSpec::eEnumerateDirectoryResultNext;
    }

    Status plugin_load_error;
    debugger->LoadPlugin(plugin_file_spec, plugin_load_error);

    return FileSpec::eEnumerateDirectoryResultNext;
  } else if (ft == fs::file_type::directory_file ||
             ft == fs::file_type::symlink_file ||
             ft == fs::file_type::type_unknown) {
    // Try and recurse into anything that a directory or symbolic link. We must
    // also do this for unknown as sometimes the directory enumeration might be
    // enumerating a file system that doesn't have correct file type
    // information.
    return FileSpec::eEnumerateDirectoryResultEnter;
  }

  return FileSpec::eEnumerateDirectoryResultNext;
}

void Debugger::InstanceInitialize() {
  const bool find_directories = true;
  const bool find_files = true;
  const bool find_other = true;
  char dir_path[PATH_MAX];
  if (FileSpec dir_spec = HostInfo::GetSystemPluginDir()) {
    if (dir_spec.Exists() && dir_spec.GetPath(dir_path, sizeof(dir_path))) {
      FileSpec::EnumerateDirectory(dir_path, find_directories, find_files,
                                   find_other, LoadPluginCallback, this);
    }
  }

  if (FileSpec dir_spec = HostInfo::GetUserPluginDir()) {
    if (dir_spec.Exists() && dir_spec.GetPath(dir_path, sizeof(dir_path))) {
      FileSpec::EnumerateDirectory(dir_path, find_directories, find_files,
                                   find_other, LoadPluginCallback, this);
    }
  }

  PluginManager::DebuggerInitialize(*this);
}

DebuggerSP Debugger::CreateInstance(lldb::LogOutputCallback log_callback,
                                    void *baton) {
  DebuggerSP debugger_sp(new Debugger(log_callback, baton));
  if (g_debugger_list_ptr && g_debugger_list_mutex_ptr) {
    std::lock_guard<std::recursive_mutex> guard(*g_debugger_list_mutex_ptr);
    g_debugger_list_ptr->push_back(debugger_sp);
  }
  debugger_sp->InstanceInitialize();
  return debugger_sp;
}

void Debugger::Destroy(DebuggerSP &debugger_sp) {
  if (!debugger_sp)
    return;

  debugger_sp->Clear();

  if (g_debugger_list_ptr && g_debugger_list_mutex_ptr) {
    std::lock_guard<std::recursive_mutex> guard(*g_debugger_list_mutex_ptr);
    DebuggerList::iterator pos, end = g_debugger_list_ptr->end();
    for (pos = g_debugger_list_ptr->begin(); pos != end; ++pos) {
      if ((*pos).get() == debugger_sp.get()) {
        g_debugger_list_ptr->erase(pos);
        return;
      }
    }
  }
}

DebuggerSP
Debugger::FindDebuggerWithInstanceName(const ConstString &instance_name) {
  DebuggerSP debugger_sp;
  if (g_debugger_list_ptr && g_debugger_list_mutex_ptr) {
    std::lock_guard<std::recursive_mutex> guard(*g_debugger_list_mutex_ptr);
    DebuggerList::iterator pos, end = g_debugger_list_ptr->end();
    for (pos = g_debugger_list_ptr->begin(); pos != end; ++pos) {
      if ((*pos)->m_instance_name == instance_name) {
        debugger_sp = *pos;
        break;
      }
    }
  }
  return debugger_sp;
}

TargetSP Debugger::FindTargetWithProcessID(lldb::pid_t pid) {
  TargetSP target_sp;
  if (g_debugger_list_ptr && g_debugger_list_mutex_ptr) {
    std::lock_guard<std::recursive_mutex> guard(*g_debugger_list_mutex_ptr);
    DebuggerList::iterator pos, end = g_debugger_list_ptr->end();
    for (pos = g_debugger_list_ptr->begin(); pos != end; ++pos) {
      target_sp = (*pos)->GetTargetList().FindTargetWithProcessID(pid);
      if (target_sp)
        break;
    }
  }
  return target_sp;
}

TargetSP Debugger::FindTargetWithProcess(Process *process) {
  TargetSP target_sp;
  if (g_debugger_list_ptr && g_debugger_list_mutex_ptr) {
    std::lock_guard<std::recursive_mutex> guard(*g_debugger_list_mutex_ptr);
    DebuggerList::iterator pos, end = g_debugger_list_ptr->end();
    for (pos = g_debugger_list_ptr->begin(); pos != end; ++pos) {
      target_sp = (*pos)->GetTargetList().FindTargetWithProcess(process);
      if (target_sp)
        break;
    }
  }
  return target_sp;
}

Debugger::Debugger(lldb::LogOutputCallback log_callback, void *baton)
    : UserID(g_unique_id++),
      Properties(std::make_shared<OptionValueProperties>()),
      m_input_file_sp(std::make_shared<StreamFile>(stdin, false)),
      m_output_file_sp(std::make_shared<StreamFile>(stdout, false)),
      m_error_file_sp(std::make_shared<StreamFile>(stderr, false)),
      m_broadcaster_manager_sp(BroadcasterManager::MakeBroadcasterManager()),
      m_terminal_state(), m_target_list(*this), m_platform_list(),
      m_listener_sp(Listener::MakeListener("lldb.Debugger")),
      m_source_manager_ap(), m_source_file_cache(),
      m_command_interpreter_ap(llvm::make_unique<CommandInterpreter>(
          *this, eScriptLanguageDefault, false)),
      m_input_reader_stack(), m_instance_name(), m_loaded_plugins(),
      m_event_handler_thread(), m_io_handler_thread(),
      m_sync_broadcaster(nullptr, "lldb.debugger.sync"),
      m_forward_listener_sp(), m_clear_once() {
  char instance_cstr[256];
  snprintf(instance_cstr, sizeof(instance_cstr), "debugger_%d", (int)GetID());
  m_instance_name.SetCString(instance_cstr);
  if (log_callback)
    m_log_callback_stream_sp =
        std::make_shared<StreamCallback>(log_callback, baton);
  m_command_interpreter_ap->Initialize();
  // Always add our default platform to the platform list
  PlatformSP default_platform_sp(Platform::GetHostPlatform());
  assert(default_platform_sp);
  m_platform_list.Append(default_platform_sp, true);

  m_collection_sp->Initialize(g_properties);
  m_collection_sp->AppendProperty(
      ConstString("target"),
      ConstString("Settings specify to debugging targets."), true,
      Target::GetGlobalProperties()->GetValueProperties());
  m_collection_sp->AppendProperty(
      ConstString("platform"), ConstString("Platform settings."), true,
      Platform::GetGlobalPlatformProperties()->GetValueProperties());
  m_collection_sp->AppendProperty(
      ConstString("symbols"), ConstString("Symbol lookup and cache settings."),
      true, ModuleList::GetGlobalModuleListProperties().GetValueProperties());
  if (m_command_interpreter_ap) {
    m_collection_sp->AppendProperty(
        ConstString("interpreter"),
        ConstString("Settings specify to the debugger's command interpreter."),
        true, m_command_interpreter_ap->GetValueProperties());
  }
  OptionValueSInt64 *term_width =
      m_collection_sp->GetPropertyAtIndexAsOptionValueSInt64(
          nullptr, ePropertyTerminalWidth);
  term_width->SetMinimumValue(10);
  term_width->SetMaximumValue(1024);

  // Turn off use-color if this is a dumb terminal.
  const char *term = getenv("TERM");
  if (term && !strcmp(term, "dumb"))
    SetUseColor(false);
}

Debugger::~Debugger() { Clear(); }

void Debugger::Clear() {
  //----------------------------------------------------------------------
  // Make sure we call this function only once. With the C++ global destructor
  // chain having a list of debuggers and with code that can be running on
  // other threads, we need to ensure this doesn't happen multiple times.
  //
  // The following functions call Debugger::Clear():
  //     Debugger::~Debugger();
  //     static void Debugger::Destroy(lldb::DebuggerSP &debugger_sp);
  //     static void Debugger::Terminate();
  //----------------------------------------------------------------------
  llvm::call_once(m_clear_once, [this]() {
    ClearIOHandlers();
    StopIOHandlerThread();
    StopEventHandlerThread();
    m_listener_sp->Clear();
    int num_targets = m_target_list.GetNumTargets();
    for (int i = 0; i < num_targets; i++) {
      TargetSP target_sp(m_target_list.GetTargetAtIndex(i));
      if (target_sp) {
        ProcessSP process_sp(target_sp->GetProcessSP());
        if (process_sp)
          process_sp->Finalize();
        target_sp->Destroy();
      }
    }
    m_broadcaster_manager_sp->Clear();

    // Close the input file _before_ we close the input read communications
    // class as it does NOT own the input file, our m_input_file does.
    m_terminal_state.Clear();
    if (m_input_file_sp)
      m_input_file_sp->GetFile().Close();

    m_command_interpreter_ap->Clear();
  });
}

bool Debugger::GetCloseInputOnEOF() const {
  //    return m_input_comm.GetCloseOnEOF();
  return false;
}

void Debugger::SetCloseInputOnEOF(bool b) {
  //    m_input_comm.SetCloseOnEOF(b);
}

bool Debugger::GetAsyncExecution() {
  return !m_command_interpreter_ap->GetSynchronous();
}

void Debugger::SetAsyncExecution(bool async_execution) {
  m_command_interpreter_ap->SetSynchronous(!async_execution);
}

void Debugger::SetInputFileHandle(FILE *fh, bool tranfer_ownership) {
  if (m_input_file_sp)
    m_input_file_sp->GetFile().SetStream(fh, tranfer_ownership);
  else
    m_input_file_sp = std::make_shared<StreamFile>(fh, tranfer_ownership);

  File &in_file = m_input_file_sp->GetFile();
  if (!in_file.IsValid())
    in_file.SetStream(stdin, true);

  // Save away the terminal state if that is relevant, so that we can restore
  // it in RestoreInputState.
  SaveInputTerminalState();
}

void Debugger::SetOutputFileHandle(FILE *fh, bool tranfer_ownership) {
  if (m_output_file_sp)
    m_output_file_sp->GetFile().SetStream(fh, tranfer_ownership);
  else
    m_output_file_sp = std::make_shared<StreamFile>(fh, tranfer_ownership);

  File &out_file = m_output_file_sp->GetFile();
  if (!out_file.IsValid())
    out_file.SetStream(stdout, false);

  // do not create the ScriptInterpreter just for setting the output file
  // handle as the constructor will know how to do the right thing on its own
  const bool can_create = false;
  ScriptInterpreter *script_interpreter =
      GetCommandInterpreter().GetScriptInterpreter(can_create);
  if (script_interpreter)
    script_interpreter->ResetOutputFileHandle(fh);
}

void Debugger::SetErrorFileHandle(FILE *fh, bool tranfer_ownership) {
  if (m_error_file_sp)
    m_error_file_sp->GetFile().SetStream(fh, tranfer_ownership);
  else
    m_error_file_sp = std::make_shared<StreamFile>(fh, tranfer_ownership);

  File &err_file = m_error_file_sp->GetFile();
  if (!err_file.IsValid())
    err_file.SetStream(stderr, false);
}

void Debugger::SaveInputTerminalState() {
  if (m_input_file_sp) {
    File &in_file = m_input_file_sp->GetFile();
    if (in_file.GetDescriptor() != File::kInvalidDescriptor)
      m_terminal_state.Save(in_file.GetDescriptor(), true);
  }
}

void Debugger::RestoreInputTerminalState() { m_terminal_state.Restore(); }

ExecutionContext Debugger::GetSelectedExecutionContext() {
  ExecutionContext exe_ctx;
  TargetSP target_sp(GetSelectedTarget());
  exe_ctx.SetTargetSP(target_sp);

  if (target_sp) {
    ProcessSP process_sp(target_sp->GetProcessSP());
    exe_ctx.SetProcessSP(process_sp);
    if (process_sp && !process_sp->IsRunning()) {
      ThreadSP thread_sp(process_sp->GetThreadList().GetSelectedThread());
      if (thread_sp) {
        exe_ctx.SetThreadSP(thread_sp);
        exe_ctx.SetFrameSP(thread_sp->GetSelectedFrame());
        if (exe_ctx.GetFramePtr() == nullptr)
          exe_ctx.SetFrameSP(thread_sp->GetStackFrameAtIndex(0));
      }
    }
  }
  return exe_ctx;
}

void Debugger::DispatchInputInterrupt() {
  std::lock_guard<std::recursive_mutex> guard(m_input_reader_stack.GetMutex());
  IOHandlerSP reader_sp(m_input_reader_stack.Top());
  if (reader_sp)
    reader_sp->Interrupt();
}

void Debugger::DispatchInputEndOfFile() {
  std::lock_guard<std::recursive_mutex> guard(m_input_reader_stack.GetMutex());
  IOHandlerSP reader_sp(m_input_reader_stack.Top());
  if (reader_sp)
    reader_sp->GotEOF();
}

void Debugger::ClearIOHandlers() {
  // The bottom input reader should be the main debugger input reader.  We do
  // not want to close that one here.
  std::lock_guard<std::recursive_mutex> guard(m_input_reader_stack.GetMutex());
  while (m_input_reader_stack.GetSize() > 1) {
    IOHandlerSP reader_sp(m_input_reader_stack.Top());
    if (reader_sp)
      PopIOHandler(reader_sp);
  }
}

void Debugger::ExecuteIOHandlers() {
  while (true) {
    IOHandlerSP reader_sp(m_input_reader_stack.Top());
    if (!reader_sp)
      break;

    reader_sp->Run();

    // Remove all input readers that are done from the top of the stack
    while (true) {
      IOHandlerSP top_reader_sp = m_input_reader_stack.Top();
      if (top_reader_sp && top_reader_sp->GetIsDone())
        PopIOHandler(top_reader_sp);
      else
        break;
    }
  }
  ClearIOHandlers();
}

bool Debugger::IsTopIOHandler(const lldb::IOHandlerSP &reader_sp) {
  return m_input_reader_stack.IsTop(reader_sp);
}

bool Debugger::CheckTopIOHandlerTypes(IOHandler::Type top_type,
                                      IOHandler::Type second_top_type) {
  return m_input_reader_stack.CheckTopIOHandlerTypes(top_type, second_top_type);
}

void Debugger::PrintAsync(const char *s, size_t len, bool is_stdout) {
  lldb::StreamFileSP stream = is_stdout ? GetOutputFile() : GetErrorFile();
  m_input_reader_stack.PrintAsync(stream.get(), s, len);
}

ConstString Debugger::GetTopIOHandlerControlSequence(char ch) {
  return m_input_reader_stack.GetTopIOHandlerControlSequence(ch);
}

const char *Debugger::GetIOHandlerCommandPrefix() {
  return m_input_reader_stack.GetTopIOHandlerCommandPrefix();
}

const char *Debugger::GetIOHandlerHelpPrologue() {
  return m_input_reader_stack.GetTopIOHandlerHelpPrologue();
}

void Debugger::RunIOHandler(const IOHandlerSP &reader_sp) {
  PushIOHandler(reader_sp);

  IOHandlerSP top_reader_sp = reader_sp;
  while (top_reader_sp) {
    top_reader_sp->Run();

    if (top_reader_sp.get() == reader_sp.get()) {
      if (PopIOHandler(reader_sp))
        break;
    }

    while (true) {
      top_reader_sp = m_input_reader_stack.Top();
      if (top_reader_sp && top_reader_sp->GetIsDone())
        PopIOHandler(top_reader_sp);
      else
        break;
    }
  }
}

void Debugger::AdoptTopIOHandlerFilesIfInvalid(StreamFileSP &in,
                                               StreamFileSP &out,
                                               StreamFileSP &err) {
  // Before an IOHandler runs, it must have in/out/err streams. This function
  // is called when one ore more of the streams are nullptr. We use the top
  // input reader's in/out/err streams, or fall back to the debugger file
  // handles, or we fall back onto stdin/stdout/stderr as a last resort.

  std::lock_guard<std::recursive_mutex> guard(m_input_reader_stack.GetMutex());
  IOHandlerSP top_reader_sp(m_input_reader_stack.Top());
  // If no STDIN has been set, then set it appropriately
  if (!in) {
    if (top_reader_sp)
      in = top_reader_sp->GetInputStreamFile();
    else
      in = GetInputFile();

    // If there is nothing, use stdin
    if (!in)
      in = std::make_shared<StreamFile>(stdin, false);
  }
  // If no STDOUT has been set, then set it appropriately
  if (!out) {
    if (top_reader_sp)
      out = top_reader_sp->GetOutputStreamFile();
    else
      out = GetOutputFile();

    // If there is nothing, use stdout
    if (!out)
      out = std::make_shared<StreamFile>(stdout, false);
  }
  // If no STDERR has been set, then set it appropriately
  if (!err) {
    if (top_reader_sp)
      err = top_reader_sp->GetErrorStreamFile();
    else
      err = GetErrorFile();

    // If there is nothing, use stderr
    if (!err)
      err = std::make_shared<StreamFile>(stdout, false);
  }
}

void Debugger::PushIOHandler(const IOHandlerSP &reader_sp) {
  if (!reader_sp)
    return;

  std::lock_guard<std::recursive_mutex> guard(m_input_reader_stack.GetMutex());

  // Get the current top input reader...
  IOHandlerSP top_reader_sp(m_input_reader_stack.Top());

  // Don't push the same IO handler twice...
  if (reader_sp == top_reader_sp)
    return;

  // Push our new input reader
  m_input_reader_stack.Push(reader_sp);
  reader_sp->Activate();

  // Interrupt the top input reader to it will exit its Run() function and let
  // this new input reader take over
  if (top_reader_sp) {
    top_reader_sp->Deactivate();
    top_reader_sp->Cancel();
  }
}

bool Debugger::PopIOHandler(const IOHandlerSP &pop_reader_sp) {
  if (!pop_reader_sp)
    return false;

  std::lock_guard<std::recursive_mutex> guard(m_input_reader_stack.GetMutex());

  // The reader on the stop of the stack is done, so let the next read on the
  // stack refresh its prompt and if there is one...
  if (m_input_reader_stack.IsEmpty())
    return false;

  IOHandlerSP reader_sp(m_input_reader_stack.Top());

  if (pop_reader_sp != reader_sp)
    return false;

  reader_sp->Deactivate();
  reader_sp->Cancel();
  m_input_reader_stack.Pop();

  reader_sp = m_input_reader_stack.Top();
  if (reader_sp)
    reader_sp->Activate();

  return true;
}

StreamSP Debugger::GetAsyncOutputStream() {
  return std::make_shared<StreamAsynchronousIO>(*this, true);
}

StreamSP Debugger::GetAsyncErrorStream() {
  return std::make_shared<StreamAsynchronousIO>(*this, false);
}

size_t Debugger::GetNumDebuggers() {
  if (g_debugger_list_ptr && g_debugger_list_mutex_ptr) {
    std::lock_guard<std::recursive_mutex> guard(*g_debugger_list_mutex_ptr);
    return g_debugger_list_ptr->size();
  }
  return 0;
}

lldb::DebuggerSP Debugger::GetDebuggerAtIndex(size_t index) {
  DebuggerSP debugger_sp;

  if (g_debugger_list_ptr && g_debugger_list_mutex_ptr) {
    std::lock_guard<std::recursive_mutex> guard(*g_debugger_list_mutex_ptr);
    if (index < g_debugger_list_ptr->size())
      debugger_sp = g_debugger_list_ptr->at(index);
  }

  return debugger_sp;
}

DebuggerSP Debugger::FindDebuggerWithID(lldb::user_id_t id) {
  DebuggerSP debugger_sp;

  if (g_debugger_list_ptr && g_debugger_list_mutex_ptr) {
    std::lock_guard<std::recursive_mutex> guard(*g_debugger_list_mutex_ptr);
    DebuggerList::iterator pos, end = g_debugger_list_ptr->end();
    for (pos = g_debugger_list_ptr->begin(); pos != end; ++pos) {
      if ((*pos)->GetID() == id) {
        debugger_sp = *pos;
        break;
      }
    }
  }
  return debugger_sp;
}

bool Debugger::FormatDisassemblerAddress(const FormatEntity::Entry *format,
                                         const SymbolContext *sc,
                                         const SymbolContext *prev_sc,
                                         const ExecutionContext *exe_ctx,
                                         const Address *addr, Stream &s) {
  FormatEntity::Entry format_entry;

  if (format == nullptr) {
    if (exe_ctx != nullptr && exe_ctx->HasTargetScope())
      format = exe_ctx->GetTargetRef().GetDebugger().GetDisassemblyFormat();
    if (format == nullptr) {
      FormatEntity::Parse("${addr}: ", format_entry);
      format = &format_entry;
    }
  }
  bool function_changed = false;
  bool initial_function = false;
  if (prev_sc && (prev_sc->function || prev_sc->symbol)) {
    if (sc && (sc->function || sc->symbol)) {
      if (prev_sc->symbol && sc->symbol) {
        if (!sc->symbol->Compare(prev_sc->symbol->GetName(),
                                 prev_sc->symbol->GetType())) {
          function_changed = true;
        }
      } else if (prev_sc->function && sc->function) {
        if (prev_sc->function->GetMangled() != sc->function->GetMangled()) {
          function_changed = true;
        }
      }
    }
  }
  // The first context on a list of instructions will have a prev_sc that has
  // no Function or Symbol -- if SymbolContext had an IsValid() method, it
  // would return false.  But we do get a prev_sc pointer.
  if ((sc && (sc->function || sc->symbol)) && prev_sc &&
      (prev_sc->function == nullptr && prev_sc->symbol == nullptr)) {
    initial_function = true;
  }
  return FormatEntity::Format(*format, s, sc, exe_ctx, addr, nullptr,
                              function_changed, initial_function);
}

void Debugger::SetLoggingCallback(lldb::LogOutputCallback log_callback,
                                  void *baton) {
  // For simplicity's sake, I am not going to deal with how to close down any
  // open logging streams, I just redirect everything from here on out to the
  // callback.
  m_log_callback_stream_sp =
      std::make_shared<StreamCallback>(log_callback, baton);
}

bool Debugger::EnableLog(llvm::StringRef channel,
                         llvm::ArrayRef<const char *> categories,
                         llvm::StringRef log_file, uint32_t log_options,
                         llvm::raw_ostream &error_stream) {
  const bool should_close = true;
  const bool unbuffered = true;

  std::shared_ptr<llvm::raw_ostream> log_stream_sp;
  if (m_log_callback_stream_sp) {
    log_stream_sp = m_log_callback_stream_sp;
    // For now when using the callback mode you always get thread & timestamp.
    log_options |=
        LLDB_LOG_OPTION_PREPEND_TIMESTAMP | LLDB_LOG_OPTION_PREPEND_THREAD_NAME;
  } else if (log_file.empty()) {
    log_stream_sp = std::make_shared<llvm::raw_fd_ostream>(
        GetOutputFile()->GetFile().GetDescriptor(), !should_close, unbuffered);
  } else {
    auto pos = m_log_streams.find(log_file);
    if (pos != m_log_streams.end())
      log_stream_sp = pos->second.lock();
    if (!log_stream_sp) {
      llvm::sys::fs::OpenFlags flags = llvm::sys::fs::F_Text;
      if (log_options & LLDB_LOG_OPTION_APPEND)
        flags |= llvm::sys::fs::F_Append;
      int FD;
      if (std::error_code ec = llvm::sys::fs::openFileForWrite(
              log_file, FD, llvm::sys::fs::CD_CreateAlways, flags)) {
        error_stream << "Unable to open log file: " << ec.message();
        return false;
      }
      log_stream_sp =
          std::make_shared<llvm::raw_fd_ostream>(FD, should_close, unbuffered);
      m_log_streams[log_file] = log_stream_sp;
    }
  }
  assert(log_stream_sp);

  if (log_options == 0)
    log_options =
        LLDB_LOG_OPTION_PREPEND_THREAD_NAME | LLDB_LOG_OPTION_THREADSAFE;

  return Log::EnableLogChannel(log_stream_sp, log_options, channel, categories,
                               error_stream);
}

SourceManager &Debugger::GetSourceManager() {
  if (!m_source_manager_ap)
    m_source_manager_ap = llvm::make_unique<SourceManager>(shared_from_this());
  return *m_source_manager_ap;
}

// This function handles events that were broadcast by the process.
void Debugger::HandleBreakpointEvent(const EventSP &event_sp) {
  using namespace lldb;
  const uint32_t event_type =
      Breakpoint::BreakpointEventData::GetBreakpointEventTypeFromEvent(
          event_sp);

  //    if (event_type & eBreakpointEventTypeAdded
  //        || event_type & eBreakpointEventTypeRemoved
  //        || event_type & eBreakpointEventTypeEnabled
  //        || event_type & eBreakpointEventTypeDisabled
  //        || event_type & eBreakpointEventTypeCommandChanged
  //        || event_type & eBreakpointEventTypeConditionChanged
  //        || event_type & eBreakpointEventTypeIgnoreChanged
  //        || event_type & eBreakpointEventTypeLocationsResolved)
  //    {
  //        // Don't do anything about these events, since the breakpoint
  //        commands already echo these actions.
  //    }
  //
  if (event_type & eBreakpointEventTypeLocationsAdded) {
    uint32_t num_new_locations =
        Breakpoint::BreakpointEventData::GetNumBreakpointLocationsFromEvent(
            event_sp);
    if (num_new_locations > 0) {
      BreakpointSP breakpoint =
          Breakpoint::BreakpointEventData::GetBreakpointFromEvent(event_sp);
      StreamSP output_sp(GetAsyncOutputStream());
      if (output_sp) {
        output_sp->Printf("%d location%s added to breakpoint %d\n",
                          num_new_locations, num_new_locations == 1 ? "" : "s",
                          breakpoint->GetID());
        output_sp->Flush();
      }
    }
  }
  //    else if (event_type & eBreakpointEventTypeLocationsRemoved)
  //    {
  //        // These locations just get disabled, not sure it is worth spamming
  //        folks about this on the command line.
  //    }
  //    else if (event_type & eBreakpointEventTypeLocationsResolved)
  //    {
  //        // This might be an interesting thing to note, but I'm going to
  //        leave it quiet for now, it just looked noisy.
  //    }
}

size_t Debugger::GetProcessSTDOUT(Process *process, Stream *stream) {
  size_t total_bytes = 0;
  if (stream == nullptr)
    stream = GetOutputFile().get();

  if (stream) {
    //  The process has stuff waiting for stdout; get it and write it out to the
    //  appropriate place.
    if (process == nullptr) {
      TargetSP target_sp = GetTargetList().GetSelectedTarget();
      if (target_sp)
        process = target_sp->GetProcessSP().get();
    }
    if (process) {
      Status error;
      size_t len;
      char stdio_buffer[1024];
      while ((len = process->GetSTDOUT(stdio_buffer, sizeof(stdio_buffer),
                                       error)) > 0) {
        stream->Write(stdio_buffer, len);
        total_bytes += len;
      }
    }
    stream->Flush();
  }
  return total_bytes;
}

size_t Debugger::GetProcessSTDERR(Process *process, Stream *stream) {
  size_t total_bytes = 0;
  if (stream == nullptr)
    stream = GetOutputFile().get();

  if (stream) {
    //  The process has stuff waiting for stderr; get it and write it out to the
    //  appropriate place.
    if (process == nullptr) {
      TargetSP target_sp = GetTargetList().GetSelectedTarget();
      if (target_sp)
        process = target_sp->GetProcessSP().get();
    }
    if (process) {
      Status error;
      size_t len;
      char stdio_buffer[1024];
      while ((len = process->GetSTDERR(stdio_buffer, sizeof(stdio_buffer),
                                       error)) > 0) {
        stream->Write(stdio_buffer, len);
        total_bytes += len;
      }
    }
    stream->Flush();
  }
  return total_bytes;
}

// This function handles events that were broadcast by the process.
void Debugger::HandleProcessEvent(const EventSP &event_sp) {
  using namespace lldb;
  const uint32_t event_type = event_sp->GetType();
  ProcessSP process_sp =
      (event_type == Process::eBroadcastBitStructuredData)
          ? EventDataStructuredData::GetProcessFromEvent(event_sp.get())
          : Process::ProcessEventData::GetProcessFromEvent(event_sp.get());

  StreamSP output_stream_sp = GetAsyncOutputStream();
  StreamSP error_stream_sp = GetAsyncErrorStream();
  const bool gui_enabled = IsForwardingEvents();

  if (!gui_enabled) {
    bool pop_process_io_handler = false;
    assert(process_sp);

    bool state_is_stopped = false;
    const bool got_state_changed =
        (event_type & Process::eBroadcastBitStateChanged) != 0;
    const bool got_stdout = (event_type & Process::eBroadcastBitSTDOUT) != 0;
    const bool got_stderr = (event_type & Process::eBroadcastBitSTDERR) != 0;
    const bool got_structured_data =
        (event_type & Process::eBroadcastBitStructuredData) != 0;

    if (got_state_changed) {
      StateType event_state =
          Process::ProcessEventData::GetStateFromEvent(event_sp.get());
      state_is_stopped = StateIsStoppedState(event_state, false);
    }

    // Display running state changes first before any STDIO
    if (got_state_changed && !state_is_stopped) {
      Process::HandleProcessStateChangedEvent(event_sp, output_stream_sp.get(),
                                              pop_process_io_handler);
    }

    // Now display and STDOUT
    if (got_stdout || got_state_changed) {
      GetProcessSTDOUT(process_sp.get(), output_stream_sp.get());
    }

    // Now display and STDERR
    if (got_stderr || got_state_changed) {
      GetProcessSTDERR(process_sp.get(), error_stream_sp.get());
    }

    // Give structured data events an opportunity to display.
    if (got_structured_data) {
      StructuredDataPluginSP plugin_sp =
          EventDataStructuredData::GetPluginFromEvent(event_sp.get());
      if (plugin_sp) {
        auto structured_data_sp =
            EventDataStructuredData::GetObjectFromEvent(event_sp.get());
        if (output_stream_sp) {
          StreamString content_stream;
          Status error =
              plugin_sp->GetDescription(structured_data_sp, content_stream);
          if (error.Success()) {
            if (!content_stream.GetString().empty()) {
              // Add newline.
              content_stream.PutChar('\n');
              content_stream.Flush();

              // Print it.
              output_stream_sp->PutCString(content_stream.GetString());
            }
          } else {
            error_stream_sp->Printf("Failed to print structured "
                                    "data with plugin %s: %s",
                                    plugin_sp->GetPluginName().AsCString(),
                                    error.AsCString());
          }
        }
      }
    }

    // Now display any stopped state changes after any STDIO
    if (got_state_changed && state_is_stopped) {
      Process::HandleProcessStateChangedEvent(event_sp, output_stream_sp.get(),
                                              pop_process_io_handler);
    }

    output_stream_sp->Flush();
    error_stream_sp->Flush();

    if (pop_process_io_handler)
      process_sp->PopProcessIOHandler();
  }
}

void Debugger::HandleThreadEvent(const EventSP &event_sp) {
  // At present the only thread event we handle is the Frame Changed event, and
  // all we do for that is just reprint the thread status for that thread.
  using namespace lldb;
  const uint32_t event_type = event_sp->GetType();
  const bool stop_format = true;
  if (event_type == Thread::eBroadcastBitStackChanged ||
      event_type == Thread::eBroadcastBitThreadSelected) {
    ThreadSP thread_sp(
        Thread::ThreadEventData::GetThreadFromEvent(event_sp.get()));
    if (thread_sp) {
      thread_sp->GetStatus(*GetAsyncOutputStream(), 0, 1, 1, stop_format);
    }
  }
}

bool Debugger::IsForwardingEvents() { return (bool)m_forward_listener_sp; }

void Debugger::EnableForwardEvents(const ListenerSP &listener_sp) {
  m_forward_listener_sp = listener_sp;
}

void Debugger::CancelForwardEvents(const ListenerSP &listener_sp) {
  m_forward_listener_sp.reset();
}

void Debugger::DefaultEventHandler() {
  ListenerSP listener_sp(GetListener());
  ConstString broadcaster_class_target(Target::GetStaticBroadcasterClass());
  ConstString broadcaster_class_process(Process::GetStaticBroadcasterClass());
  ConstString broadcaster_class_thread(Thread::GetStaticBroadcasterClass());
  BroadcastEventSpec target_event_spec(broadcaster_class_target,
                                       Target::eBroadcastBitBreakpointChanged);

  BroadcastEventSpec process_event_spec(
      broadcaster_class_process,
      Process::eBroadcastBitStateChanged | Process::eBroadcastBitSTDOUT |
          Process::eBroadcastBitSTDERR | Process::eBroadcastBitStructuredData);

  BroadcastEventSpec thread_event_spec(broadcaster_class_thread,
                                       Thread::eBroadcastBitStackChanged |
                                           Thread::eBroadcastBitThreadSelected);

  listener_sp->StartListeningForEventSpec(m_broadcaster_manager_sp,
                                          target_event_spec);
  listener_sp->StartListeningForEventSpec(m_broadcaster_manager_sp,
                                          process_event_spec);
  listener_sp->StartListeningForEventSpec(m_broadcaster_manager_sp,
                                          thread_event_spec);
  listener_sp->StartListeningForEvents(
      m_command_interpreter_ap.get(),
      CommandInterpreter::eBroadcastBitQuitCommandReceived |
          CommandInterpreter::eBroadcastBitAsynchronousOutputData |
          CommandInterpreter::eBroadcastBitAsynchronousErrorData);

  // Let the thread that spawned us know that we have started up and that we
  // are now listening to all required events so no events get missed
  m_sync_broadcaster.BroadcastEvent(eBroadcastBitEventThreadIsListening);

  bool done = false;
  while (!done) {
    EventSP event_sp;
    if (listener_sp->GetEvent(event_sp, llvm::None)) {
      if (event_sp) {
        Broadcaster *broadcaster = event_sp->GetBroadcaster();
        if (broadcaster) {
          uint32_t event_type = event_sp->GetType();
          ConstString broadcaster_class(broadcaster->GetBroadcasterClass());
          if (broadcaster_class == broadcaster_class_process) {
            HandleProcessEvent(event_sp);
          } else if (broadcaster_class == broadcaster_class_target) {
            if (Breakpoint::BreakpointEventData::GetEventDataFromEvent(
                    event_sp.get())) {
              HandleBreakpointEvent(event_sp);
            }
          } else if (broadcaster_class == broadcaster_class_thread) {
            HandleThreadEvent(event_sp);
          } else if (broadcaster == m_command_interpreter_ap.get()) {
            if (event_type &
                CommandInterpreter::eBroadcastBitQuitCommandReceived) {
              done = true;
            } else if (event_type &
                       CommandInterpreter::eBroadcastBitAsynchronousErrorData) {
              const char *data = reinterpret_cast<const char *>(
                  EventDataBytes::GetBytesFromEvent(event_sp.get()));
              if (data && data[0]) {
                StreamSP error_sp(GetAsyncErrorStream());
                if (error_sp) {
                  error_sp->PutCString(data);
                  error_sp->Flush();
                }
              }
            } else if (event_type & CommandInterpreter::
                                        eBroadcastBitAsynchronousOutputData) {
              const char *data = reinterpret_cast<const char *>(
                  EventDataBytes::GetBytesFromEvent(event_sp.get()));
              if (data && data[0]) {
                StreamSP output_sp(GetAsyncOutputStream());
                if (output_sp) {
                  output_sp->PutCString(data);
                  output_sp->Flush();
                }
              }
            }
          }
        }

        if (m_forward_listener_sp)
          m_forward_listener_sp->AddEvent(event_sp);
      }
    }
  }
}

lldb::thread_result_t Debugger::EventHandlerThread(lldb::thread_arg_t arg) {
  ((Debugger *)arg)->DefaultEventHandler();
  return NULL;
}

bool Debugger::StartEventHandlerThread() {
  if (!m_event_handler_thread.IsJoinable()) {
    // We must synchronize with the DefaultEventHandler() thread to ensure it
    // is up and running and listening to events before we return from this
    // function. We do this by listening to events for the
    // eBroadcastBitEventThreadIsListening from the m_sync_broadcaster
    ConstString full_name("lldb.debugger.event-handler");
    ListenerSP listener_sp(Listener::MakeListener(full_name.AsCString()));
    listener_sp->StartListeningForEvents(&m_sync_broadcaster,
                                         eBroadcastBitEventThreadIsListening);

    auto thread_name =
        full_name.GetLength() < llvm::get_max_thread_name_length() ?
        full_name.AsCString() : "dbg.evt-handler";

    // Use larger 8MB stack for this thread
    m_event_handler_thread = ThreadLauncher::LaunchThread(thread_name,
        EventHandlerThread, this, nullptr, g_debugger_event_thread_stack_bytes);

    // Make sure DefaultEventHandler() is running and listening to events
    // before we return from this function. We are only listening for events of
    // type eBroadcastBitEventThreadIsListening so we don't need to check the
    // event, we just need to wait an infinite amount of time for it (nullptr
    // timeout as the first parameter)
    lldb::EventSP event_sp;
    listener_sp->GetEvent(event_sp, llvm::None);
  }
  return m_event_handler_thread.IsJoinable();
}

void Debugger::StopEventHandlerThread() {
  if (m_event_handler_thread.IsJoinable()) {
    GetCommandInterpreter().BroadcastEvent(
        CommandInterpreter::eBroadcastBitQuitCommandReceived);
    m_event_handler_thread.Join(nullptr);
  }
}

lldb::thread_result_t Debugger::IOHandlerThread(lldb::thread_arg_t arg) {
  Debugger *debugger = (Debugger *)arg;
  debugger->ExecuteIOHandlers();
  debugger->StopEventHandlerThread();
  return NULL;
}

bool Debugger::HasIOHandlerThread() { return m_io_handler_thread.IsJoinable(); }

bool Debugger::StartIOHandlerThread() {
  if (!m_io_handler_thread.IsJoinable())
    m_io_handler_thread = ThreadLauncher::LaunchThread(
        "lldb.debugger.io-handler", IOHandlerThread, this, nullptr,
        8 * 1024 * 1024); // Use larger 8MB stack for this thread
  return m_io_handler_thread.IsJoinable();
}

void Debugger::StopIOHandlerThread() {
  if (m_io_handler_thread.IsJoinable()) {
    if (m_input_file_sp)
      m_input_file_sp->GetFile().Close();
    m_io_handler_thread.Join(nullptr);
  }
}

void Debugger::JoinIOHandlerThread() {
  if (HasIOHandlerThread()) {
    thread_result_t result;
    m_io_handler_thread.Join(&result);
    m_io_handler_thread = LLDB_INVALID_HOST_THREAD;
  }
}

Target *Debugger::GetDummyTarget() {
  return m_target_list.GetDummyTarget(*this).get();
}

Target *Debugger::GetSelectedOrDummyTarget(bool prefer_dummy) {
  Target *target = nullptr;
  if (!prefer_dummy) {
    target = m_target_list.GetSelectedTarget().get();
    if (target)
      return target;
  }

  return GetDummyTarget();
}

Status Debugger::RunREPL(LanguageType language, const char *repl_options) {
  Status err;
  FileSpec repl_executable;

  if (language == eLanguageTypeUnknown) {
    std::set<LanguageType> repl_languages;

    Language::GetLanguagesSupportingREPLs(repl_languages);

    if (repl_languages.size() == 1) {
      language = *repl_languages.begin();
    } else if (repl_languages.empty()) {
      err.SetErrorStringWithFormat(
          "LLDB isn't configured with REPL support for any languages.");
      return err;
    } else {
      err.SetErrorStringWithFormat(
          "Multiple possible REPL languages.  Please specify a language.");
      return err;
    }
  }

  Target *const target =
      nullptr; // passing in an empty target means the REPL must create one

  REPLSP repl_sp(REPL::Create(err, language, this, target, repl_options));

  if (!err.Success()) {
    return err;
  }

  if (!repl_sp) {
    err.SetErrorStringWithFormat("couldn't find a REPL for %s",
                                 Language::GetNameForLanguageType(language));
    return err;
  }

  repl_sp->SetCompilerOptions(repl_options);
  repl_sp->RunLoop();

  return err;
}
