//===-- InstrumentationRuntimeTSan.cpp ------------------------------------===//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//

#include "InstrumentationRuntimeTSan.h"

#include "Plugins/Process/Utility/HistoryThread.h"
#include "lldb/Breakpoint/StoppointCallbackContext.h"
#include "lldb/Core/Debugger.h"
#include "lldb/Core/Module.h"
#include "lldb/Core/PluginInterface.h"
#include "lldb/Core/PluginManager.h"
#include "lldb/Core/StreamFile.h"
#include "lldb/Core/ValueObject.h"
#include "lldb/Expression/UserExpression.h"
#include "lldb/Interpreter/CommandReturnObject.h"
#include "lldb/Symbol/Symbol.h"
#include "lldb/Symbol/SymbolContext.h"
#include "lldb/Symbol/Variable.h"
#include "lldb/Symbol/VariableList.h"
#include "lldb/Target/InstrumentationRuntimeStopInfo.h"
#include "lldb/Target/SectionLoadList.h"
#include "lldb/Target/StopInfo.h"
#include "lldb/Target/Target.h"
#include "lldb/Target/Thread.h"
#include "lldb/Utility/RegularExpression.h"
#include "lldb/Utility/Stream.h"

#include <memory>

using namespace lldb;
using namespace lldb_private;

LLDB_PLUGIN_DEFINE(InstrumentationRuntimeTSan)

lldb::InstrumentationRuntimeSP
InstrumentationRuntimeTSan::CreateInstance(const lldb::ProcessSP &process_sp) {
  return InstrumentationRuntimeSP(new InstrumentationRuntimeTSan(process_sp));
}

void InstrumentationRuntimeTSan::Initialize() {
  PluginManager::RegisterPlugin(
      GetPluginNameStatic(), "ThreadSanitizer instrumentation runtime plugin.",
      CreateInstance, GetTypeStatic);
}

void InstrumentationRuntimeTSan::Terminate() {
  PluginManager::UnregisterPlugin(CreateInstance);
}

lldb::InstrumentationRuntimeType InstrumentationRuntimeTSan::GetTypeStatic() {
  return eInstrumentationRuntimeTypeThreadSanitizer;
}

InstrumentationRuntimeTSan::~InstrumentationRuntimeTSan() { Deactivate(); }

const char *thread_sanitizer_retrieve_report_data_prefix = R"(
extern "C"
{
    void *__tsan_get_current_report();
    int __tsan_get_report_data(void *report, const char **description, int *count,
                               int *stack_count, int *mop_count, int *loc_count,
                               int *mutex_count, int *thread_count,
                               int *unique_tid_count, void **sleep_trace,
                               unsigned long trace_size);
    int __tsan_get_report_stack(void *report, unsigned long idx, void **trace,
                                unsigned long trace_size);
    int __tsan_get_report_mop(void *report, unsigned long idx, int *tid, void **addr,
                              int *size, int *write, int *atomic, void **trace,
                              unsigned long trace_size);
    int __tsan_get_report_loc(void *report, unsigned long idx, const char **type,
                              void **addr, unsigned long *start, unsigned long *size, int *tid,
                              int *fd, int *suppressable, void **trace,
                              unsigned long trace_size);
    int __tsan_get_report_mutex(void *report, unsigned long idx, unsigned long *mutex_id, void **addr,
                                int *destroyed, void **trace, unsigned long trace_size);
    int __tsan_get_report_thread(void *report, unsigned long idx, int *tid, unsigned long *os_id,
                                 int *running, const char **name, int *parent_tid,
                                 void **trace, unsigned long trace_size);
    int __tsan_get_report_unique_tid(void *report, unsigned long idx, int *tid);

    // TODO: dlsym won't work on Windows.
    void *dlsym(void* handle, const char* symbol);
    int (*ptr__tsan_get_report_loc_object_type)(void *report, unsigned long idx, const char **object_type);
}

const int REPORT_TRACE_SIZE = 128;
const int REPORT_ARRAY_SIZE = 4;

struct data {
    void *report;
    const char *description;
    int report_count;

    void *sleep_trace[REPORT_TRACE_SIZE];

    int stack_count;
    struct {
        int idx;
        void *trace[REPORT_TRACE_SIZE];
    } stacks[REPORT_ARRAY_SIZE];

    int mop_count;
    struct {
        int idx;
        int tid;
        int size;
        int write;
        int atomic;
        void *addr;
        void *trace[REPORT_TRACE_SIZE];
    } mops[REPORT_ARRAY_SIZE];

    int loc_count;
    struct {
        int idx;
        const char *type;
        void *addr;
        unsigned long start;
        unsigned long size;
        int tid;
        int fd;
        int suppressable;
        void *trace[REPORT_TRACE_SIZE];
        const char *object_type;
    } locs[REPORT_ARRAY_SIZE];

    int mutex_count;
    struct {
        int idx;
        unsigned long mutex_id;
        void *addr;
        int destroyed;
        void *trace[REPORT_TRACE_SIZE];
    } mutexes[REPORT_ARRAY_SIZE];

    int thread_count;
    struct {
        int idx;
        int tid;
        unsigned long os_id;
        int running;
        const char *name;
        int parent_tid;
        void *trace[REPORT_TRACE_SIZE];
    } threads[REPORT_ARRAY_SIZE];

