[Lldb-commits] [lldb] r265906 - Add a ThreadSanitizer testcase that tests multiple reported issues.

Kuba Brecka via lldb-commits lldb-commits at lists.llvm.org
Sun Apr 10 12:29:41 PDT 2016


Author: kuba.brecka
Date: Sun Apr 10 14:29:40 2016
New Revision: 265906

URL: http://llvm.org/viewvc/llvm-project?rev=265906&view=rev
Log:
Add a ThreadSanitizer testcase that tests multiple reported issues.


Added:
    lldb/trunk/packages/Python/lldbsuite/test/functionalities/tsan/multiple/
    lldb/trunk/packages/Python/lldbsuite/test/functionalities/tsan/multiple/Makefile
    lldb/trunk/packages/Python/lldbsuite/test/functionalities/tsan/multiple/TestTsanMultiple.py
    lldb/trunk/packages/Python/lldbsuite/test/functionalities/tsan/multiple/main.m

Added: lldb/trunk/packages/Python/lldbsuite/test/functionalities/tsan/multiple/Makefile
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/packages/Python/lldbsuite/test/functionalities/tsan/multiple/Makefile?rev=265906&view=auto
==============================================================================
--- lldb/trunk/packages/Python/lldbsuite/test/functionalities/tsan/multiple/Makefile (added)
+++ lldb/trunk/packages/Python/lldbsuite/test/functionalities/tsan/multiple/Makefile Sun Apr 10 14:29:40 2016
@@ -0,0 +1,6 @@
+LEVEL = ../../../make
+
+C_SOURCES := main.c
+CFLAGS_EXTRAS := -fsanitize=thread -g
+
+include $(LEVEL)/Makefile.rules

Added: lldb/trunk/packages/Python/lldbsuite/test/functionalities/tsan/multiple/TestTsanMultiple.py
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/packages/Python/lldbsuite/test/functionalities/tsan/multiple/TestTsanMultiple.py?rev=265906&view=auto
==============================================================================
--- lldb/trunk/packages/Python/lldbsuite/test/functionalities/tsan/multiple/TestTsanMultiple.py (added)
+++ lldb/trunk/packages/Python/lldbsuite/test/functionalities/tsan/multiple/TestTsanMultiple.py Sun Apr 10 14:29:40 2016
@@ -0,0 +1,68 @@
+"""
+Test ThreadSanitizer when multiple different issues are found.
+"""
+
+import os, time
+import lldb
+from lldbsuite.test.lldbtest import *
+from lldbsuite.test.decorators import *
+import lldbsuite.test.lldbutil as lldbutil
+import json
+
+class TsanMultipleTestCase(TestBase):
+
+    mydir = TestBase.compute_mydir(__file__)
+
+    @expectedFailureAll(oslist=["linux"], bugnumber="non-core functionality, need to reenable and fix later (DES 2014.11.07)")
+    @skipIfFreeBSD # llvm.org/pr21136 runtimes not yet available by default
+    @skipIfRemote
+    @skipUnlessCompilerRt
+    def test (self):
+        self.build ()
+        self.tsan_tests ()
+
+    def setUp(self):
+        # Call super's setUp().
+        TestBase.setUp(self)
+
+    def tsan_tests (self):
+        exe = os.path.join (os.getcwd(), "a.out")
+        self.expect("file " + exe, patterns = [ "Current executable set to .*a.out" ])
+
+        self.runCmd("env TSAN_OPTIONS=abort_on_error=0")
+
+        self.runCmd("run")
+
+        stop_reason = self.dbg.GetSelectedTarget().process.GetSelectedThread().GetStopReason()
+        if stop_reason == lldb.eStopReasonExec:
+            # On OS X 10.10 and older, we need to re-exec to enable interceptors.
+            self.runCmd("continue")
+
+        report_count = 0
+        while self.dbg.GetSelectedTarget().process.GetSelectedThread().GetStopReason() == lldb.eStopReasonInstrumentation:
+            report_count += 1
+
+            stop_description = self.dbg.GetSelectedTarget().process.GetSelectedThread().GetStopDescription(100)
+
+            self.assertTrue(
+                 (stop_description == "Data race detected") or
+                 (stop_description == "Use of deallocated memory detected") or
+                 (stop_description == "Thread leak detected") or
+                 (stop_description == "Use of an invalid mutex (e.g. uninitialized or destroyed) detected") or
+                 (stop_description == "Unlock of an unlocked mutex (or by a wrong thread) detected")
+            )
+
+            self.expect("thread info -s", "The extended stop info should contain the TSan provided fields",
+                substrs = ["instrumentation_class", "description", "mops"])
+
+            output_lines = self.res.GetOutput().split('\n')
+            json_line = '\n'.join(output_lines[2:])
+            data = json.loads(json_line)
+            self.assertEqual(data["instrumentation_class"], "ThreadSanitizer")
+
+            backtraces = self.dbg.GetSelectedTarget().process.GetSelectedThread().GetStopReasonExtendedBacktraces(lldb.eInstrumentationRuntimeTypeThreadSanitizer)
+            self.assertTrue(backtraces.GetSize() >= 1)
+
+            self.runCmd("continue")
+
+        self.assertEqual(self.dbg.GetSelectedTarget().process.GetState(), lldb.eStateExited, PROCESS_EXITED)

