Revision: 21382
Author: [email protected]
Date: Tue May 20 10:13:46 2014 UTC
Log: Reland "v8::TryCatch now works correctly with ASAN's
UseAfterReturn mode enabled."
BUG=chromium:369962
LOG=N
[email protected]
Review URL: https://codereview.chromium.org/282783004
http://code.google.com/p/v8/source/detail?r=21382
Modified:
/branches/bleeding_edge/include/v8.h
/branches/bleeding_edge/src/api.cc
/branches/bleeding_edge/src/arm/simulator-arm.h
/branches/bleeding_edge/src/arm64/simulator-arm64.h
/branches/bleeding_edge/src/base/macros.h
/branches/bleeding_edge/src/ia32/simulator-ia32.h
/branches/bleeding_edge/src/isolate.cc
/branches/bleeding_edge/src/isolate.h
/branches/bleeding_edge/src/mips/simulator-mips.h
/branches/bleeding_edge/src/x64/simulator-x64.h
/branches/bleeding_edge/src/zone.h
=======================================
--- /branches/bleeding_edge/include/v8.h Mon May 19 13:45:45 2014 UTC
+++ /branches/bleeding_edge/include/v8.h Tue May 20 10:13:46 2014 UTC
@@ -5075,6 +5075,22 @@
* occurred. True by default.
*/
void SetCaptureMessage(bool value);
+
+ /**
+ * There are cases when the raw address of C++ TryCatch object cannot be
+ * used for comparisons with addresses into the JS stack. The cases are:
+ * 1) ARM, ARM64 and MIPS simulators which have separate JS stack.
+ * 2) Address sanitizer allocates local C++ object in the heap when
+ * UseAfterReturn mode is enabled.
+ * This method returns address that can be used for comparisons with
+ * addresses into the JS stack. When neither simulator nor ASAN's
+ * UseAfterReturn is enabled, then the address returned will be the
address
+ * of the C++ try catch handler itself.
+ */
+ static void* JSStackComparableAddress(v8::TryCatch* handler) {
+ if (handler == NULL) return NULL;
+ return handler->js_stack_comparable_address_;
+ }
private:
// Make it hard to create heap-allocated TryCatch blocks.
@@ -5084,10 +5100,11 @@
void operator delete(void*, size_t);
v8::internal::Isolate* isolate_;
- void* next_;
+ v8::TryCatch* next_;
void* exception_;
void* message_obj_;
void* message_script_;
+ void* js_stack_comparable_address_;
int message_start_pos_;
int message_end_pos_;
bool is_verbose_ : 1;
=======================================
--- /branches/bleeding_edge/src/api.cc Mon May 19 13:45:45 2014 UTC
+++ /branches/bleeding_edge/src/api.cc Tue May 20 10:13:46 2014 UTC
@@ -6,6 +6,9 @@
#include <string.h> // For memcpy, strlen.
#include <cmath> // For isnan.
+#ifdef V8_USE_ADDRESS_SANITIZER
+#include <sanitizer/asan_interface.h>
+#endif // V8_USE_ADDRESS_SANITIZER
#include "../include/v8-debug.h"
#include "../include/v8-profiler.h"
#include "../include/v8-testing.h"
@@ -37,6 +40,7 @@
#include "runtime.h"
#include "runtime-profiler.h"
#include "scanner-character-streams.h"
+#include "simulator.h"
#include "snapshot.h"
#include "unicode-inl.h"
#include "utils/random-number-generator.h"
@@ -1785,13 +1789,26 @@
v8::TryCatch::TryCatch()
: isolate_(i::Isolate::Current()),
- next_(isolate_->try_catch_handler_address()),
+ next_(isolate_->try_catch_handler()),
is_verbose_(false),
can_continue_(true),
capture_message_(true),
rethrow_(false),
has_terminated_(false) {
Reset();
+ js_stack_comparable_address_ = this;
+#ifdef V8_USE_ADDRESS_SANITIZER
+ void* asan_fake_stack_handle = __asan_get_current_fake_stack();
+ if (asan_fake_stack_handle != NULL) {
+ js_stack_comparable_address_ = __asan_addr_is_in_fake_stack(
+ asan_fake_stack_handle, js_stack_comparable_address_, NULL, NULL);
+ CHECK(js_stack_comparable_address_ != NULL);
+ }
+#endif
+ // Special handling for simulators which have a separate JS stack.
+ js_stack_comparable_address_ = reinterpret_cast<void*>(
+ v8::internal::SimulatorStack::RegisterCTryCatch(
+ reinterpret_cast<uintptr_t>(js_stack_comparable_address_)));
isolate_->RegisterTryCatchHandler(this);
}
@@ -1811,10 +1828,12 @@
isolate_->RestorePendingMessageFromTryCatch(this);
}
isolate_->UnregisterTryCatchHandler(this);
+ v8::internal::SimulatorStack::UnregisterCTryCatch();
reinterpret_cast<Isolate*>(isolate_)->ThrowException(exc);
ASSERT(!isolate_->thread_local_top()->rethrowing_message_);
} else {
isolate_->UnregisterTryCatchHandler(this);
+ v8::internal::SimulatorStack::UnregisterCTryCatch();
}
}
=======================================
--- /branches/bleeding_edge/src/arm/simulator-arm.h Fri May 9 12:59:24
2014 UTC
+++ /branches/bleeding_edge/src/arm/simulator-arm.h Tue May 20 10:13:46
2014 UTC
@@ -37,9 +37,6 @@
(FUNCTION_CAST<arm_regexp_matcher>(entry)( \
p0, p1, p2, p3, NULL, p4, p5, p6, p7, p8))
-#define TRY_CATCH_FROM_ADDRESS(try_catch_address) \
- reinterpret_cast<TryCatch*>(try_catch_address)
-
// The stack limit beyond which we will throw stack overflow errors in
// generated code. Because generated code on arm uses the C stack, we
// just use the C stack limit.
@@ -436,10 +433,6 @@
Simulator::current(Isolate::Current())->Call( \
entry, 10, p0, p1, p2, p3, NULL, p4, p5, p6, p7, p8)
-#define
TRY_CATCH_FROM_ADDRESS(try_catch_address) \
- try_catch_address ==
NULL ? \
- NULL : *(reinterpret_cast<TryCatch**>(try_catch_address))
-
// The simulator has its own stack. Thus it has a different stack limit
from
// the C-based native code. Setting the c_limit to indicate a very small
=======================================
--- /branches/bleeding_edge/src/arm64/simulator-arm64.h Mon May 12 15:44:21
2014 UTC
+++ /branches/bleeding_edge/src/arm64/simulator-arm64.h Tue May 20 10:13:46
2014 UTC
@@ -54,9 +54,6 @@
(FUNCTION_CAST<arm64_regexp_matcher>(entry)(
\
p0, p1, p2, p3, p4, p5, p6, p7, NULL, p8))
-#define TRY_CATCH_FROM_ADDRESS(try_catch_address) \
- reinterpret_cast<TryCatch*>(try_catch_address)
-
// Running without a simulator there is nothing to do.
class SimulatorStack : public v8::internal::AllStatic {
public:
@@ -857,10 +854,6 @@
entry, \
p0, p1, p2, p3, p4, p5, p6, p7, NULL, p8)
-#define
TRY_CATCH_FROM_ADDRESS(try_catch_address) \
- try_catch_address ==
NULL ? \
- NULL : *(reinterpret_cast<TryCatch**>(try_catch_address))
-
// The simulator has its own stack. Thus it has a different stack limit
from
// the C-based native code.
=======================================
--- /branches/bleeding_edge/src/base/macros.h Mon May 12 20:10:47 2014 UTC
+++ /branches/bleeding_edge/src/base/macros.h Tue May 20 10:13:46 2014 UTC
@@ -54,15 +54,17 @@
#define MUST_USE_RESULT V8_WARN_UNUSED_RESULT
-// Define DISABLE_ASAN macros.
+// Define V8_USE_ADDRESS_SANITIZER macros.
#if defined(__has_feature)
#if __has_feature(address_sanitizer)
-#define DISABLE_ASAN __attribute__((no_sanitize_address))
+#define V8_USE_ADDRESS_SANITIZER 1
#endif
#endif
-
-#ifndef DISABLE_ASAN
+// Define DISABLE_ASAN macros.
+#ifdef V8_USE_ADDRESS_SANITIZER
+#define DISABLE_ASAN __attribute__((no_sanitize_address))
+#else
#define DISABLE_ASAN
#endif
=======================================
--- /branches/bleeding_edge/src/ia32/simulator-ia32.h Tue Apr 29 06:42:26
2014 UTC
+++ /branches/bleeding_edge/src/ia32/simulator-ia32.h Tue May 20 10:13:46
2014 UTC
@@ -25,9 +25,6 @@
(FUNCTION_CAST<regexp_matcher>(entry)(p0, p1, p2, p3, p4, p5, p6, p7,
p8))
-#define TRY_CATCH_FROM_ADDRESS(try_catch_address) \
- (reinterpret_cast<TryCatch*>(try_catch_address))
-
// The stack limit beyond which we will throw stack overflow errors in
// generated code. Because generated code on ia32 uses the C stack, we
// just use the C stack limit.
=======================================
--- /branches/bleeding_edge/src/isolate.cc Tue May 20 08:52:42 2014 UTC
+++ /branches/bleeding_edge/src/isolate.cc Tue May 20 10:13:46 2014 UTC
@@ -69,7 +69,7 @@
js_entry_sp_ = NULL;
external_callback_scope_ = NULL;
current_vm_state_ = EXTERNAL;
- try_catch_handler_address_ = NULL;
+ try_catch_handler_ = NULL;
context_ = NULL;
thread_id_ = ThreadId::Invalid();
external_caught_exception_ = false;
@@ -96,11 +96,6 @@
#endif
thread_id_ = ThreadId::Current();
}
-
-
-v8::TryCatch* ThreadLocalTop::TryCatchHandler() {
- return TRY_CATCH_FROM_ADDRESS(try_catch_handler_address());
-}
Thread::LocalStorageKey Isolate::isolate_key_;
@@ -209,9 +204,9 @@
v->VisitPointer(BitCast<Object**>(&(thread->context_)));
v->VisitPointer(&thread->scheduled_exception_);
- for (v8::TryCatch* block = thread->TryCatchHandler();
+ for (v8::TryCatch* block = thread->try_catch_handler();
block != NULL;
- block = TRY_CATCH_FROM_ADDRESS(block->next_)) {
+ block = block->next_) {
v->VisitPointer(BitCast<Object**>(&(block->exception_)));
v->VisitPointer(BitCast<Object**>(&(block->message_obj_)));
v->VisitPointer(BitCast<Object**>(&(block->message_script_)));
@@ -266,23 +261,14 @@
void Isolate::RegisterTryCatchHandler(v8::TryCatch* that) {
- // The ARM simulator has a separate JS stack. We therefore register
- // the C++ try catch handler with the simulator and get back an
- // address that can be used for comparisons with addresses into the
- // JS stack. When running without the simulator, the address
- // returned will be the address of the C++ try catch handler itself.
- Address address = reinterpret_cast<Address>(
-
SimulatorStack::RegisterCTryCatch(reinterpret_cast<uintptr_t>(that)));
- thread_local_top()->set_try_catch_handler_address(address);
+ thread_local_top()->set_try_catch_handler(that);
}
void Isolate::UnregisterTryCatchHandler(v8::TryCatch* that) {
- ASSERT(thread_local_top()->TryCatchHandler() == that);
- thread_local_top()->set_try_catch_handler_address(
- reinterpret_cast<Address>(that->next_));
+ ASSERT(thread_local_top()->try_catch_handler() == that);
+ thread_local_top()->set_try_catch_handler(that->next_);
thread_local_top()->catcher_ = NULL;
- SimulatorStack::UnregisterCTryCatch();
}
=======================================
--- /branches/bleeding_edge/src/isolate.h Mon May 19 07:57:04 2014 UTC
+++ /branches/bleeding_edge/src/isolate.h Tue May 20 10:13:46 2014 UTC
@@ -213,10 +213,10 @@
// Get the top C++ try catch handler or NULL if none are registered.
//
- // This method is not guarenteed to return an address that can be
+ // This method is not guaranteed to return an address that can be
// used for comparison with addresses into the JS stack. If such an
// address is needed, use try_catch_handler_address.
- v8::TryCatch* TryCatchHandler();
+ FIELD_ACCESSOR(v8::TryCatch*, try_catch_handler)
// Get the address of the top C++ try catch handler or NULL if
// none are registered.
@@ -228,12 +228,15 @@
// stack, try_catch_handler_address returns a JS stack address that
// corresponds to the place on the JS stack where the C++ handler
// would have been if the stack were not separate.
- FIELD_ACCESSOR(Address, try_catch_handler_address)
+ Address try_catch_handler_address() {
+ return reinterpret_cast<Address>(
+ v8::TryCatch::JSStackComparableAddress(try_catch_handler()));
+ }
void Free() {
ASSERT(!has_pending_message_);
ASSERT(!external_caught_exception_);
- ASSERT(try_catch_handler_address_ == NULL);
+ ASSERT(try_catch_handler_ == NULL);
}
Isolate* isolate_;
@@ -281,7 +284,7 @@
private:
void InitializeInternal();
- Address try_catch_handler_address_;
+ v8::TryCatch* try_catch_handler_;
};
@@ -559,7 +562,7 @@
thread_local_top_.pending_message_script_ = heap_.the_hole_value();
}
v8::TryCatch* try_catch_handler() {
- return thread_local_top_.TryCatchHandler();
+ return thread_local_top_.try_catch_handler();
}
Address try_catch_handler_address() {
return thread_local_top_.try_catch_handler_address();
=======================================
--- /branches/bleeding_edge/src/mips/simulator-mips.h Tue Apr 29 06:42:26
2014 UTC
+++ /branches/bleeding_edge/src/mips/simulator-mips.h Tue May 20 10:13:46
2014 UTC
@@ -38,9 +38,6 @@
(FUNCTION_CAST<mips_regexp_matcher>(entry)( \
p0, p1, p2, p3, NULL, p4, p5, p6, p7, p8))
-#define TRY_CATCH_FROM_ADDRESS(try_catch_address) \
- reinterpret_cast<TryCatch*>(try_catch_address)
-
// The stack limit beyond which we will throw stack overflow errors in
// generated code. Because generated code on mips uses the C stack, we
// just use the C stack limit.
@@ -390,10 +387,6 @@
Simulator::current(Isolate::Current())->Call( \
entry, 10, p0, p1, p2, p3, NULL, p4, p5, p6, p7, p8)
-#define
TRY_CATCH_FROM_ADDRESS(try_catch_address) \
- try_catch_address ==
NULL ? \
- NULL : *(reinterpret_cast<TryCatch**>(try_catch_address))
-
// The simulator has its own stack. Thus it has a different stack limit
from
// the C-based native code. Setting the c_limit to indicate a very small
=======================================
--- /branches/bleeding_edge/src/x64/simulator-x64.h Tue Apr 29 06:42:26
2014 UTC
+++ /branches/bleeding_edge/src/x64/simulator-x64.h Tue May 20 10:13:46
2014 UTC
@@ -24,9 +24,6 @@
#define CALL_GENERATED_REGEXP_CODE(entry, p0, p1, p2, p3, p4, p5, p6, p7,
p8) \
(FUNCTION_CAST<regexp_matcher>(entry)(p0, p1, p2, p3, p4, p5, p6, p7,
p8))
-#define TRY_CATCH_FROM_ADDRESS(try_catch_address) \
- (reinterpret_cast<TryCatch*>(try_catch_address))
-
// The stack limit beyond which we will throw stack overflow errors in
// generated code. Because generated code on x64 uses the C stack, we
// just use the C stack limit.
=======================================
--- /branches/bleeding_edge/src/zone.h Mon May 12 20:10:47 2014 UTC
+++ /branches/bleeding_edge/src/zone.h Tue May 20 10:13:46 2014 UTC
@@ -15,11 +15,6 @@
namespace v8 {
namespace internal {
-#if defined(__has_feature)
- #if __has_feature(address_sanitizer)
- #define V8_USE_ADDRESS_SANITIZER
- #endif
-#endif
class Segment;
class Isolate;
--
--
v8-dev mailing list
[email protected]
http://groups.google.com/group/v8-dev
---
You received this message because you are subscribed to the Google Groups "v8-dev" group.
To unsubscribe from this group and stop receiving emails from it, send an email
to [email protected].
For more options, visit https://groups.google.com/d/optout.