    int unique_tid_count;
    struct {
        int idx;
        int tid;
    } unique_tids[REPORT_ARRAY_SIZE];
};
)";

const char *thread_sanitizer_retrieve_report_data_command = R"(
data t = {0};

ptr__tsan_get_report_loc_object_type = (typeof(ptr__tsan_get_report_loc_object_type))(void *)dlsym((void*)-2 /*RTLD_DEFAULT*/, "__tsan_get_report_loc_object_type");

t.report = __tsan_get_current_report();
__tsan_get_report_data(t.report, &t.description, &t.report_count, &t.stack_count, &t.mop_count, &t.loc_count, &t.mutex_count, &t.thread_count, &t.unique_tid_count, t.sleep_trace, REPORT_TRACE_SIZE);

if (t.stack_count > REPORT_ARRAY_SIZE) t.stack_count = REPORT_ARRAY_SIZE;
for (int i = 0; i < t.stack_count; i++) {
    t.stacks[i].idx = i;
    __tsan_get_report_stack(t.report, i, t.stacks[i].trace, REPORT_TRACE_SIZE);
}

if (t.mop_count > REPORT_ARRAY_SIZE) t.mop_count = REPORT_ARRAY_SIZE;
for (int i = 0; i < t.mop_count; i++) {
    t.mops[i].idx = i;
    __tsan_get_report_mop(t.report, i, &t.mops[i].tid, &t.mops[i].addr, &t.mops[i].size, &t.mops[i].write, &t.mops[i].atomic, t.mops[i].trace, REPORT_TRACE_SIZE);
}

if (t.loc_count > REPORT_ARRAY_SIZE) t.loc_count = REPORT_ARRAY_SIZE;
for (int i = 0; i < t.loc_count; i++) {
    t.locs[i].idx = i;
    __tsan_get_report_loc(t.report, i, &t.locs[i].type, &t.locs[i].addr, &t.locs[i].start, &t.locs[i].size, &t.locs[i].tid, &t.locs[i].fd, &t.locs[i].suppressable, t.locs[i].trace, REPORT_TRACE_SIZE);
    if (ptr__tsan_get_report_loc_object_type)
        ptr__tsan_get_report_loc_object_type(t.report, i, &t.locs[i].object_type);
}

if (t.mutex_count > REPORT_ARRAY_SIZE) t.mutex_count = REPORT_ARRAY_SIZE;
for (int i = 0; i < t.mutex_count; i++) {
    t.mutexes[i].idx = i;
    __tsan_get_report_mutex(t.report, i, &t.mutexes[i].mutex_id, &t.mutexes[i].addr, &t.mutexes[i].destroyed, t.mutexes[i].trace, REPORT_TRACE_SIZE);
}

if (t.thread_count > REPORT_ARRAY_SIZE) t.thread_count = REPORT_ARRAY_SIZE;
for (int i = 0; i < t.thread_count; i++) {
    t.threads[i].idx = i;
    __tsan_get_report_thread(t.report, i, &t.threads[i].tid, &t.threads[i].os_id, &t.threads[i].running, &t.threads[i].name, &t.threads[i].parent_tid, t.threads[i].trace, REPORT_TRACE_SIZE);
}

if (t.unique_tid_count > REPORT_ARRAY_SIZE) t.unique_tid_count = REPORT_ARRAY_SIZE;
for (int i = 0; i < t.unique_tid_count; i++) {
    t.unique_tids[i].idx = i;
    __tsan_get_report_unique_tid(t.report, i, &t.unique_tids[i].tid);
}

t;
)";

static StructuredData::Array *
CreateStackTrace(ValueObjectSP o,
                 const std::string &trace_item_name = ".trace") {
  StructuredData::Array *trace = new StructuredData::Array();
  ValueObjectSP trace_value_object =
      o->GetValueForExpressionPath(trace_item_name.c_str());
  size_t count = trace_value_object->GetNumChildren();
  for (size_t j = 0; j < count; j++) {
    addr_t trace_addr =
        trace_value_object->GetChildAtIndex(j, true)->GetValueAsUnsigned(0);
    if (trace_addr == 0)
      break;
    trace->AddItem(
        StructuredData::ObjectSP(new StructuredData::Integer(trace_addr)));
  }
  return trace;
}

static StructuredData::Array *ConvertToStructuredArray(
    ValueObjectSP return_value_sp, const std::string &items_name,
    const std::string &count_name,
    std::function<void(ValueObjectSP o, StructuredData::Dictionary *dict)> const
        &callback) {
  StructuredData::Array *array = new StructuredData::Array();
  unsigned int count =
      return_value_sp->GetValueForExpressionPath(count_name.c_str())
          ->GetValueAsUnsigned(0);
  ValueObjectSP objects =
      return_value_sp->GetValueForExpressionPath(items_name.c_str());
  for (unsigned int i = 0; i < count; i++) {
    ValueObjectSP o = objects->GetChildAtIndex(i, true);
    StructuredData::Dictionary *dict = new StructuredData::Dictionary();

    callback(o, dict);

    array->AddItem(StructuredData::ObjectSP(dict));
  }
  return array;
}