Added: lldb/trunk/packages/Python/lldbsuite/test/functionalities/tsan/multiple/main.m
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/packages/Python/lldbsuite/test/functionalities/tsan/multiple/main.m?rev=265906&view=auto
==============================================================================
--- lldb/trunk/packages/Python/lldbsuite/test/functionalities/tsan/multiple/main.m (added)
+++ lldb/trunk/packages/Python/lldbsuite/test/functionalities/tsan/multiple/main.m Sun Apr 10 14:29:40 2016
@@ -0,0 +1,138 @@
+//===-- main.c --------------------------------------------------*- C++ -*-===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#import <Foundation/Foundation.h>
+#import <pthread.h>
+
+long my_global;
+
+void *Thread1(void *arg) {
+    my_global = 42;
+    return NULL;
+}
+
+void *Thread2(void *arg) {
+    my_global = 144;
+    return NULL;
+}
+
+void TestDataRace1() {
+    pthread_t t1, t2;
+    pthread_create(&t1, NULL, Thread1, NULL);
+    pthread_create(&t2, NULL, Thread2, NULL);
+    
+    pthread_join(t1, NULL);
+    pthread_join(t2, NULL);
+}
+
+void TestInvalidMutex() {
+    pthread_mutex_t m = {0};
+    pthread_mutex_lock(&m);
+    
+    pthread_mutex_init(&m, NULL);
+    pthread_mutex_lock(&m);
+    pthread_mutex_unlock(&m);
+    pthread_mutex_destroy(&m);
+    pthread_mutex_lock(&m);
+}
+
+void TestMutexWrongLock() {
+    pthread_mutex_t m = {0};
+    pthread_mutex_init(&m, NULL);
+    pthread_mutex_unlock(&m);
+}
+
+long some_global;
+
+void TestDataRaceBlocks1() {
+    dispatch_queue_t q = dispatch_queue_create("my.queue", DISPATCH_QUEUE_CONCURRENT);
+    
+    for (int i = 0; i < 2; i++) {
+        dispatch_async(q, ^{
+            some_global++;  // race 1
+            
+            usleep(100000);  // force the blocks to be on different threads
+        });
+    }
+    
+    usleep(100000);
+    dispatch_barrier_sync(q, ^{ });
+}
+
+void TestDataRaceBlocks2() {
+    dispatch_queue_t q = dispatch_queue_create("my.queue2", DISPATCH_QUEUE_CONCURRENT);
+    
+    char *c;
+    
+    c = malloc((rand() % 1000) + 10);
+    for (int i = 0; i < 2; i++) {
+        dispatch_async(q, ^{
+            c[0] = 'x';  // race 2
+            fprintf(stderr, "tid: %p\n", pthread_self());
+            usleep(100000);  // force the blocks to be on different threads
+        });
+    }
+    dispatch_barrier_sync(q, ^{ });
+    
+    free(c);
+}
+
+void TestUseAfterFree() {
+    char *c;
+    
+    c = malloc((rand() % 1000) + 10);
+    free(c);
+    c[0] = 'x';
+}
+
+void TestRacePipe() {
+    dispatch_queue_t q = dispatch_queue_create("my.queue3", DISPATCH_QUEUE_CONCURRENT);
+    
+    int a[2];
+    pipe(a);
+    int fd = a[0];
+    
+    for (int i = 0; i < 2; i++) {
+        dispatch_async(q, ^{
+            write(fd, "abc", 3);
+            usleep(100000);  // force the blocks to be on different threads
+        });
+        dispatch_async(q, ^{
+            close(fd);
+            usleep(100000);
+        });
+    }
+    
+    dispatch_barrier_sync(q, ^{ });
+}
+
+void TestThreadLeak() {
+    pthread_t t1;
+    pthread_create(&t1, NULL, Thread1, NULL);
+}
+
+int main(int argc, const char * argv[]) {
+    TestDataRace1();
+    
+    TestInvalidMutex();
+    
+    TestMutexWrongLock();
+    
+    TestDataRaceBlocks1();
+    
+    TestDataRaceBlocks2();
+    
+    TestUseAfterFree();
+    
+    TestRacePipe();
+    
+    TestThreadLeak();
+
+    return 0;
+}




More information about the lldb-commits mailing list