summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--CMakeLists.txt2
-rwxr-xr-xenablesanitizers.sh26
-rw-r--r--sanitizerblacklist.txt14
-rw-r--r--src/gc/handletable.cpp8
-rw-r--r--src/gc/handletablecore.cpp10
-rw-r--r--src/inc/clrhost.h16
-rw-r--r--src/vm/vars.hpp5
7 files changed, 57 insertions, 24 deletions
diff --git a/CMakeLists.txt b/CMakeLists.txt
index c7b53ef911..64a6eb912f 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -321,7 +321,7 @@ if (CLR_CMAKE_PLATFORM_UNIX)
string(FIND "$ENV{DEBUG_SANITIZERS}" "asan" __ASAN_POS)
string(FIND "$ENV{DEBUG_SANITIZERS}" "ubsan" __UBSAN_POS)
if ((${__ASAN_POS} GREATER -1) OR (${__UBSAN_POS} GREATER -1))
- set(CLR_SANITIZE_CXX_FLAGS "${CLR_SANITIZE_CXX_FLAGS} -fsanitize=")
+ set(CLR_SANITIZE_CXX_FLAGS "${CLR_SANITIZE_CXX_FLAGS} -fsanitize-blacklist=${CMAKE_CURRENT_SOURCE_DIR}/sanitizerblacklist.txt -fsanitize=")
set(CLR_SANITIZE_LINK_FLAGS "${CLR_SANITIZE_LINK_FLAGS} -fsanitize=")
if (${__ASAN_POS} GREATER -1)
set(CLR_SANITIZE_CXX_FLAGS "${CLR_SANITIZE_CXX_FLAGS}address,")
diff --git a/enablesanitizers.sh b/enablesanitizers.sh
index 0afec5d1ee..70555aa70e 100755
--- a/enablesanitizers.sh
+++ b/enablesanitizers.sh
@@ -10,15 +10,17 @@ if [ $# -eq 0 ]; then
echo " cd $(dirname $0);. enablesanitizers.sh [options]; cd -"
fi
echo "Usage: [asan] [ubsan] [lsan] [all] [off] [clangx.y]"
- echo "asan: optional argument to enable Address Sanitizer."
- echo "ubsan: optional argument to enable Undefined Behavior Sanitizer."
- echo "lsan - optional argument to enable memory Leak Sanitizer."
- echo "all - optional argument to enable asan, ubsan and lsan."
- echo "off - optional argument to turn off all sanitizers."
- echo "clangx.y - optional argument to specify clang version x.y. which is used to resolve stack traces."
+ echo " asan: optional argument to enable Address Sanitizer."
+ echo " ubsan: optional argument to enable Undefined Behavior Sanitizer."
+ echo " lsan - optional argument to enable memory Leak Sanitizer."
+ echo " all - optional argument to enable asan, ubsan and lsan."
+ echo " off - optional argument to turn off all sanitizers."
+ echo " clangx.y - optional argument to specify clang version x.y. which is used to resolve stack traces. Default is 3.6"
else
+ # default to clang 3.6 instead of 3.5 because it supports print_stacktrace (otherwise only one stack frame)
__ClangMajorVersion=3
- __ClangMinorVersion=5
+ __ClangMinorVersion=6
+
__EnableASan=0
__EnableUBSan=0
__EnableLSan=0
@@ -69,7 +71,10 @@ else
unset DEBUG_SANITIZERS
echo "Setting DEBUG_SANITIZERS="
else
- ASAN_OPTIONS="symbolize=1"
+ # for now, specify alloc_dealloc_mismatch=0 as there are too many error reports that are not an issue
+ ASAN_OPTIONS="symbolize=1 alloc_dealloc_mismatch=0"
+ # when Clang 3.8 available, add: suppressions=$(readlink -f sanitizersuppressions.txt)
+ UBSAN_OPTIONS="print_stacktrace=1"
if [ $__EnableASan == 1 ]; then
__Options="$__Options asan"
@@ -91,10 +96,15 @@ else
export ASAN_OPTIONS
echo "Setting ASAN_OPTIONS=$ASAN_OPTIONS"
+ UBSAN_OPTIONS="\"$UBSAN_OPTIONS\""
+ export UBSAN_OPTIONS
+ echo "Setting UBSAN_OPTIONS=$UBSAN_OPTIONS"
+
# used by ASan at run-time
ASAN_SYMBOLIZER_PATH="/usr/bin/llvm-symbolizer-$__ClangMajorVersion.$__ClangMinorVersion"
export ASAN_SYMBOLIZER_PATH
echo "Setting ASAN_SYMBOLIZER_PATH=$ASAN_SYMBOLIZER_PATH"
+ echo "Done. You can now run: build.sh Debug clang$__ClangMajorVersion.$__ClangMinorVersion"
fi
unset __ClangMajorVersion
diff --git a/sanitizerblacklist.txt b/sanitizerblacklist.txt
new file mode 100644
index 0000000000..ec3313973b
--- /dev/null
+++ b/sanitizerblacklist.txt
@@ -0,0 +1,14 @@
+# This file has exclusions to the Clang address sanitizer to suppress error reports
+# When Clang 3.8 is available, convert these to suppression list instead as that is preferred for internal code
+
+# CMiniMdBase::UsesAllocatedMemory - suppress stack-buffer-underflow (code backs up pointer by -1 to check allocation ownership)
+fun:_ZN11CMiniMdBase19UsesAllocatedMemoryEP11CMiniColDef
+
+# JIT_InitPInvokeFrame - suppress unknown sanitizer issue causing SEGV on unknown address 0x000000000000
+# 0 0x4e8a0c in __ubsan::checkDynamicType(void*, void*, unsigned long)
+# 1 0x4e807f in HandleDynamicTypeCacheMiss(__ubsan::DynamicTypeCacheMissData*, unsigned long, unsigned long, __ubsan::ReportOptions)
+# 2 0x4e8051 in __ubsan_handle_dynamic_type_cache_miss
+# 3 0x7f02ce676cd8 in JIT_InitPInvokeFrame(InlinedCallFrame*, void*) /home/steveharter/git/dotnet_coreclr/src/vm/jithelpers.cpp:6491:9
+# 4 0x7f0252bbceb2 (<unknown module>)
+fun:_Z20JIT_InitPInvokeFrameP16InlinedCallFramePv
+
diff --git a/src/gc/handletable.cpp b/src/gc/handletable.cpp
index 7f855bba29..7ded783211 100644
--- a/src/gc/handletable.cpp
+++ b/src/gc/handletable.cpp
@@ -391,11 +391,11 @@ void ValidateFetchObjrefForHandle(OBJECTREF objref, ADIndex appDomainIndex)
_ASSERTE(!pDomain->NoAccessToHandleTable());
#if CHECK_APP_DOMAIN_LEAKS
- if (g_pConfig->AppDomainLeaks())
+ if (g_pConfig->AppDomainLeaks() && objref != NULL)
{
if (appDomainIndex.m_dwIndex)
objref->TryAssignAppDomain(pDomain);
- else if (objref != 0)
+ else
objref->TrySetAppDomainAgile();
}
#endif
@@ -421,11 +421,11 @@ void ValidateAssignObjrefForHandle(OBJECTREF objref, ADIndex appDomainIndex)
_ASSERTE(!pDomain->NoAccessToHandleTable());
#if CHECK_APP_DOMAIN_LEAKS
- if (g_pConfig->AppDomainLeaks())
+ if (g_pConfig->AppDomainLeaks() && objref != NULL)
{
if (appDomainIndex.m_dwIndex)
objref->TryAssignAppDomain(pDomain);
- else if (objref != 0)
+ else
objref->TrySetAppDomainAgile();
}
#endif
diff --git a/src/gc/handletablecore.cpp b/src/gc/handletablecore.cpp
index d302087ec9..10c66497d0 100644
--- a/src/gc/handletablecore.cpp
+++ b/src/gc/handletablecore.cpp
@@ -1984,15 +1984,17 @@ uint32_t BlockAllocHandlesInitial(TableSegment *pSegment, uint32_t uType, uint32
uint32_t uAlloc = uRemain;
// compute the default mask based on that count
- uint32_t dwNewMask = (MASK_EMPTY << uAlloc);
-
+ uint32_t dwNewMask;
// are we allocating all of them?
if (uAlloc >= HANDLE_HANDLES_PER_MASK)
{
- // shift above has unpredictable results in this case
- dwNewMask = MASK_FULL;
+ dwNewMask = MASK_FULL; // avoid unpredictable shift
uAlloc = HANDLE_HANDLES_PER_MASK;
}
+ else
+ {
+ dwNewMask = (MASK_EMPTY << uAlloc);
+ }
// set the free mask
*pdwMask = dwNewMask;
diff --git a/src/inc/clrhost.h b/src/inc/clrhost.h
index 8268c9a69b..3d1a8fae04 100644
--- a/src/inc/clrhost.h
+++ b/src/inc/clrhost.h
@@ -85,6 +85,8 @@ void ClrFlsAssociateCallback(DWORD slot, PTLS_CALLBACK_FUNCTION callback);
// Function pointer for fast TLS fetch - do not use directly
typedef LPVOID (*POPTIMIZEDTLSGETTER)();
+typedef LPVOID* (*CLRFLSGETBLOCK)();
+
extern POPTIMIZEDTLSGETTER __ClrFlsGetBlock;
#ifndef CLR_STANDALONE_BINDER
@@ -98,8 +100,9 @@ inline void ClrFlsIncrementValue(DWORD slot, int increment)
STATIC_CONTRACT_SO_TOLERANT;
_ASSERTE(increment != 0);
-
- void **block = (void **) (*__ClrFlsGetBlock)();
+
+ CLRFLSGETBLOCK clrFlsGetBlockFn = (CLRFLSGETBLOCK)__ClrFlsGetBlock;
+ void **block = (*clrFlsGetBlockFn)();
size_t value;
if (block != NULL)
@@ -134,7 +137,8 @@ inline void * ClrFlsGetValue (DWORD slot)
STATIC_CONTRACT_CANNOT_TAKE_LOCK;
STATIC_CONTRACT_SO_TOLERANT;
- void **block = (void **) (*__ClrFlsGetBlock)();
+ CLRFLSGETBLOCK clrFlsGetBlockFn = (CLRFLSGETBLOCK)__ClrFlsGetBlock;
+ void **block = (*clrFlsGetBlockFn)();
if (block != NULL)
{
return block[slot];
@@ -159,7 +163,8 @@ inline BOOL ClrFlsCheckValue(DWORD slot, void ** pValue)
#ifdef _DEBUG
*pValue = ULongToPtr(0xcccccccc);
#endif //_DEBUG
- void **block = (void **) (*__ClrFlsGetBlock)();
+ CLRFLSGETBLOCK clrFlsGetBlockFn = (CLRFLSGETBLOCK)__ClrFlsGetBlock;
+ void **block = (*clrFlsGetBlockFn)();
if (block != NULL)
{
*pValue = block[slot];
@@ -181,7 +186,8 @@ inline void ClrFlsSetValue(DWORD slot, void *pData)
STATIC_CONTRACT_CANNOT_TAKE_LOCK;
STATIC_CONTRACT_SO_TOLERANT;
- void **block = (void **) (*__ClrFlsGetBlock)();
+ CLRFLSGETBLOCK clrFlsGetBlockFn = (CLRFLSGETBLOCK)__ClrFlsGetBlock;
+ void **block = (*clrFlsGetBlockFn)();
if (block != NULL)
{
block[slot] = pData;
diff --git a/src/vm/vars.hpp b/src/vm/vars.hpp
index cfb4a93233..5286930f4c 100644
--- a/src/vm/vars.hpp
+++ b/src/vm/vars.hpp
@@ -341,8 +341,9 @@ class REF : public OBJECTREF
};
-#define VALIDATEOBJECTREF(objref) ((objref).Validate())
-#define VALIDATEOBJECT(obj) obj->Validate()
+// the while (0) syntax below is to force a trailing semicolon on users of the macro
+#define VALIDATEOBJECTREF(objref) do {if ((objref) != NULL) (objref).Validate();} while (0)
+#define VALIDATEOBJECT(obj) do {if ((obj) != NULL) (obj)->Validate();} while (0)
#define ObjectToOBJECTREF(obj) (OBJECTREF(obj))
#define OBJECTREFToObject(objref) ((objref).operator-> ())