static std::string RetrieveString(ValueObjectSP return_value_sp,
                                  ProcessSP process_sp,
                                  const std::string &expression_path) {
  addr_t ptr =
      return_value_sp->GetValueForExpressionPath(expression_path.c_str())
          ->GetValueAsUnsigned(0);
  std::string str;
  Status error;
  process_sp->ReadCStringFromMemory(ptr, str, error);
  return str;
}

static void
GetRenumberedThreadIds(ProcessSP process_sp, ValueObjectSP data,
                       std::map<uint64_t, user_id_t> &thread_id_map) {
  ConvertToStructuredArray(
      data, ".threads", ".thread_count",
      [process_sp, &thread_id_map](ValueObjectSP o,
                                   StructuredData::Dictionary *dict) {
        uint64_t thread_id =
            o->GetValueForExpressionPath(".tid")->GetValueAsUnsigned(0);
        uint64_t thread_os_id =
            o->GetValueForExpressionPath(".os_id")->GetValueAsUnsigned(0);
        user_id_t lldb_user_id = 0;

        bool can_update = true;
        ThreadSP lldb_thread = process_sp->GetThreadList().FindThreadByID(
            thread_os_id, can_update);
        if (lldb_thread) {
          lldb_user_id = lldb_thread->GetIndexID();
        } else {
          // This isn't a live thread anymore.  Ask process to assign a new
          // Index ID (or return an old one if we've already seen this
          // thread_os_id). It will also make sure that no new threads are
          // assigned this Index ID.
          lldb_user_id = process_sp->AssignIndexIDToThread(thread_os_id);
        }

        thread_id_map[thread_id] = lldb_user_id;
      });
}

static user_id_t Renumber(uint64_t id,
                          std::map<uint64_t, user_id_t> &thread_id_map) {
  auto IT = thread_id_map.find(id);
  if (IT == thread_id_map.end())
    return 0;

  return IT->second;
}

