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.

Reply via email to