[Lldb-commits] [lldb] r265905 - Provide more information in ThreadSanitizer's JSON data. Move remaining TSan logic from SBThread to InstrumentationRuntime plugin.
Kuba Brecka via lldb-commits
lldb-commits at lists.llvm.org
Sun Apr 10 11:57:41 PDT 2016
Author: kuba.brecka
Date: Sun Apr 10 13:57:38 2016
New Revision: 265905
URL: http://llvm.org/viewvc/llvm-project?rev=265905&view=rev
Log:
Provide more information in ThreadSanitizer's JSON data. Move remaining TSan logic from SBThread to InstrumentationRuntime plugin.
Modified:
lldb/trunk/include/lldb/Target/InstrumentationRuntime.h
lldb/trunk/packages/Python/lldbsuite/test/functionalities/tsan/basic/TestTsanBasic.py
lldb/trunk/source/API/SBThread.cpp
lldb/trunk/source/Plugins/InstrumentationRuntime/ThreadSanitizer/ThreadSanitizerRuntime.cpp
lldb/trunk/source/Plugins/InstrumentationRuntime/ThreadSanitizer/ThreadSanitizerRuntime.h
lldb/trunk/source/Target/InstrumentationRuntime.cpp
Modified: lldb/trunk/include/lldb/Target/InstrumentationRuntime.h
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/include/lldb/Target/InstrumentationRuntime.h?rev=265905&r1=265904&r2=265905&view=diff
==============================================================================
--- lldb/trunk/include/lldb/Target/InstrumentationRuntime.h (original)
+++ lldb/trunk/include/lldb/Target/InstrumentationRuntime.h Sun Apr 10 13:57:38 2016
@@ -20,6 +20,7 @@
#include "lldb/lldb-private.h"
#include "lldb/lldb-types.h"
#include "lldb/Core/PluginInterface.h"
+#include "lldb/Core/StructuredData.h"
namespace lldb_private {
@@ -39,6 +40,9 @@ public:
virtual bool
IsActive();
+
+ virtual lldb::ThreadCollectionSP
+ GetBacktracesFromExtendedStopInfo(StructuredData::ObjectSP info);
};
Modified: lldb/trunk/packages/Python/lldbsuite/test/functionalities/tsan/basic/TestTsanBasic.py
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/packages/Python/lldbsuite/test/functionalities/tsan/basic/TestTsanBasic.py?rev=265905&r1=265904&r2=265905&view=diff
==============================================================================
--- lldb/trunk/packages/Python/lldbsuite/test/functionalities/tsan/basic/TestTsanBasic.py (original)
+++ lldb/trunk/packages/Python/lldbsuite/test/functionalities/tsan/basic/TestTsanBasic.py Sun Apr 10 13:57:38 2016
@@ -73,7 +73,7 @@ class TsanBasicTestCase(TestBase):
json_line = '\n'.join(output_lines[2:])
data = json.loads(json_line)
self.assertEqual(data["instrumentation_class"], "ThreadSanitizer")
- self.assertEqual(data["description"], "data-race")
+ self.assertEqual(data["issue_type"], "data-race")
self.assertEqual(len(data["mops"]), 2)
backtraces = thread.GetStopReasonExtendedBacktraces(lldb.eInstrumentationRuntimeTypeAddressSanitizer)
@@ -109,7 +109,7 @@ class TsanBasicTestCase(TestBase):
self.runCmd("continue")
# the stop reason of the thread should be a SIGABRT.
- self.expect("thread list", STOPPED_DUE_TO_BREAKPOINT,
+ self.expect("thread list", "We should be stopped due a SIGABRT",
substrs = ['stopped', 'stop reason = signal SIGABRT'])
# test that we're in pthread_kill now (TSan abort the process)
Modified: lldb/trunk/source/API/SBThread.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/API/SBThread.cpp?rev=265905&r1=265904&r2=265905&view=diff
==============================================================================
--- lldb/trunk/source/API/SBThread.cpp (original)
+++ lldb/trunk/source/API/SBThread.cpp Sun Apr 10 13:57:38 2016
@@ -34,7 +34,6 @@
#include "lldb/Target/ThreadPlanStepOut.h"
#include "lldb/Target/ThreadPlanStepRange.h"
#include "lldb/Target/ThreadPlanStepInRange.h"
-#include "Plugins/Process/Utility/HistoryThread.h"
#include "lldb/API/SBAddress.h"
#include "lldb/API/SBDebugger.h"
@@ -329,33 +328,6 @@ SBThread::GetStopReasonExtendedInfoAsJSO
return true;
}
-static void
-AddThreadsForPath(std::string path, ThreadCollectionSP threads, ProcessSP process_sp, StructuredData::ObjectSP info)
-{
- info->GetObjectForDotSeparatedPath(path)->GetAsArray()->ForEach([process_sp, threads] (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_id");
- tid_t tid = thread_id_obj ? thread_id_obj->GetIntegerValue() : 0;
- uint32_t stop_id = 0;
- bool stop_id_is_valid = false;
- HistoryThread *history_thread = new HistoryThread(*process_sp, tid, pcs, stop_id, stop_id_is_valid);
- ThreadSP new_thread_sp(history_thread);
- // 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;
- });
-}
-
SBThreadCollection
SBThread::GetStopReasonExtendedBacktraces (InstrumentationRuntimeType type)
{
@@ -365,10 +337,10 @@ SBThread::GetStopReasonExtendedBacktrace
// We currently only support ThreadSanitizer.
if (type != eInstrumentationRuntimeTypeThreadSanitizer)
return threads;
-
+
ExecutionContext exe_ctx (m_opaque_sp.get());
if (! exe_ctx.HasThreadScope())
- return SBThreadCollection(threads);
+ return threads;
ProcessSP process_sp = exe_ctx.GetProcessSP();
@@ -377,16 +349,7 @@ SBThread::GetStopReasonExtendedBacktrace
if (! info)
return threads;
- if (info->GetObjectForDotSeparatedPath("instrumentation_class")->GetStringValue() != "ThreadSanitizer")
- return threads;
-
- 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;
+ return process_sp->GetInstrumentationRuntime(type)->GetBacktracesFromExtendedStopInfo(info);
}
size_t
Modified: lldb/trunk/source/Plugins/InstrumentationRuntime/ThreadSanitizer/ThreadSanitizerRuntime.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Plugins/InstrumentationRuntime/ThreadSanitizer/ThreadSanitizerRuntime.cpp?rev=265905&r1=265904&r2=265905&view=diff
==============================================================================
--- lldb/trunk/source/Plugins/InstrumentationRuntime/ThreadSanitizer/ThreadSanitizerRuntime.cpp (original)
+++ lldb/trunk/source/Plugins/InstrumentationRuntime/ThreadSanitizer/ThreadSanitizerRuntime.cpp Sun Apr 10 13:57:38 2016
@@ -24,9 +24,11 @@
#include "lldb/Symbol/Symbol.h"
#include "lldb/Symbol/SymbolContext.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 "Plugins/Process/Utility/HistoryThread.h"
using namespace lldb;
using namespace lldb_private;
@@ -346,7 +348,7 @@ ThreadSanitizerRuntime::RetrieveReportDa
StructuredData::Dictionary *dict = new StructuredData::Dictionary();
dict->AddStringItem("instrumentation_class", "ThreadSanitizer");
- dict->AddStringItem("description", RetrieveString(main_value, process_sp, ".description"));
+ 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")));
@@ -412,42 +414,174 @@ ThreadSanitizerRuntime::RetrieveReportDa
std::string
ThreadSanitizerRuntime::FormatDescription(StructuredData::ObjectSP report)
{
- std::string description = report->GetAsDictionary()->GetValueForKey("description")->GetAsString()->GetValue();
+ std::string description = report->GetAsDictionary()->GetValueForKey("issue_type")->GetAsString()->GetValue();
if (description == "data-race") {
- return "Data race detected";
+ return "Data race";
} else if (description == "data-race-vptr") {
- return "Data race on C++ virtual pointer detected";
+ return "Data race on C++ virtual pointer";
} else if (description == "heap-use-after-free") {
- return "Use of deallocated memory detected";
+ return "Use of deallocated memory";
} else if (description == "heap-use-after-free-vptr") {
- return "Use of deallocated C++ virtual pointer detected";
+ return "Use of deallocated C++ virtual pointer";
} else if (description == "thread-leak") {
- return "Thread leak detected";
+ return "Thread leak";
} else if (description == "locked-mutex-destroy") {
- return "Destruction of a locked mutex detected";
+ return "Destruction of a locked mutex";
} else if (description == "mutex-double-lock") {
- return "Double lock of a mutex detected";
+ return "Double lock of a mutex";
} else if (description == "mutex-invalid-access") {
- return "Use of an invalid mutex (e.g. uninitialized or destroyed) detected";
+ return "Use of an invalid mutex (e.g. uninitialized or destroyed)";
} else if (description == "mutex-bad-unlock") {
- return "Unlock of an unlocked mutex (or by a wrong thread) detected";
+ 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 detected";
+ return "Read lock of a write locked mutex";
} else if (description == "mutex-bad-read-unlock") {
- return "Read unlock of a write locked mutex detected";
+ return "Read unlock of a write locked mutex";
} else if (description == "signal-unsafe-call") {
- return "Signal-unsafe call inside a signal handler detected";
+ return "Signal-unsafe call inside a signal handler";
} else if (description == "errno-in-signal-handler") {
- return "Overwrite of errno in a signal handler detected";
+ return "Overwrite of errno in a signal handler";
} else if (description == "lock-order-inversion") {
- return "Lock order inversion (potential deadlock) detected";
+ return "Lock order inversion (potential deadlock)";
}
// 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 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;
+}
+
+addr_t
+ThreadSanitizerRuntime::GetFirstNonInternalFramePc(StructuredData::ObjectSP trace)
+{
+ ProcessSP process_sp = GetProcessSP();
+ ModuleSP runtime_module_sp = GetRuntimeModuleSP();
+
+ addr_t result = 0;
+ trace->GetAsArray()->ForEach([process_sp, runtime_module_sp, &result] (StructuredData::Object *o) -> bool {
+ addr_t addr = o->GetIntegerValue();
+ lldb_private::Address so_addr;
+ if (! process_sp->GetTarget().GetSectionLoadList().ResolveLoadAddress(addr, so_addr))
+ return true;
+
+ if (so_addr.GetModule() == runtime_module_sp)
+ return true;
+
+ result = addr;
+ return false;
+ });
+
+ return result;
+}
+
+std::string
+ThreadSanitizerRuntime::GenerateSummary(StructuredData::ObjectSP report)
+{
+ ProcessSP process_sp = GetProcessSP();
+
+ std::string summary = report->GetAsDictionary()->GetValueForKey("description")->GetAsString()->GetValue();
+ addr_t pc = 0;
+ if (report->GetAsDictionary()->GetValueForKey("mops")->GetAsArray()->GetSize() > 0)
+ pc = GetFirstNonInternalFramePc(report->GetAsDictionary()->GetValueForKey("mops")->GetAsArray()->GetItemAtIndex(0)->GetAsDictionary()->GetValueForKey("trace"));
+
+ if (report->GetAsDictionary()->GetValueForKey("stacks")->GetAsArray()->GetSize() > 0)
+ pc = GetFirstNonInternalFramePc(report->GetAsDictionary()->GetValueForKey("stacks")->GetAsArray()->GetItemAtIndex(0)->GetAsDictionary()->GetValueForKey("trace"));
+
+ 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);
+ addr_t addr = loc->GetAsDictionary()->GetValueForKey("address")->GetAsInteger()->GetValue();
+ if (addr == 0)
+ addr = loc->GetAsDictionary()->GetValueForKey("start")->GetAsInteger()->GetValue();
+
+ if (addr != 0) {
+ 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
+ThreadSanitizerRuntime::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
+ThreadSanitizerRuntime::GetLocationDescription(StructuredData::ObjectSP report)
+{
+ 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 = loc->GetAsDictionary()->GetValueForKey("type")->GetStringValue();
+ if (type == "global") {
+ addr_t addr = loc->GetAsDictionary()->GetValueForKey("address")->GetAsInteger()->GetValue();
+ std::string global_name = GetSymbolNameFromAddress(process_sp, addr);
+ result = Sprintf("Location is a global '%s'", global_name.c_str());
+ } else if (type == "heap") {
+ addr_t addr = loc->GetAsDictionary()->GetValueForKey("start")->GetAsInteger()->GetValue();
+ long size = loc->GetAsDictionary()->GetValueForKey("size")->GetAsInteger()->GetValue();
+ 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
ThreadSanitizerRuntime::NotifyBreakpointHit(void *baton, StoppointCallbackContext *context, user_id_t break_id, user_id_t break_loc_id)
{
@@ -458,17 +592,27 @@ ThreadSanitizerRuntime::NotifyBreakpoint
ThreadSanitizerRuntime *const instance = static_cast<ThreadSanitizerRuntime*>(baton);
StructuredData::ObjectSP report = instance->RetrieveReportData(context->exe_ctx_ref);
- std::string description;
+ std::string stop_reason_description;
if (report) {
- description = instance->FormatDescription(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);
+ std::string location_description = instance->GetLocationDescription(report);
+ report->GetAsDictionary()->AddStringItem("location_description", location_description);
}
+
ProcessSP process_sp = instance->GetProcessSP();
// 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, description.c_str(), report));
+ thread_sp->SetStopInfo(InstrumentationRuntimeStopInfo::CreateStopReasonWithInstrumentationData(*thread_sp, stop_reason_description.c_str(), report));
StreamFileSP stream_sp (process_sp->GetTarget().GetDebugger().GetOutputFile());
if (stream_sp)
@@ -536,3 +680,100 @@ ThreadSanitizerRuntime::Deactivate()
}
m_is_active = false;
}
+
+static std::string
+GenerateThreadName(std::string path, StructuredData::Object *o) {
+ 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();
+
+ result = Sprintf("%s%s of size %d at 0x%llx by thread %d", is_atomic ? "atomic " : "", is_write ? "write" : "read", size, addr, thread_id);
+ }
+
+ if (path == "threads") {
+ int thread_id = o->GetObjectForDotSeparatedPath("thread_id")->GetIntegerValue();
+ int parent_thread_id = o->GetObjectForDotSeparatedPath("parent_thread_id")->GetIntegerValue();
+
+ result = Sprintf("thread %d created by thread %d at", thread_id, parent_thread_id);
+ }
+
+ if (path == "locs") {
+ std::string type = 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 at", thread_id);
+ } else if (type == "fd") {
+ result = Sprintf("File descriptor %d created by thread %t at", fd, thread_id);
+ }
+ }
+
+ if (path == "mutexes") {
+ int mutex_id = o->GetObjectForDotSeparatedPath("mutex_id")->GetIntegerValue();
+
+ result = Sprintf("mutex M%d created at", mutex_id);
+ }
+
+ if (path == "stacks") {
+ result = "happened at";
+ }
+
+ result[0] = toupper(result[0]);
+
+ return result;
+}
+
+static void
+AddThreadsForPath(std::string path, ThreadCollectionSP threads, ProcessSP process_sp, StructuredData::ObjectSP info)
+{
+ info->GetObjectForDotSeparatedPath(path)->GetAsArray()->ForEach([process_sp, threads, path] (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_id");
+ tid_t tid = thread_id_obj ? thread_id_obj->GetIntegerValue() : 0;
+
+ uint32_t stop_id = 0;
+ bool stop_id_is_valid = false;
+ HistoryThread *history_thread = new HistoryThread(*process_sp, tid, pcs, stop_id, stop_id_is_valid);
+ ThreadSP new_thread_sp(history_thread);
+ new_thread_sp->SetName(GenerateThreadName(path, o).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
+ThreadSanitizerRuntime::GetBacktracesFromExtendedStopInfo(StructuredData::ObjectSP info)
+{
+ ThreadCollectionSP threads;
+ threads.reset(new 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;
+}
Modified: lldb/trunk/source/Plugins/InstrumentationRuntime/ThreadSanitizer/ThreadSanitizerRuntime.h
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Plugins/InstrumentationRuntime/ThreadSanitizer/ThreadSanitizerRuntime.h?rev=265905&r1=265904&r2=265905&view=diff
==============================================================================
--- lldb/trunk/source/Plugins/InstrumentationRuntime/ThreadSanitizer/ThreadSanitizerRuntime.h (original)
+++ lldb/trunk/source/Plugins/InstrumentationRuntime/ThreadSanitizer/ThreadSanitizerRuntime.h Sun Apr 10 13:57:38 2016
@@ -63,6 +63,9 @@ public:
bool
IsActive() override;
+ lldb::ThreadCollectionSP
+ GetBacktracesFromExtendedStopInfo(StructuredData::ObjectSP info) override;
+
private:
ThreadSanitizerRuntime(const lldb::ProcessSP &process_sp);
@@ -93,6 +96,18 @@ private:
std::string
FormatDescription(StructuredData::ObjectSP report);
+ std::string
+ GenerateSummary(StructuredData::ObjectSP report);
+
+ lldb::addr_t
+ GetMainRacyAddress(StructuredData::ObjectSP report);
+
+ std::string
+ GetLocationDescription(StructuredData::ObjectSP report);
+
+ lldb::addr_t
+ GetFirstNonInternalFramePc(StructuredData::ObjectSP trace);
+
bool m_is_active;
lldb::ModuleWP m_runtime_module_wp;
lldb::ProcessWP m_process_wp;
Modified: lldb/trunk/source/Target/InstrumentationRuntime.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Target/InstrumentationRuntime.cpp?rev=265905&r1=265904&r2=265905&view=diff
==============================================================================
--- lldb/trunk/source/Target/InstrumentationRuntime.cpp (original)
+++ lldb/trunk/source/Target/InstrumentationRuntime.cpp Sun Apr 10 13:57:38 2016
@@ -50,3 +50,9 @@ InstrumentationRuntime::IsActive()
{
return false;
}
+
+lldb::ThreadCollectionSP
+InstrumentationRuntime::GetBacktracesFromExtendedStopInfo(StructuredData::ObjectSP info)
+{
+ return ThreadCollectionSP(new ThreadCollection());
+}
More information about the lldb-commits
mailing list