StructuredData::ObjectSP InstrumentationRuntimeTSan::RetrieveReportData(
    ExecutionContextRef exe_ctx_ref) {
  ProcessSP process_sp = GetProcessSP();
  if (!process_sp)
    return StructuredData::ObjectSP();

  ThreadSP thread_sp = exe_ctx_ref.GetThreadSP();
  StackFrameSP frame_sp = thread_sp->GetSelectedFrame();

  if (!frame_sp)
    return StructuredData::ObjectSP();

  EvaluateExpressionOptions options;
  options.SetUnwindOnError(true);
  options.SetTryAllThreads(true);
  options.SetStopOthers(true);
  options.SetIgnoreBreakpoints(true);
  options.SetTimeout(process_sp->GetUtilityExpressionTimeout());
  options.SetPrefix(thread_sanitizer_retrieve_report_data_prefix);
  options.SetAutoApplyFixIts(false);
  options.SetLanguage(eLanguageTypeObjC_plus_plus);

  ValueObjectSP main_value;
  ExecutionContext exe_ctx;
  Status eval_error;
  frame_sp->CalculateExecutionContext(exe_ctx);
  ExpressionResults result = UserExpression::Evaluate(
      exe_ctx, options, thread_sanitizer_retrieve_report_data_command, "",
      main_value, eval_error);
  if (result != eExpressionCompleted) {
    process_sp->GetTarget().GetDebugger().GetAsyncOutputStream()->Printf(
        "Warning: Cannot evaluate ThreadSanitizer expression:\n%s\n",
        eval_error.AsCString());
    return StructuredData::ObjectSP();
  }

  std::map<uint64_t, user_id_t> thread_id_map;
  GetRenumberedThreadIds(process_sp, main_value, thread_id_map);

  StructuredData::Dictionary *dict = new StructuredData::Dictionary();
  dict->AddStringItem("instrumentation_class", "ThreadSanitizer");
  dict->AddStringItem("issue_type",
                      RetrieveString(main_value, process_sp, ".description"));
  dict->AddIntegerItem("report_count",
                       main_value->GetValueForExpressionPath(".report_count")
                           ->GetValueAsUnsigned(0));
  dict->AddItem("sleep_trace", StructuredData::ObjectSP(CreateStackTrace(
                                   main_value, ".sleep_trace")));

  StructuredData::Array *stacks = ConvertToStructuredArray(
      main_value, ".stacks", ".stack_count",
      [thread_sp](ValueObjectSP o, StructuredData::Dictionary *dict) {
        dict->AddIntegerItem(
            "index",
            o->GetValueForExpressionPath(".idx")->GetValueAsUnsigned(0));
        dict->AddItem("trace", StructuredData::ObjectSP(CreateStackTrace(o)));
        // "stacks" happen on the current thread
        dict->AddIntegerItem("thread_id", thread_sp->GetIndexID());
      });
  dict->AddItem("stacks", StructuredData::ObjectSP(stacks));

  StructuredData::Array *mops = ConvertToStructuredArray(
      main_value, ".mops", ".mop_count",
      [&thread_id_map](ValueObjectSP o, StructuredData::Dictionary *dict) {
        dict->AddIntegerItem(
            "index",
            o->GetValueForExpressionPath(".idx")->GetValueAsUnsigned(0));
        dict->AddIntegerItem(
            "thread_id",
            Renumber(
                o->GetValueForExpressionPath(".tid")->GetValueAsUnsigned(0),
                thread_id_map));
        dict->AddIntegerItem(
            "size",
            o->GetValueForExpressionPath(".size")->GetValueAsUnsigned(0));
        dict->AddBooleanItem(
            "is_write",
            o->GetValueForExpressionPath(".write")->GetValueAsUnsigned(0));
        dict->AddBooleanItem(
            "is_atomic",
            o->GetValueForExpressionPath(".atomic")->GetValueAsUnsigned(0));
        dict->AddIntegerItem(
            "address",
            o->GetValueForExpressionPath(".addr")->GetValueAsUnsigned(0));
        dict->AddItem("trace", StructuredData::ObjectSP(CreateStackTrace(o)));
      });
  dict->AddItem("mops", StructuredData::ObjectSP(mops));

  StructuredData::Array *locs = ConvertToStructuredArray(
      main_value, ".locs", ".loc_count",
      [process_sp, &thread_id_map](ValueObjectSP o,
                                   StructuredData::Dictionary *dict) {
        dict->AddIntegerItem(
            "index",
            o->GetValueForExpressionPath(".idx")->GetValueAsUnsigned(0));
        dict->AddStringItem("type", RetrieveString(o, process_sp, ".type"));
        dict->AddIntegerItem(
            "address",
            o->GetValueForExpressionPath(".addr")->GetValueAsUnsigned(0));
        dict->AddIntegerItem(
            "start",
            o->GetValueForExpressionPath(".start")->GetValueAsUnsigned(0));
        dict->AddIntegerItem(
            "size",
            o->GetValueForExpressionPath(".size")->GetValueAsUnsigned(0));
        dict->AddIntegerItem(
            "thread_id",
            Renumber(
                o->GetValueForExpressionPath(".tid")->GetValueAsUnsigned(0),
                thread_id_map));
        dict->AddIntegerItem(
            "file_descriptor",
            o->GetValueForExpressionPath(".fd")->GetValueAsUnsigned(0));
        dict->AddIntegerItem("suppressable",
                             o->GetValueForExpressionPath(".suppressable")
                                 ->GetValueAsUnsigned(0));
        dict->AddItem("trace", StructuredData::ObjectSP(CreateStackTrace(o)));
        dict->AddStringItem("object_type",
                            RetrieveString(o, process_sp, ".object_type"));
      });
  dict->AddItem("locs", StructuredData::ObjectSP(locs));

  StructuredData::Array *mutexes = ConvertToStructuredArray(
      main_value, ".mutexes", ".mutex_count",
      [](ValueObjectSP o, StructuredData::Dictionary *dict) {
        dict->AddIntegerItem(
            "index",
            o->GetValueForExpressionPath(".idx")->GetValueAsUnsigned(0));
        dict->AddIntegerItem(
            "mutex_id",
            o->GetValueForExpressionPath(".mutex_id")->GetValueAsUnsigned(0));
        dict->AddIntegerItem(
            "address",
            o->GetValueForExpressionPath(".addr")->GetValueAsUnsigned(0));
        dict->AddIntegerItem(
            "destroyed",
            o->GetValueForExpressionPath(".destroyed")->GetValueAsUnsigned(0));
        dict->AddItem("trace", StructuredData::ObjectSP(CreateStackTrace(o)));
      });
  dict->AddItem("mutexes", StructuredData::ObjectSP(mutexes));

  StructuredData::Array *threads = ConvertToStructuredArray(
      main_value, ".threads", ".thread_count",
      [process_sp, &thread_id_map](ValueObjectSP o,
                                   StructuredData::Dictionary *dict) {
        dict->AddIntegerItem(
            "index",
            o->GetValueForExpressionPath(".idx")->GetValueAsUnsigned(0));
        dict->AddIntegerItem(
            "thread_id",
            Renumber(
                o->GetValueForExpressionPath(".tid")->GetValueAsUnsigned(0),
                thread_id_map));
        dict->AddIntegerItem(
            "thread_os_id",
            o->GetValueForExpressionPath(".os_id")->GetValueAsUnsigned(0));
        dict->AddIntegerItem(
            "running",
            o->GetValueForExpressionPath(".running")->GetValueAsUnsigned(0));
        dict->AddStringItem("name", RetrieveString(o, process_sp, ".name"));
        dict->AddIntegerItem(
            "parent_thread_id",
            Renumber(o->GetValueForExpressionPath(".parent_tid")
                         ->GetValueAsUnsigned(0),
                     thread_id_map));
        dict->AddItem("trace", StructuredData::ObjectSP(CreateStackTrace(o)));
      });
  dict->AddItem("threads", StructuredData::ObjectSP(threads));

  StructuredData::Array *unique_tids = ConvertToStructuredArray(
      main_value, ".unique_tids", ".unique_tid_count",
      [&thread_id_map](ValueObjectSP o, StructuredData::Dictionary *dict) {
        dict->AddIntegerItem(
            "index",
            o->GetValueForExpressionPath(".idx")->GetValueAsUnsigned(0));
        dict->AddIntegerItem(
            "tid",
            Renumber(
                o->GetValueForExpressionPath(".tid")->GetValueAsUnsigned(0),
                thread_id_map));
      });
  dict->AddItem("unique_tids", StructuredData::ObjectSP(unique_tids));

  return StructuredData::ObjectSP(dict);
}

