[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