Index: include/v8-debug.h
===================================================================
--- include/v8-debug.h	(revision 3039)
+++ include/v8-debug.h	(working copy)
@@ -188,29 +188,56 @@
    */
   typedef void (*HostDispatchHandler)();
 
-  // Set a C debug event listener.
+  /**
+   * Callback function for the host to ensure debug messages are processed.
+   */
+  typedef void (*DebugMessageDispatchHandler)();
+
+  /**
+    *Set a C debug event listener.
+    */
   static bool SetDebugEventListener(EventCallback that,
                                     Handle<Value> data = Handle<Value>());
 
-  // Set a JavaScript debug event listener.
+  /**
+    *Set a JavaScript debug event listener.
+    */
   static bool SetDebugEventListener(v8::Handle<v8::Object> that,
                                     Handle<Value> data = Handle<Value>());
 
-  // Break execution of JavaScript.
+  /**
+   * Break execution of JavaScript.
+   */
   static void DebugBreak();
 
-  // Message based interface. The message protocol is JSON. NOTE the message
-  // handler thread is not supported any more parameter must be false.
+  /**
+    * Message based interface. The message protocol is JSON. NOTE the message
+    * handler thread is not supported any more parameter must be false.
+  */
   static void SetMessageHandler(MessageHandler handler,
                                 bool message_handler_thread = false);
   static void SetMessageHandler2(MessageHandler2 handler);
   static void SendCommand(const uint16_t* command, int length,
                           ClientData* client_data = NULL);
 
-  // Dispatch interface.
+  /**
+    *Dispatch interface.
+    */
   static void SetHostDispatchHandler(HostDispatchHandler handler,
                                      int period = 100);
 
+  /**
+    * Register a callback function to be called when a debug message has been
+    * received and is ready to be precessed. For the debug messages to be
+    * processed V8 needs to be entered, and in certain embedding scenarios this
+    * callback can be used to make sure V8 is entered for the debug message to
+    * be processed. Note that debug messages will only be processed if there is
+    * a V8 break. This can happen automatically by using the option
+    * --debugger-auto-break.
+    */
+  static void SetDebugMessageDispatchHandler(
+      DebugMessageDispatchHandler handler);
+
  /**
   * Run a JavaScript function in the debugger.
   * \param fun the function to call
Index: src/api.cc
===================================================================
--- src/api.cc	(revision 3039)
+++ src/api.cc	(working copy)
@@ -3642,6 +3642,14 @@
 }
 
 
+void Debug::SetDebugMessageDispatchHandler(
+    DebugMessageDispatchHandler handler) {
+  EnsureInitialized("v8::Debug::SetDebugMessageDispatchHandler");
+  ENTER_V8;
+  i::Debugger::SetDebugMessageDispatchHandler(handler);
+}
+
+
 Local<Value> Debug::Call(v8::Handle<v8::Function> fun,
                          v8::Handle<v8::Value> data) {
   if (!i::V8::IsRunning()) return Local<Value>();
Index: src/debug.h
===================================================================
--- src/debug.h	(revision 3039)
+++ src/debug.h	(working copy)
@@ -625,6 +625,8 @@
   static void SetMessageHandler(v8::Debug::MessageHandler2 handler);
   static void SetHostDispatchHandler(v8::Debug::HostDispatchHandler handler,
                                      int period);
+  static void SetDebugMessageDispatchHandler(
+      v8::Debug::DebugMessageDispatchHandler handler);
 
   // Invoke the message handler function.
   static void InvokeMessageHandler(MessageImpl message);
@@ -685,6 +687,7 @@
   static v8::Debug::MessageHandler2 message_handler_;
   static bool debugger_unload_pending_;  // Was message handler cleared?
   static v8::Debug::HostDispatchHandler host_dispatch_handler_;
+  static v8::Debug::DebugMessageDispatchHandler debug_message_dispatch_handler_;
   static int host_dispatch_micros_;
 
   static DebuggerAgent* agent_;
Index: src/debug.cc
===================================================================
--- src/debug.cc	(revision 3039)
+++ src/debug.cc	(working copy)
@@ -1677,6 +1677,22 @@
 }
 
 
+// If an object given is an external string, check that the underlying
+// resource is accessible. For other kinds of objects, always return true.
+static bool IsExternalStringValid(Object* str) {
+  if (!str->IsString() || !StringShape(String::cast(str)).IsExternal()) {
+    return true;
+  }
+  if (String::cast(str)->IsAsciiRepresentation()) {
+    return ExternalAsciiString::cast(str)->resource() != NULL;
+  } else if (String::cast(str)->IsTwoByteRepresentation()) {
+    return ExternalTwoByteString::cast(str)->resource() != NULL;
+  } else {
+    return true;
+  }
+}
+
+
 void Debug::CreateScriptCache() {
   HandleScope scope;
 
@@ -1695,7 +1711,7 @@
   while (iterator.has_next()) {
     HeapObject* obj = iterator.next();
     ASSERT(obj != NULL);
-    if (obj->IsScript() && Script::cast(obj)->HasValidSource()) {
+    if (obj->IsScript() && IsExternalStringValid(Script::cast(obj)->source())) {
       script_cache_->Add(Handle<Script>(Script::cast(obj)));
       count++;
     }
@@ -1759,6 +1775,8 @@
 bool Debugger::debugger_unload_pending_ = false;
 v8::Debug::HostDispatchHandler Debugger::host_dispatch_handler_ = NULL;
 int Debugger::host_dispatch_micros_ = 100 * 1000;
+v8::Debug::DebugMessageDispatchHandler
+    Debugger::debug_message_dispatch_handler_ = NULL;
 DebuggerAgent* Debugger::agent_ = NULL;
 LockingCommandMessageQueue Debugger::command_queue_(kQueueInitialSize);
 Semaphore* Debugger::command_received_ = OS::CreateSemaphore(0);
@@ -2389,6 +2407,12 @@
 }
 
 
+void Debugger::SetDebugMessageDispatchHandler(
+    v8::Debug::DebugMessageDispatchHandler handler) {
+  debug_message_dispatch_handler_ = handler;
+}
+
+
 // Calls the registered debug message handler. This callback is part of the
 // public API.
 void Debugger::InvokeMessageHandler(MessageImpl message) {
@@ -2408,7 +2432,6 @@
                               v8::Debug::ClientData* client_data) {
   // Need to cast away const.
   CommandMessage message = CommandMessage::New(
-      Vector<uint16_t>(const_cast<uint16_t*>(command.start()),
                        command.length()),
       client_data);
   Logger::DebugTag("Put command on command_queue.");
@@ -2419,6 +2442,10 @@
   if (!Debug::InDebugger()) {
     StackGuard::DebugCommand();
   }
+
+  if (Debugger::debug_message_dispatch_handler_ != NULL) {
+    Debugger::debug_message_dispatch_handler_();
+  }
 }
 
 