std::string
InstrumentationRuntimeTSan::FormatDescription(StructuredData::ObjectSP report) {
  std::string description = std::string(report->GetAsDictionary()
                                            ->GetValueForKey("issue_type")
                                            ->GetAsString()
                                            ->GetValue());

  if (description == "data-race") {
    return "Data race";
  } else if (description == "data-race-vptr") {
    return "Data race on C++ virtual pointer";
  } else if (description == "heap-use-after-free") {
    return "Use of deallocated memory";
  } else if (description == "heap-use-after-free-vptr") {
    return "Use of deallocated C++ virtual pointer";
  } else if (description == "thread-leak") {
    return "Thread leak";
  } else if (description == "locked-mutex-destroy") {
    return "Destruction of a locked mutex";
  } else if (description == "mutex-double-lock") {
    return "Double lock of a mutex";
  } else if (description == "mutex-invalid-access") {
    return "Use of an uninitialized or destroyed mutex";
  } else if (description == "mutex-bad-unlock") {
    return "Unlock of an unlocked mutex (or by a wrong thread)";
  } else if (description == "mutex-bad-read-lock") {
    return "Read lock of a write locked mutex";
  } else if (description == "mutex-bad-read-unlock") {
    return "Read unlock of a write locked mutex";
  } else if (description == "signal-unsafe-call") {
    return "Signal-unsafe call inside a signal handler";
  } else if (description == "errno-in-signal-handler") {
    return "Overwrite of errno in a signal handler";
  } else if (description == "lock-order-inversion") {
    return "Lock order inversion (potential deadlock)";
  } else if (description == "external-race") {
    return "Race on a library object";
  } else if (description == "swift-access-race") {
    return "Swift access race";
  }

  // for unknown report codes just show the code
  return description;
}

static std::string Sprintf(const char *format, ...) {
  StreamString s;
  va_list args;
  va_start(args, format);
  s.PrintfVarArg(format, args);
  va_end(args);
  return std::string(s.GetString());
}

static std::string GetSymbolNameFromAddress(ProcessSP process_sp, addr_t addr) {
  lldb_private::Address so_addr;
  if (!process_sp->GetTarget().GetSectionLoadList().ResolveLoadAddress(addr,
                                                                       so_addr))
    return "";

  lldb_private::Symbol *symbol = so_addr.CalculateSymbolContextSymbol();
  if (!symbol)
    return "";

  std::string sym_name = symbol->GetName().GetCString();
  return sym_name;
}

static void GetSymbolDeclarationFromAddress(ProcessSP process_sp, addr_t addr,
                                            Declaration &decl) {
  lldb_private::Address so_addr;
  if (!process_sp->GetTarget().GetSectionLoadList().ResolveLoadAddress(addr,
                                                                       so_addr))
    return;

  lldb_private::Symbol *symbol = so_addr.CalculateSymbolContextSymbol();
  if (!symbol)
    return;

  ConstString sym_name = symbol->GetMangled().GetName(Mangled::ePreferMangled);

  ModuleSP module = symbol->CalculateSymbolContextModule();
  if (!module)
    return;

  VariableList var_list;
  module->FindGlobalVariables(sym_name, CompilerDeclContext(), 1U, var_list);
  if (var_list.GetSize() < 1)
    return;

  VariableSP var = var_list.GetVariableAtIndex(0);
  decl = var->GetDeclaration();
}

addr_t InstrumentationRuntimeTSan::GetFirstNonInternalFramePc(
    StructuredData::ObjectSP trace, bool skip_one_frame) {
  ProcessSP process_sp = GetProcessSP();
  ModuleSP runtime_module_sp = GetRuntimeModuleSP();

  StructuredData::Array *trace_array = trace->GetAsArray();
  for (size_t i = 0; i < trace_array->GetSize(); i++) {
    if (skip_one_frame && i == 0)
      continue;

    addr_t addr;
    if (!trace_array->GetItemAtIndexAsInteger(i, addr))
      continue;

    lldb_private::Address so_addr;
    if (!process_sp->GetTarget().GetSectionLoadList().ResolveLoadAddress(
            addr, so_addr))
      continue;

    if (so_addr.GetModule() == runtime_module_sp)
      continue;

    return addr;
  }

  return 0;
}

