Imported Upstream version 6.10.0.49

Former-commit-id: 1d6753294b2993e1fbf92de9366bb9544db4189b
This commit is contained in:
Xamarin Public Jenkins (auto-signing)
2020-01-16 16:38:04 +00:00
parent d94e79959b
commit 468663ddbb
48518 changed files with 2789335 additions and 61176 deletions

View File

@ -0,0 +1,6 @@
LEVEL = ../../../make
C_SOURCES := main.c
CFLAGS_EXTRAS := -fsanitize=thread -g
include $(LEVEL)/Makefile.rules

View File

@ -0,0 +1,136 @@
"""
Tests basic ThreadSanitizer support (detecting a data race).
"""
import os
import time
import lldb
from lldbsuite.test.lldbtest import *
from lldbsuite.test.decorators import *
import lldbsuite.test.lldbutil as lldbutil
import json
class TsanBasicTestCase(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
@skipUnlessThreadSanitizer
def test(self):
self.build()
self.tsan_tests()
def setUp(self):
# Call super's setUp().
TestBase.setUp(self)
self.line_malloc = line_number('main.c', '// malloc line')
self.line_thread1 = line_number('main.c', '// thread1 line')
self.line_thread2 = line_number('main.c', '// thread2 line')
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("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")
# the stop reason of the thread should be breakpoint.
self.expect("thread list", "A data race should be detected",
substrs=['stopped', 'stop reason = Data race detected'])
self.assertEqual(
self.dbg.GetSelectedTarget().process.GetSelectedThread().GetStopReason(),
lldb.eStopReasonInstrumentation)
# test that the TSan dylib is present
self.expect(
"image lookup -n __tsan_get_current_report",
"__tsan_get_current_report should be present",
substrs=['1 match found'])
# We should be stopped in __tsan_on_report
process = self.dbg.GetSelectedTarget().process
thread = process.GetSelectedThread()
frame = thread.GetSelectedFrame()
self.assertTrue("__tsan_on_report" in frame.GetFunctionName())
# The stopped thread backtrace should contain either line1 or line2
# from main.c.
found = False
for i in range(0, thread.GetNumFrames()):
frame = thread.GetFrameAtIndex(i)
if frame.GetLineEntry().GetFileSpec().GetFilename() == "main.c":
if frame.GetLineEntry().GetLine() == self.line_thread1:
found = True
if frame.GetLineEntry().GetLine() == self.line_thread2:
found = True
self.assertTrue(found)
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")
self.assertEqual(data["issue_type"], "data-race")
self.assertEqual(len(data["mops"]), 2)
backtraces = thread.GetStopReasonExtendedBacktraces(
lldb.eInstrumentationRuntimeTypeAddressSanitizer)
self.assertEqual(backtraces.GetSize(), 0)
backtraces = thread.GetStopReasonExtendedBacktraces(
lldb.eInstrumentationRuntimeTypeThreadSanitizer)
self.assertTrue(backtraces.GetSize() >= 2)
# First backtrace is a memory operation
thread = backtraces.GetThreadAtIndex(0)
found = False
for i in range(0, thread.GetNumFrames()):
frame = thread.GetFrameAtIndex(i)
if frame.GetLineEntry().GetFileSpec().GetFilename() == "main.c":
if frame.GetLineEntry().GetLine() == self.line_thread1:
found = True
if frame.GetLineEntry().GetLine() == self.line_thread2:
found = True
self.assertTrue(found)
# Second backtrace is a memory operation
thread = backtraces.GetThreadAtIndex(1)
found = False
for i in range(0, thread.GetNumFrames()):
frame = thread.GetFrameAtIndex(i)
if frame.GetLineEntry().GetFileSpec().GetFilename() == "main.c":
if frame.GetLineEntry().GetLine() == self.line_thread1:
found = True
if frame.GetLineEntry().GetLine() == self.line_thread2:
found = True
self.assertTrue(found)
self.runCmd("continue")
# the stop reason of the thread should be a SIGABRT.
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)
self.expect("thread list", "We should be stopped in pthread_kill",
substrs=['pthread_kill'])

View File

