Renumber ThreadSanitizer-provided thread IDs to match LLDB thread numbers.

llvm-svn: 267133
diff --git a/lldb/source/Plugins/InstrumentationRuntime/ThreadSanitizer/ThreadSanitizerRuntime.cpp b/lldb/source/Plugins/InstrumentationRuntime/ThreadSanitizer/ThreadSanitizerRuntime.cpp
index beac526..167f7df 100644
--- a/lldb/source/Plugins/InstrumentationRuntime/ThreadSanitizer/ThreadSanitizerRuntime.cpp
+++ b/lldb/source/Plugins/InstrumentationRuntime/ThreadSanitizer/ThreadSanitizerRuntime.cpp
@@ -150,7 +150,7 @@
                               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 *pid,
+    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);
@@ -209,7 +209,7 @@
     struct {
         int idx;
         int tid;
-        unsigned long pid;
+        unsigned long os_id;
         int running;
         const char *name;
         int parent_tid;
@@ -258,7 +258,7 @@
 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].pid, &t.threads[i].running, &t.threads[i].name, &t.threads[i].parent_tid, t.threads[i].trace, REPORT_TRACE_SIZE);
+    __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;
@@ -310,6 +310,35 @@
     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) {
+    if (! thread_id_map.count(id))
+        return 0;
+    
+    return thread_id_map[id];
+}
+
 StructuredData::ObjectSP
 ThreadSanitizerRuntime::RetrieveReportData(ExecutionContextRef exe_ctx_ref)
 {
@@ -346,6 +375,9 @@
         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"));
@@ -358,9 +390,9 @@
     });
     dict->AddItem("stacks", StructuredData::ObjectSP(stacks));
     
-    StructuredData::Array *mops = ConvertToStructuredArray(main_value, ".mops", ".mop_count", [] (ValueObjectSP o, StructuredData::Dictionary *dict) {
+    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", o->GetValueForExpressionPath(".tid")->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));
@@ -369,13 +401,13 @@
     });
     dict->AddItem("mops", StructuredData::ObjectSP(mops));
     
-    StructuredData::Array *locs = ConvertToStructuredArray(main_value, ".locs", ".loc_count", [process_sp] (ValueObjectSP o, StructuredData::Dictionary *dict) {
+    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", o->GetValueForExpressionPath(".tid")->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)));
@@ -391,20 +423,20 @@
     });
     dict->AddItem("mutexes", StructuredData::ObjectSP(mutexes));
     
-    StructuredData::Array *threads = ConvertToStructuredArray(main_value, ".threads", ".thread_count", [process_sp] (ValueObjectSP o, StructuredData::Dictionary *dict) {
+    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", o->GetValueForExpressionPath(".tid")->GetValueAsUnsigned(0));
-        dict->AddIntegerItem("process_id", o->GetValueForExpressionPath(".pid")->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", o->GetValueForExpressionPath(".parent_tid")->GetValueAsUnsigned(0));
+        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", [] (ValueObjectSP o, StructuredData::Dictionary *dict) {
+    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", o->GetValueForExpressionPath(".tid")->GetValueAsUnsigned(0));
+        dict->AddIntegerItem("tid", Renumber(o->GetValueForExpressionPath(".tid")->GetValueAsUnsigned(0), thread_id_map));
     });
     dict->AddItem("unique_tids", StructuredData::ObjectSP(unique_tids));
     
@@ -697,9 +729,7 @@
     
     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);
+        result = Sprintf("thread %d created at", thread_id);
     }
     
     if (path == "locs") {
@@ -741,7 +771,7 @@
         if (pcs.size() == 0)
             return true;
         
-        StructuredData::ObjectSP thread_id_obj = o->GetObjectForDotSeparatedPath("thread_id");
+        StructuredData::ObjectSP thread_id_obj = o->GetObjectForDotSeparatedPath("thread_os_id");
         tid_t tid = thread_id_obj ? thread_id_obj->GetIntegerValue() : 0;
         
         uint32_t stop_id = 0;