std::string
InstrumentationRuntimeTSan::GenerateSummary(StructuredData::ObjectSP report) {
  ProcessSP process_sp = GetProcessSP();

  std::string summary = std::string(report->GetAsDictionary()
                                        ->GetValueForKey("description")
                                        ->GetAsString()
                                        ->GetValue());
  bool skip_one_frame =
      report->GetObjectForDotSeparatedPath("issue_type")->GetStringValue() ==
      "external-race";

  addr_t pc = 0;
  if (report->GetAsDictionary()
          ->GetValueForKey("mops")
          ->GetAsArray()
          ->GetSize() > 0)
    pc = GetFirstNonInternalFramePc(report->GetAsDictionary()
                                        ->GetValueForKey("mops")
                                        ->GetAsArray()
                                        ->GetItemAtIndex(0)
                                        ->GetAsDictionary()
                                        ->GetValueForKey("trace"),
                                    skip_one_frame);

  if (report->GetAsDictionary()
          ->GetValueForKey("stacks")
          ->GetAsArray()
          ->GetSize() > 0)
    pc = GetFirstNonInternalFramePc(report->GetAsDictionary()
                                        ->GetValueForKey("stacks")
                                        ->GetAsArray()
                                        ->GetItemAtIndex(0)
                                        ->GetAsDictionary()
                                        ->GetValueForKey("trace"),
                                    skip_one_frame);

  if (pc != 0) {
    summary = summary + " in " + GetSymbolNameFromAddress(process_sp, pc);
  }

  if (report->GetAsDictionary()
          ->GetValueForKey("locs")
          ->GetAsArray()
          ->GetSize() > 0) {
    StructuredData::ObjectSP loc = report->GetAsDictionary()
                                       ->GetValueForKey("locs")
                                       ->GetAsArray()
                                       ->GetItemAtIndex(0);
    std::string object_type = std::string(loc->GetAsDictionary()
                                              ->GetValueForKey("object_type")
                                              ->GetAsString()
                                              ->GetValue());
    if (!object_type.empty()) {
      summary = "Race on " + object_type + " object";
    }
    addr_t addr = loc->GetAsDictionary()
                      ->GetValueForKey("address")
                      ->GetAsInteger()
                      ->GetValue();
    if (addr == 0)
      addr = loc->GetAsDictionary()
                 ->GetValueForKey("start")
                 ->GetAsInteger()
                 ->GetValue();

    if (addr != 0) {
      std::string global_name = GetSymbolNameFromAddress(process_sp, addr);
      if (!global_name.empty()) {
        summary = summary + " at " + global_name;
      } else {
        summary = summary + " at " + Sprintf("0x%llx", addr);
      }
    } else {
      int fd = loc->GetAsDictionary()
                   ->GetValueForKey("file_descriptor")
                   ->GetAsInteger()
                   ->GetValue();
      if (fd != 0) {
        summary = summary + " on file descriptor " + Sprintf("%d", fd);
      }
    }
  }

  return summary;
}

addr_t InstrumentationRuntimeTSan::GetMainRacyAddress(
    StructuredData::ObjectSP report) {
  addr_t result = (addr_t)-1;

  report->GetObjectForDotSeparatedPath("mops")->GetAsArray()->ForEach(
      [&result](StructuredData::Object *o) -> bool {
        addr_t addr =
            o->GetObjectForDotSeparatedPath("address")->GetIntegerValue();
        if (addr < result)
          result = addr;
        return true;
      });

  return (result == (addr_t)-1) ? 0 : result;
}

std::string InstrumentationRuntimeTSan::GetLocationDescription(
    StructuredData::ObjectSP report, addr_t &global_addr,
    std::string &global_name, std::string &filename, uint32_t &line) {
  std::string result = "";

  ProcessSP process_sp = GetProcessSP();

  if (report->GetAsDictionary()
          ->GetValueForKey("locs")
          ->GetAsArray()
          ->GetSize() > 0) {
    StructuredData::ObjectSP loc = report->GetAsDictionary()
                                       ->GetValueForKey("locs")
                                       ->GetAsArray()
                                       ->GetItemAtIndex(0);
    std::string type = std::string(
        loc->GetAsDictionary()->GetValueForKey("type")->GetStringValue());
    if (type == "global") {
      global_addr = loc->GetAsDictionary()
                        ->GetValueForKey("address")
                        ->GetAsInteger()
                        ->GetValue();
      global_name = GetSymbolNameFromAddress(process_sp, global_addr);
      if (!global_name.empty()) {
        result = Sprintf("'%s' is a global variable (0x%llx)",
                         global_name.c_str(), global_addr);
      } else {
        result = Sprintf("0x%llx is a global variable", global_addr);
      }

      Declaration decl;
      GetSymbolDeclarationFromAddress(process_sp, global_addr, decl);
      if (decl.GetFile()) {
        filename = decl.GetFile().GetPath();
        line = decl.GetLine();
      }
    } else if (type == "heap") {
      addr_t addr = loc->GetAsDictionary()
                        ->GetValueForKey("start")
                        ->GetAsInteger()
                        ->GetValue();
      long size = loc->GetAsDictionary()
                      ->GetValueForKey("size")
                      ->GetAsInteger()
                      ->GetValue();
      std::string object_type = std::string(loc->GetAsDictionary()
                                                ->GetValueForKey("object_type")
                                                ->GetAsString()
                                                ->GetValue());
      if (!object_type.empty()) {
        result = Sprintf("Location is a %ld-byte %s object at 0x%llx", size,
                         object_type.c_str(), addr);
      } else {
        result =
            Sprintf("Location is a %ld-byte heap object at 0x%llx", size, addr);
      }
    } else if (type == "stack") {
      int tid = loc->GetAsDictionary()
                    ->GetValueForKey("thread_id")
                    ->GetAsInteger()
                    ->GetValue();
      result = Sprintf("Location is stack of thread %d", tid);
    } else if (type == "tls") {
      int tid = loc->GetAsDictionary()
                    ->GetValueForKey("thread_id")
                    ->GetAsInteger()
                    ->GetValue();
      result = Sprintf("Location is TLS of thread %d", tid);
    } else if (type == "fd") {
      int fd = loc->GetAsDictionary()
                   ->GetValueForKey("file_descriptor")
                   ->GetAsInteger()
                   ->GetValue();
      result = Sprintf("Location is file descriptor %d", fd);
    }
  }

  return result;
}