@ -0,0 +1,37 @@
//===-- main.c --------------------------------------------------*- C++ -*-===//
//
// The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
#include <pthread.h>
#include <stdio.h>
#include <stdlib.h>
char *pointer;
void *f1(void *p) {
pointer[0] = 'x'; // thread1 line
return NULL;
}
void *f2(void *p) {
pointer[0] = 'y'; // thread2 line
return NULL;
}
int main (int argc, char const *argv[])
{
pointer = (char *)malloc(10); // malloc line
pthread_t t1, t2;
pthread_create(&t1, NULL, f1, NULL);
pthread_create(&t2, NULL, f2, NULL);
pthread_join(t1, NULL);
pthread_join(t2, NULL);
return 0;
}

View File

@ -0,0 +1,6 @@
LEVEL = ../../../make
CXX_SOURCES := main.cpp
CFLAGS_EXTRAS := -fsanitize=thread -g
include $(LEVEL)/Makefile.rules

View File

@ -0,0 +1,69 @@
"""
Tests that TSan correctly reports the filename and line number of a racy global C++ variable.
"""
import os
import time
import lldb
from lldbsuite.test.lldbtest import *
from lldbsuite.test.decorators import *
import lldbsuite.test.lldbutil as lldbutil
import json
class TsanCPPGlobalLocationTestCase(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
@skipUnlessThreadSanitizer
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("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")
# the stop reason of the thread should be breakpoint.
self.expect("thread list", "A data race should be detected",
substrs=['stopped', 'stop reason = Data race 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")
self.assertEqual(data["issue_type"], "data-race")
self.assertTrue(data["location_filename"].endswith("/main.cpp"))
self.assertEqual(
data["location_line"],
line_number(
'main.cpp',
'// global variable'))

View File

@ -0,0 +1,38 @@
//===-- main.cpp ------------------------------------------------*- C++ -*-===//
//
// The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
#include <pthread.h>
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
long my_global_variable; // global variable
void *f1(void *p) {
my_global_variable = 42;
return NULL;
}
void *f2(void *p) {
my_global_variable = 43;
return NULL;
}
int main (int argc, char const *argv[])
{
pthread_t t1;
pthread_create(&t1, NULL, f1, NULL);
pthread_t t2;
pthread_create(&t2, NULL, f2, NULL);
pthread_join(t1, NULL);
pthread_join(t2, NULL);
return 0;
}

View File

@ -0,0 +1,6 @@
LEVEL = ../../../make
C_SOURCES := main.c
CFLAGS_EXTRAS := -fsanitize=thread -g
include $(LEVEL)/Makefile.rules

View File

@ -0,0 +1,69 @@
"""
Tests that TSan correctly reports the filename and line number of a racy global variable.
"""
import os
import time
import lldb
from lldbsuite.test.lldbtest import *
from lldbsuite.test.decorators import *
import lldbsuite.test.lldbutil as lldbutil
import json
class TsanGlobalLocationTestCase(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
@skipUnlessThreadSanitizer
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("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")
# the stop reason of the thread should be breakpoint.
self.expect("thread list", "A data race should be detected",
substrs=['stopped', 'stop reason = Data race 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")
self.assertEqual(data["issue_type"], "data-race")
self.assertTrue(data["location_filename"].endswith("/main.c"))
self.assertEqual(
data["location_line"],
line_number(
'main.c',
'// global variable'))

View File

@ -0,0 +1,38 @@
//===-- main.c --------------------------------------------------*- C++ -*-===//
//
// The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
#include <pthread.h>
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
long my_global_variable; // global variable
void *f1(void *p) {
my_global_variable = 42;
return NULL;
}
void *f2(void *p) {
my_global_variable = 43;
return NULL;
}
int main (int argc, char const *argv[])
{
pthread_t t1;
pthread_create(&t1, NULL, f1, NULL);
pthread_t t2;
pthread_create(&t2, NULL, f2, NULL);
pthread_join(t1, NULL);
pthread_join(t2, NULL);
return 0;
}

View File

@ -0,0 +1,6 @@
LEVEL = ../../../make
C_SOURCES := main.c
CFLAGS_EXTRAS := -fsanitize=thread -g
include $(LEVEL)/Makefile.rules

View File

@ -0,0 +1,86 @@
"""
Test ThreadSanitizer when multiple different issues are found.
"""
import os
import 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
@skipUnlessThreadSanitizer
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 uninitialized or destroyed mutex 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)

View File

@ -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;
}

View File

@ -0,0 +1,6 @@
LEVEL = ../../../make
C_SOURCES := main.c
CFLAGS_EXTRAS := -fsanitize=thread -g
include $(LEVEL)/Makefile.rules

View File

@ -0,0 +1,48 @@
"""
Tests ThreadSanitizer's support to detect a leaked thread.
"""
import os
import time
import lldb
from lldbsuite.test.lldbtest import *
from lldbsuite.test.decorators import *
import lldbsuite.test.lldbutil as lldbutil
import json
class TsanThreadLeakTestCase(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
@skipUnlessThreadSanitizer
def test(self):
self.build()
self.tsan_tests()
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("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")
# the stop reason of the thread should be breakpoint.
self.expect("thread list", "A thread leak should be detected",
substrs=['stopped', 'stop reason = Thread leak detected'])
self.assertEqual(
self.dbg.GetSelectedTarget().process.GetSelectedThread().GetStopReason(),
lldb.eStopReasonInstrumentation)

View File

@ -0,0 +1,24 @@
//===-- main.c --------------------------------------------------*- C++ -*-===//
//
// The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
#include <pthread.h>
#include <stdio.h>
#include <stdlib.h>
void *f1(void *p) {
printf("hello\n");
return NULL;
}
int main (int argc, char const *argv[])
{
pthread_t t1;
pthread_create(&t1, NULL, f1, NULL);
return 0;
}

View File

@ -0,0 +1,6 @@
LEVEL = ../../../make
C_SOURCES := main.c
CFLAGS_EXTRAS := -fsanitize=thread -g
include $(LEVEL)/Makefile.rules

View File

@ -0,0 +1,87 @@
"""
Tests that TSan and LLDB have correct thread numbers.
"""
import os
import time
import lldb
from lldbsuite.test.lldbtest import *
from lldbsuite.test.decorators import *
import lldbsuite.test.lldbutil as lldbutil
import json
class TsanThreadNumbersTestCase(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
@skipUnlessThreadSanitizer
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("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")
# the stop reason of the thread should be breakpoint.
self.expect("thread list", "A data race should be detected",
substrs=['stopped', 'stop reason = Data race detected'])
self.assertEqual(
self.dbg.GetSelectedTarget().process.GetSelectedThread().GetStopReason(),
lldb.eStopReasonInstrumentation)
report_thread_id = self.dbg.GetSelectedTarget(
).process.GetSelectedThread().GetIndexID()
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")
self.assertEqual(data["issue_type"], "data-race")
self.assertEqual(len(data["mops"]), 2)
self.assertEqual(data["mops"][0]["thread_id"], report_thread_id)
other_thread_id = data["mops"][1]["thread_id"]
self.assertTrue(other_thread_id != report_thread_id)
other_thread = self.dbg.GetSelectedTarget(
).process.GetThreadByIndexID(other_thread_id)
self.assertTrue(other_thread.IsValid())
self.runCmd("thread select %d" % other_thread_id)
self.expect(
"thread backtrace",
"The other thread should be stopped in f1 or f2",
substrs=[
"a.out",
"main.c"])

View File

@ -0,0 +1,58 @@
//===-- main.c --------------------------------------------------*- C++ -*-===//
//
// The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
#include <pthread.h>
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
char *pointer;
void *nothing(void *p) {
return NULL;
}
void *f1(void *p) {
pointer[0] = 'x';
sleep(100);
return NULL;
}
void *f2(void *p) {
pointer[0] = 'y';
sleep(100);
return NULL;
}
int main (int argc, char const *argv[])
{
pointer = (char *)malloc(10);
for (int i = 0; i < 3; i++) {
pthread_t t;
pthread_create(&t, NULL, nothing, NULL);
pthread_join(t, NULL);
}
pthread_t t1;
pthread_create(&t1, NULL, f1, NULL);
for (int i = 0; i < 3; i++) {
pthread_t t;
pthread_create(&t, NULL, nothing, NULL);
pthread_join(t, NULL);
}
pthread_t t2;
pthread_create(&t2, NULL, f2, NULL);
pthread_join(t1, NULL);
pthread_join(t2, NULL);
return 0;
}