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/1343709 Reviewed-by: Camillo Bruni <cbruni@chromium.org> Commit-Queue: Yuki Shiino <yukishiino@chromium.org> Cr-Commit-Position: refs/heads/master@{#57662}
This commit is contained in:
parent
8708d46cc3
commit
f379bb117f
@ -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
|
||||
|
Loading…
Reference in New Issue
Block a user