diff options
author | Egor Chesakov <Egor.Chesakov@microsoft.com> | 2018-04-14 00:24:58 -0700 |
---|---|---|
committer | GitHub <noreply@github.com> | 2018-04-14 00:24:58 -0700 |
commit | db18c71ada41cb978fa61a1b7fcd18e2aa9b217c (patch) | |
tree | 2f00517d306fd5f5b9b7a93f37f3b6ffed4f758c /src/pal | |
parent | 93f703bf2b65622776ead46dfca34a81bc00c6e5 (diff) | |
download | coreclr-db18c71ada41cb978fa61a1b7fcd18e2aa9b217c.tar.gz coreclr-db18c71ada41cb978fa61a1b7fcd18e2aa9b217c.tar.bz2 coreclr-db18c71ada41cb978fa61a1b7fcd18e2aa9b217c.zip |
Fix random Segfaults on Ubuntu arm (#17523)
Fix random Segfaults on Ubuntu arm
Diffstat (limited to 'src/pal')
-rw-r--r-- | src/pal/src/thread/context.cpp | 25 |
1 files changed, 24 insertions, 1 deletions
diff --git a/src/pal/src/thread/context.cpp b/src/pal/src/thread/context.cpp index 0707f4cc6b..12672e86fb 100644 --- a/src/pal/src/thread/context.cpp +++ b/src/pal/src/thread/context.cpp @@ -26,6 +26,8 @@ SET_DEFAULT_DEBUG_CHANNEL(THREAD); // some headers have code with asserts, so do #include "pal/context.h" #include "pal/debug.h" #include "pal/thread.hpp" +#include "pal/utils.h" +#include "pal/virtual.h" #include <sys/ptrace.h> #include <errno.h> @@ -1438,8 +1440,29 @@ DBG_FlushInstructionCache( IN LPCVOID lpBaseAddress, IN SIZE_T dwSize) { - // Intrinsic should do the right thing across all platforms +#ifndef _ARM_ + // Intrinsic should do the right thing across all platforms (except Linux arm) __builtin___clear_cache((char *)lpBaseAddress, (char *)((INT_PTR)lpBaseAddress + dwSize)); +#else // _ARM_ + // On Linux/arm (at least on 3.10) we found that there is a problem with __do_cache_op (arch/arm/kernel/traps.c) + // implementing cacheflush syscall. cacheflush flushes only the first page in range [lpBaseAddress, lpBaseAddress + dwSize) + // and leaves other pages in undefined state which causes random tests failures (often due to SIGSEGV) with no particular pattern. + // + // As a workaround, we call __builtin___clear_cache on each page separately. + + const SIZE_T pageSize = GetVirtualPageSize(); + INT_PTR begin = (INT_PTR)lpBaseAddress; + const INT_PTR end = begin + dwSize; + + while (begin < end) + { + INT_PTR endOrNextPageBegin = ALIGN_UP(begin + 1, pageSize); + if (endOrNextPageBegin > end) + endOrNextPageBegin = end; + __builtin___clear_cache((char *)begin, (char *)endOrNextPageBegin); + begin = endOrNextPageBegin; + } +#endif // _ARM_ return TRUE; } |