aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authordigit@chromium.org <digit@chromium.org@4c0a9323-5329-0410-9bdc-e9ce6186880e>2013-03-21 08:22:37 +0000
committerdigit@chromium.org <digit@chromium.org@4c0a9323-5329-0410-9bdc-e9ce6186880e>2013-03-21 08:22:37 +0000
commit0192fc21b9a5e93cbf57f63444ee1cca73e58d84 (patch)
tree25cf0d13e71a12fa9f94bfc236c6e2abfdedb508 /src
parentLinux MinidumpWriter should properly set number_of_processors on ARM (diff)
downloadbreakpad-0192fc21b9a5e93cbf57f63444ee1cca73e58d84.tar.xz
Fix three unit tests on recent ARM devices.
Three unit tests were failing on recent ARM devices (e.g. Galaxy Nexus or Nexus 4), while ran properly on older ones (e.g. Nexus S). The main issue is that the instruction cache needs to be explicitely cleared on ARM after writing machine code bytes to a malloc()-ed page with PROT_EXEC. Review URL: https://breakpad.appspot.com/540002 git-svn-id: http://google-breakpad.googlecode.com/svn/trunk@1132 4c0a9323-5329-0410-9bdc-e9ce6186880e
Diffstat (limited to 'src')
-rw-r--r--src/client/linux/handler/exception_handler_unittest.cc24
1 files changed, 24 insertions, 0 deletions
diff --git a/src/client/linux/handler/exception_handler_unittest.cc b/src/client/linux/handler/exception_handler_unittest.cc
index 27a7a777..0ba52163 100644
--- a/src/client/linux/handler/exception_handler_unittest.cc
+++ b/src/client/linux/handler/exception_handler_unittest.cc
@@ -54,6 +54,27 @@ using namespace google_breakpad;
namespace {
+// Flush the instruction cache for a given memory range.
+// Only required on ARM.
+void FlushInstructionCache(const char* memory, uint32_t memory_size) {
+#if defined(__arm__)
+ long begin = reinterpret_cast<long>(memory);
+ long end = begin + static_cast<long>(memory_size);
+# if defined(__ANDROID__)
+ // Provided by Android's <unistd.h>
+ cacheflush(begin, end, 0);
+# elif defined(__linux__)
+ // GLibc/ARM doesn't provide a wrapper for it, do a direct syscall.
+# ifndef __ARM_NR_cacheflush
+# define __ARM_NR_cacheflush 0xf0002
+# endif
+ syscall(__ARM_NR_cacheflush, begin, end, 0);
+# else
+# error "Your operating system is not supported yet"
+# endif
+#endif
+}
+
// Length of a formatted GUID string =
// sizeof(MDGUID) * 2 + 4 (for dashes) + 1 (null terminator)
const int kGUIDStringSize = 37;
@@ -449,6 +470,7 @@ TEST(ExceptionHandlerTest, InstructionPointerMemory) {
// of the block of memory, because the minidump should contain 128
// bytes on either side of the instruction pointer.
memcpy(memory + kOffset, instructions, sizeof(instructions));
+ FlushInstructionCache(memory, kMemorySize);
// Now execute the instructions, which should crash.
typedef void (*void_function)(void);
@@ -541,6 +563,7 @@ TEST(ExceptionHandlerTest, InstructionPointerMemoryMinBound) {
// of the block of memory, because the minidump should contain 128
// bytes on either side of the instruction pointer.
memcpy(memory + kOffset, instructions, sizeof(instructions));
+ FlushInstructionCache(memory, kMemorySize);
// Now execute the instructions, which should crash.
typedef void (*void_function)(void);
@@ -632,6 +655,7 @@ TEST(ExceptionHandlerTest, InstructionPointerMemoryMaxBound) {
// of the block of memory, because the minidump should contain 128
// bytes on either side of the instruction pointer.
memcpy(memory + kOffset, instructions, sizeof(instructions));
+ FlushInstructionCache(memory, kMemorySize);
// Now execute the instructions, which should crash.
typedef void (*void_function)(void);