bool InstrumentationRuntimeTSan::NotifyBreakpointHit(
    void *baton, StoppointCallbackContext *context, user_id_t break_id,
    user_id_t break_loc_id) {
  assert(baton && "null baton");
  if (!baton)
    return false;

  InstrumentationRuntimeTSan *const instance =
      static_cast<InstrumentationRuntimeTSan *>(baton);

  ProcessSP process_sp = instance->GetProcessSP();

  if (process_sp->GetModIDRef().IsLastResumeForUserExpression())
    return false;

  StructuredData::ObjectSP report =
      instance->RetrieveReportData(context->exe_ctx_ref);
  std::string stop_reason_description =
      "unknown thread sanitizer fault (unable to extract thread sanitizer "
      "report)";
  if (report) {
    std::string issue_description = instance->FormatDescription(report);
    report->GetAsDictionary()->AddStringItem("description", issue_description);
    stop_reason_description = issue_description + " detected";
    report->GetAsDictionary()->AddStringItem("stop_description",
                                             stop_reason_description);
    std::string summary = instance->GenerateSummary(report);
    report->GetAsDictionary()->AddStringItem("summary", summary);
    addr_t main_address = instance->GetMainRacyAddress(report);
    report->GetAsDictionary()->AddIntegerItem("memory_address", main_address);

    addr_t global_addr = 0;
    std::string global_name = "";
    std::string location_filename = "";
    uint32_t location_line = 0;
    std::string location_description = instance->GetLocationDescription(
        report, global_addr, global_name, location_filename, location_line);
    report->GetAsDictionary()->AddStringItem("location_description",
                                             location_description);
    if (global_addr != 0) {
      report->GetAsDictionary()->AddIntegerItem("global_address", global_addr);
    }
    if (!global_name.empty()) {
      report->GetAsDictionary()->AddStringItem("global_name", global_name);
    }
    if (location_filename != "") {
      report->GetAsDictionary()->AddStringItem("location_filename",
                                               location_filename);
      report->GetAsDictionary()->AddIntegerItem("location_line", location_line);
    }

    bool all_addresses_are_same = true;
    report->GetObjectForDotSeparatedPath("mops")->GetAsArray()->ForEach(
        [&all_addresses_are_same,
         main_address](StructuredData::Object *o) -> bool {
          addr_t addr =
              o->GetObjectForDotSeparatedPath("address")->GetIntegerValue();
          if (main_address != addr)
            all_addresses_are_same = false;
          return true;
        });
    report->GetAsDictionary()->AddBooleanItem("all_addresses_are_same",
                                              all_addresses_are_same);
  }

  // Make sure this is the right process
  if (process_sp && process_sp == context->exe_ctx_ref.GetProcessSP()) {
    ThreadSP thread_sp = context->exe_ctx_ref.GetThreadSP();
    if (thread_sp)
      thread_sp->SetStopInfo(
          InstrumentationRuntimeStopInfo::
              CreateStopReasonWithInstrumentationData(
                  *thread_sp, stop_reason_description, report));

    StreamFile &s = process_sp->GetTarget().GetDebugger().GetOutputStream();
    s.Printf("ThreadSanitizer report breakpoint hit. Use 'thread "
             "info -s' to get extended information about the "
             "report.\n");

    return true; // Return true to stop the target
  } else
    return false; // Let target run
}

const RegularExpression &
InstrumentationRuntimeTSan::GetPatternForRuntimeLibrary() {
  static RegularExpression regex(llvm::StringRef("libclang_rt.tsan_"));
  return regex;
}

bool InstrumentationRuntimeTSan::CheckIfRuntimeIsValid(
    const lldb::ModuleSP module_sp) {
  static ConstString g_tsan_get_current_report("__tsan_get_current_report");
  const Symbol *symbol = module_sp->FindFirstSymbolWithNameAndType(
      g_tsan_get_current_report, lldb::eSymbolTypeAny);
  return symbol != nullptr;
}

void InstrumentationRuntimeTSan::Activate() {
  if (IsActive())
    return;

  ProcessSP process_sp = GetProcessSP();
  if (!process_sp)
    return;

  ConstString symbol_name("__tsan_on_report");
  const Symbol *symbol = GetRuntimeModuleSP()->FindFirstSymbolWithNameAndType(
      symbol_name, eSymbolTypeCode);

  if (symbol == nullptr)
    return;

  if (!symbol->ValueIsAddress() || !symbol->GetAddressRef().IsValid())
    return;

  Target &target = process_sp->GetTarget();
  addr_t symbol_address = symbol->GetAddressRef().GetOpcodeLoadAddress(&target);

  if (symbol_address == LLDB_INVALID_ADDRESS)
    return;

  bool internal = true;
  bool hardware = false;
  Breakpoint *breakpoint =
      process_sp->GetTarget()
          .CreateBreakpoint(symbol_address, internal, hardware)
          .get();
  breakpoint->SetCallback(InstrumentationRuntimeTSan::NotifyBreakpointHit, this,
                          true);
  breakpoint->SetBreakpointKind("thread-sanitizer-report");
  SetBreakpointID(breakpoint->GetID());

  SetActive(true);
}

