summaryrefslogtreecommitdiff
path: root/src/pal
diff options
context:
space:
mode:
authorEgor Chesakov <Egor.Chesakov@microsoft.com>2018-04-14 00:24:58 -0700
committerGitHub <noreply@github.com>2018-04-14 00:24:58 -0700
commitdb18c71ada41cb978fa61a1b7fcd18e2aa9b217c (patch)
tree2f00517d306fd5f5b9b7a93f37f3b6ffed4f758c /src/pal
parent93f703bf2b65622776ead46dfca34a81bc00c6e5 (diff)
downloadcoreclr-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.cpp25
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;
}