linux: Fix broken tests with address sanitizer
These fixes are mostly related to address sanitizer causing stack
variables to not be stored on the call-stack. Attempting to disable
safe-stack has no effect.
Change-Id: Ib5718bfb74ce91dee560b397ccdbf68d78e4ec6a
Reviewed-on: https://chromium-review.googlesource.com/1140507
Commit-Queue: Joshua Peraza <jperaza@chromium.org>
Reviewed-by: Mark Mentovai <mark@chromium.org>
diff --git a/client/simple_string_dictionary_test.cc b/client/simple_string_dictionary_test.cc
index 5fdeb5b..7af51a2 100644
--- a/client/simple_string_dictionary_test.cc
+++ b/client/simple_string_dictionary_test.cc
@@ -115,8 +115,7 @@
// Add a bunch of values to the dictionary, remove some entries in the middle,
// and then add more.
TEST(SimpleStringDictionary, Iterator) {
- SimpleStringDictionary* dict = new SimpleStringDictionary;
- ASSERT_TRUE(dict);
+ SimpleStringDictionary dict;
char key[SimpleStringDictionary::key_size];
char value[SimpleStringDictionary::value_size];
@@ -135,32 +134,32 @@
for (int i = 0; i < kPartitionIndex; ++i) {
sprintf(key, "key%d", i);
sprintf(value, "value%d", i);
- dict->SetKeyValue(key, value);
+ dict.SetKeyValue(key, value);
}
expected_dictionary_size = kPartitionIndex;
// set a couple of the keys twice (with the same value) - should be nop
- dict->SetKeyValue("key2", "value2");
- dict->SetKeyValue("key4", "value4");
- dict->SetKeyValue("key15", "value15");
+ dict.SetKeyValue("key2", "value2");
+ dict.SetKeyValue("key4", "value4");
+ dict.SetKeyValue("key15", "value15");
// Remove some random elements in the middle
- dict->RemoveKey("key7");
- dict->RemoveKey("key18");
- dict->RemoveKey("key23");
- dict->RemoveKey("key31");
+ dict.RemoveKey("key7");
+ dict.RemoveKey("key18");
+ dict.RemoveKey("key23");
+ dict.RemoveKey("key31");
expected_dictionary_size -= 4; // we just removed four key/value pairs
// Set some more key/value pairs like key59/value59, key60/value60, ...
for (int i = kPartitionIndex; i < kDictionaryCapacity; ++i) {
sprintf(key, "key%d", i);
sprintf(value, "value%d", i);
- dict->SetKeyValue(key, value);
+ dict.SetKeyValue(key, value);
}
expected_dictionary_size += kDictionaryCapacity - kPartitionIndex;
// Now create an iterator on the dictionary
- SimpleStringDictionary::Iterator iter(*dict);
+ SimpleStringDictionary::Iterator iter(dict);
// We then verify that it iterates through exactly the number of key/value
// pairs we expect, and that they match one-for-one with what we would expect.
diff --git a/snapshot/linux/process_reader_linux_test.cc b/snapshot/linux/process_reader_linux_test.cc
index 6c0b98a..940114c 100644
--- a/snapshot/linux/process_reader_linux_test.cc
+++ b/snapshot/linux/process_reader_linux_test.cc
@@ -40,6 +40,7 @@
#include "test/multiprocess.h"
#include "util/file/file_io.h"
#include "util/linux/direct_ptrace_connection.h"
+#include "util/misc/address_sanitizer.h"
#include "util/misc/from_pointer_cast.h"
#include "util/synchronization/semaphore.h"
@@ -264,12 +265,17 @@
iterator->second.tls);
ASSERT_TRUE(memory_map.FindMapping(thread.stack_region_address));
- EXPECT_LE(thread.stack_region_address, iterator->second.stack_address);
-
ASSERT_TRUE(memory_map.FindMapping(thread.stack_region_address +
thread.stack_region_size - 1));
+
+#if !defined(ADDRESS_SANITIZER)
+ // AddressSanitizer causes stack variables to be stored separately from the
+ // call stack.
+ EXPECT_LE(thread.stack_region_address, iterator->second.stack_address);
EXPECT_GE(thread.stack_region_address + thread.stack_region_size,
iterator->second.stack_address);
+#endif // !defined(ADDRESS_SANITIZER)
+
if (iterator->second.max_stack_size) {
EXPECT_LT(thread.stack_region_size, iterator->second.max_stack_size);
}
diff --git a/snapshot/sanitized/process_snapshot_sanitized_test.cc b/snapshot/sanitized/process_snapshot_sanitized_test.cc
index 485ef87..cb413e3 100644
--- a/snapshot/sanitized/process_snapshot_sanitized_test.cc
+++ b/snapshot/sanitized/process_snapshot_sanitized_test.cc
@@ -19,6 +19,7 @@
#include "gtest/gtest.h"
#include "test/multiprocess_exec.h"
#include "util/file/file_io.h"
+#include "util/misc/address_sanitizer.h"
#include "util/numeric/safe_assignment.h"
#if defined(OS_LINUX) || defined(OS_ANDROID)
@@ -162,6 +163,23 @@
// MemorySnapshot::Delegate
bool MemorySnapshotDelegateRead(void* data, size_t size) override {
+#if defined(ADDRESS_SANITIZER) && (defined(OS_LINUX) || defined(OS_ANDROID))
+ // AddressSanitizer causes stack variables to be stored separately from the
+ // call stack.
+ auto addr_not_in_stack_range =
+ [](VMAddress addr, VMAddress stack_addr, VMSize stack_size) {
+ return addr < stack_addr || addr >= stack_addr + stack_size;
+ };
+ EXPECT_PRED3(addr_not_in_stack_range,
+ addrs_.code_pointer_address,
+ stack_->Address(),
+ size);
+ EXPECT_PRED3(addr_not_in_stack_range,
+ addrs_.string_address,
+ stack_->Address(),
+ size);
+ return true;
+#else
size_t pointer_offset;
if (!AssignIfInRange(&pointer_offset,
addrs_.code_pointer_address - stack_->Address())) {
@@ -192,6 +210,7 @@
EXPECT_STREQ(string, kSensitiveStackData);
}
return true;
+#endif // ADDRESS_SANITIZER && (OS_LINUX || OS_ANDROID)
}
private:
diff --git a/util/misc/capture_context_test.cc b/util/misc/capture_context_test.cc
index 1117789..7f3890f 100644
--- a/util/misc/capture_context_test.cc
+++ b/util/misc/capture_context_test.cc
@@ -60,12 +60,16 @@
kReferencePC);
#endif // !defined(ADDRESS_SANITIZER)
- // Declare sp and context_2 here because all local variables need to be
- // declared before computing the stack pointer reference value, so that the
- // reference value can be the lowest value possible.
- uintptr_t sp;
+ const uintptr_t sp = StackPointerFromContext(context_1);
+
+ // Declare context_2 here because all local variables need to be declared
+ // before computing the stack pointer reference value, so that the reference
+ // value can be the lowest value possible.
NativeCPUContext context_2;
+// AddressSanitizer on Linux causes stack variables to be stored separately from
+// the call stack.
+#if !defined(ADDRESS_SANITIZER) || (!defined(OS_LINUX) && !defined(OS_ANDROID))
// The stack pointer reference value is the lowest address of a local variable
// in this function. The captured program counter will be slightly less than
// or equal to the reference stack pointer.
@@ -74,11 +78,11 @@
reinterpret_cast<uintptr_t>(&context_2)),
std::min(reinterpret_cast<uintptr_t>(&pc),
reinterpret_cast<uintptr_t>(&sp)));
- sp = StackPointerFromContext(context_1);
EXPECT_PRED2([](uintptr_t actual,
uintptr_t reference) { return reference - actual < 768u; },
sp,
kReferenceSP);
+#endif // !ADDRESS_SANITIZER || (!OS_LINUX && !OS_ANDROID)
// Capture the context again, expecting that the stack pointer stays the same
// and the program counter increases. Strictly speaking, there’s no guarantee