void InstrumentationRuntimeTSan::Deactivate() {
  if (GetBreakpointID() != LLDB_INVALID_BREAK_ID) {
    ProcessSP process_sp = GetProcessSP();
    if (process_sp) {
      process_sp->GetTarget().RemoveBreakpointByID(GetBreakpointID());
      SetBreakpointID(LLDB_INVALID_BREAK_ID);
    }
  }
  SetActive(false);
}
static std::string GenerateThreadName(const std::string &path,
                                      StructuredData::Object *o,
                                      StructuredData::ObjectSP main_info) {
  std::string result = "additional information";

  if (path == "mops") {
    int size = o->GetObjectForDotSeparatedPath("size")->GetIntegerValue();
    int thread_id =
        o->GetObjectForDotSeparatedPath("thread_id")->GetIntegerValue();
    bool is_write =
        o->GetObjectForDotSeparatedPath("is_write")->GetBooleanValue();
    bool is_atomic =
        o->GetObjectForDotSeparatedPath("is_atomic")->GetBooleanValue();
    addr_t addr = o->GetObjectForDotSeparatedPath("address")->GetIntegerValue();

    std::string addr_string = Sprintf(" at 0x%llx", addr);

    if (main_info->GetObjectForDotSeparatedPath("all_addresses_are_same")
            ->GetBooleanValue()) {
      addr_string = "";
    }

    if (main_info->GetObjectForDotSeparatedPath("issue_type")
            ->GetStringValue() == "external-race") {
      result = Sprintf("%s access by thread %d",
                       is_write ? "mutating" : "read-only", thread_id);
    } else if (main_info->GetObjectForDotSeparatedPath("issue_type")
                   ->GetStringValue() == "swift-access-race") {
      result = Sprintf("modifying access by thread %d", thread_id);
    } else {
      result = Sprintf("%s%s of size %d%s by thread %d",
                       is_atomic ? "atomic " : "", is_write ? "write" : "read",
                       size, addr_string.c_str(), thread_id);
    }
  }

  if (path == "threads") {
    int thread_id =
        o->GetObjectForDotSeparatedPath("thread_id")->GetIntegerValue();
    result = Sprintf("Thread %d created", thread_id);
  }

  if (path == "locs") {
    std::string type = std::string(
        o->GetAsDictionary()->GetValueForKey("type")->GetStringValue());
    int thread_id =
        o->GetObjectForDotSeparatedPath("thread_id")->GetIntegerValue();
    int fd =
        o->GetObjectForDotSeparatedPath("file_descriptor")->GetIntegerValue();
    if (type == "heap") {
      result = Sprintf("Heap block allocated by thread %d", thread_id);
    } else if (type == "fd") {
      result =
          Sprintf("File descriptor %d created by thread %t", fd, thread_id);
    }
  }

  if (path == "mutexes") {
    int mutex_id =
        o->GetObjectForDotSeparatedPath("mutex_id")->GetIntegerValue();

    result = Sprintf("Mutex M%d created", mutex_id);
  }

  if (path == "stacks") {
    int thread_id =
        o->GetObjectForDotSeparatedPath("thread_id")->GetIntegerValue();
    result = Sprintf("Thread %d", thread_id);
  }

  result[0] = toupper(result[0]);

  return result;
}

static void AddThreadsForPath(const std::string &path,
                              ThreadCollectionSP threads, ProcessSP process_sp,
                              StructuredData::ObjectSP info) {
  info->GetObjectForDotSeparatedPath(path)->GetAsArray()->ForEach(
      [process_sp, threads, path, info](StructuredData::Object *o) -> bool {
        std::vector<lldb::addr_t> pcs;
        o->GetObjectForDotSeparatedPath("trace")->GetAsArray()->ForEach(
            [&pcs](StructuredData::Object *pc) -> bool {
              pcs.push_back(pc->GetAsInteger()->GetValue());
              return true;
            });

        if (pcs.size() == 0)
          return true;

        StructuredData::ObjectSP thread_id_obj =
            o->GetObjectForDotSeparatedPath("thread_os_id");
        tid_t tid = thread_id_obj ? thread_id_obj->GetIntegerValue() : 0;

        HistoryThread *history_thread =
            new HistoryThread(*process_sp, tid, pcs);
        ThreadSP new_thread_sp(history_thread);
        new_thread_sp->SetName(GenerateThreadName(path, o, info).c_str());

        // Save this in the Process' ExtendedThreadList so a strong pointer
        // retains the object
        process_sp->GetExtendedThreadList().AddThread(new_thread_sp);
        threads->AddThread(new_thread_sp);

        return true;
      });
}

lldb::ThreadCollectionSP
InstrumentationRuntimeTSan::GetBacktracesFromExtendedStopInfo(
    StructuredData::ObjectSP info) {
  ThreadCollectionSP threads;
  threads = std::make_shared<ThreadCollection>();

  if (info->GetObjectForDotSeparatedPath("instrumentation_class")
          ->GetStringValue() != "ThreadSanitizer")
    return threads;

  ProcessSP process_sp = GetProcessSP();

  AddThreadsForPath("stacks", threads, process_sp, info);
  AddThreadsForPath("mops", threads, process_sp, info);
  AddThreadsForPath("locs", threads, process_sp, info);
  AddThreadsForPath("mutexes", threads, process_sp, info);
  AddThreadsForPath("threads", threads, process_sp, info);

  return threads;
}
