diff --git a/src/isolate.cc b/src/isolate.cc index e1aa127671..eb8b6fdcb4 100644 --- a/src/isolate.cc +++ b/src/isolate.cc @@ -74,6 +74,10 @@ #include "unicode/uobject.h" #endif // V8_INTL_SUPPORT +#if defined(V8_USE_ADDRESS_SANITIZER) +#include +#endif + extern "C" const uint8_t* v8_Default_embedded_blob_; extern "C" uint32_t v8_Default_embedded_blob_size_; @@ -2497,14 +2501,23 @@ Handle 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
( - 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( + reinterpret_cast(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
( + maybe_real_top ? maybe_real_top : maybe_fake_top); +#else + Address top_backup_incumbent = + reinterpret_cast
(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->native_context(), this); } diff --git a/test/unittests/api/isolate-unittest.cc b/test/unittests/api/isolate-unittest.cc index 8ddf8a29c8..10fa7bba22 100644 --- a/test/unittests/api/isolate-unittest.cc +++ b/test/unittests/api/isolate-unittest.cc @@ -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