[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