Add TestConcurrentEvents test for LLDB's handling of inferior threads
- Test verifies LLDB's handling of inferiors with threads that: hit breakpoints,
  modfiy variables that have watchpoints set, generate user signals, and crash.
- Add a few "stress tests" (with ~100 threads) -- run these with "-l" dotest.py
  flag.
- Fix stop_reason_to_str helper in lldbutil to handle eStopReasonThreadExited.
- Add sort_stopped_threads helper to lldbutil to separate thread lists based
  on stop reason.

Logged llvm.org/pr16566 and llvm.org/pr16567 for bugs exposed.




git-svn-id: https://llvm.org/svn/llvm-project/lldb/trunk@185889 91177308-0d34-0410-b5e6-96231b3b80d8
diff --git a/test/lldbutil.py b/test/lldbutil.py
index 76e4e29..a7fcee8 100644
--- a/test/lldbutil.py
+++ b/test/lldbutil.py
@@ -181,6 +181,8 @@
         return "exception"
     elif enum == lldb.eStopReasonPlanComplete:
         return "plancomplete"
+    elif enum == lldb.eStopReasonThreadExiting:
+        return "threadexiting"
     else:
         raise Exception("Unknown StopReason enum")
 
@@ -258,6 +260,41 @@
 
 
 # ==================================================
+# Get stopped threads due to each stop reason.
+# ==================================================
+
+def sort_stopped_threads(process,
+                         breakpoint_threads = None,
+                         crashed_threads = None,
+                         watchpoint_threads = None,
+                         signal_threads = None,
+                         exiting_threads = None,
+                         other_threads = None):
+    """ Fills array *_threads with threads stopped for the corresponding stop
+        reason.
+    """
+    for lst in [breakpoint_threads,
+                watchpoint_threads,
+                signal_threads,
+                exiting_threads,
+                other_threads]:
+        if lst is not None:
+            lst[:] = []
+
+    for thread in process:
+        dispatched = False
+        for (reason, list) in [(lldb.eStopReasonBreakpoint, breakpoint_threads),
+                               (lldb.eStopReasonException, crashed_threads),
+                               (lldb.eStopReasonWatchpoint, watchpoint_threads),
+                               (lldb.eStopReasonSignal, signal_threads),
+                               (lldb.eStopReasonThreadExiting, exiting_threads),
+                               (None, other_threads)]:
+            if not dispatched and list is not None:
+                if thread.GetStopReason() == reason or reason is None:
+                    list.append(thread)
+                    dispatched = True
+
+# ==================================================
 # Utility functions for setting breakpoints
 # ==================================================