Commit f379bb11 authored by Yuki Shiino's avatar Yuki Shiino Committed by Commit Bot

Make Isolate::GetIncumbentContext() work fine with ASAN

When ASAN is enabled, the previous implementation of
Isolate::GetIncumbentContext didn't work well due to mixture of fake
and real stack frames.

This patch converts an address in the fake stack frame to an address
in the real stack frame so that we can compare two addresses.

Bug: chromium:888867, chromium:866610
Change-Id: Iccf570b8555f2fbdc737b12894a2784ffdb31602
Reviewed-on: https://chromium-review.googlesource.com/c/1343709Reviewed-by: 's avatarCamillo Bruni <cbruni@chromium.org>
Commit-Queue: Yuki Shiino <yukishiino@chromium.org>
Cr-Commit-Position: refs/heads/master@{#57662}
parent 8708d46c
......@@ -74,6 +74,10 @@
#include "unicode/uobject.h"
#endif // V8_INTL_SUPPORT
#if defined(V8_USE_ADDRESS_SANITIZER)
#include <sanitizer/asan_interface.h>
#endif
extern "C" const uint8_t* v8_Default_embedded_blob_;
extern "C" uint32_t v8_Default_embedded_blob_size_;
......@@ -2497,14 +2501,23 @@ Handle<Context> Isolate::GetIncumbentContext() {
// if it's newer than the last Context::BackupIncumbentScope entry.
//
// NOTE: This code assumes that the stack grows downward.
// This code doesn't work with ASAN because ASAN seems allocating stack
// separated for native C++ code and compiled JS code, and the following
// comparison doesn't make sense in ASAN.
// TODO(yukishiino): Make the implementation of BackupIncumbentScope more
// robust.
if (!it.done() && (!top_backup_incumbent_scope() ||
it.frame()->sp() < reinterpret_cast<Address>(
top_backup_incumbent_scope()))) {
#if defined(V8_USE_ADDRESS_SANITIZER)
// |it.frame()->sp()| points to an address in the real stack frame, but
// |top_backup_incumbent_scope()| points to an address in a fake stack frame.
// In order to compare them, convert the latter into the address in the real
// stack frame.
void* maybe_fake_top = const_cast<void*>(
reinterpret_cast<const void*>(top_backup_incumbent_scope()));
void* maybe_real_top = __asan_addr_is_in_fake_stack(
__asan_get_current_fake_stack(), maybe_fake_top, nullptr, nullptr);
Address top_backup_incumbent = reinterpret_cast<Address>(
maybe_real_top ? maybe_real_top : maybe_fake_top);
#else
Address top_backup_incumbent =
reinterpret_cast<Address>(top_backup_incumbent_scope());
#endif
if (!it.done() &&
(!top_backup_incumbent || it.frame()->sp() < top_backup_incumbent)) {
Context* context = Context::cast(it.frame()->context());
return Handle<Context>(context->native_context(), this);
}
......
......@@ -74,8 +74,7 @@ using IncumbentContextTest = TestWithIsolate;
// Check that Isolate::GetIncumbentContext() returns the correct one in basic
// scenarios.
#if !defined(V8_USE_ADDRESS_SANITIZER)
TEST_F(IncumbentContextTest, MAYBE_Basic) {
TEST_F(IncumbentContextTest, Basic) {
auto Str = [&](const char* s) {
return String::NewFromUtf8(isolate(), s, NewStringType::kNormal)
.ToLocalChecked();
......@@ -137,6 +136,5 @@ TEST_F(IncumbentContextTest, MAYBE_Basic) {
EXPECT_EQ(global_c, Run(context_a, "funcA()"));
}
}
#endif // !defined(V8_USE_ADDRESS_SANITIZER)
} // namespace v8
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment