1 // Copyright 2008 the V8 project authors. All rights reserved. 2 // Redistribution and use in source and binary forms, with or without 3 // modification, are permitted provided that the following conditions are 4 // met: 5 // 6 // * Redistributions of source code must retain the above copyright 7 // notice, this list of conditions and the following disclaimer. 8 // * Redistributions in binary form must reproduce the above 9 // copyright notice, this list of conditions and the following 10 // disclaimer in the documentation and/or other materials provided 11 // with the distribution. 12 // * Neither the name of Google Inc. nor the names of its 13 // contributors may be used to endorse or promote products derived 14 // from this software without specific prior written permission. 15 // 16 // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 17 // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 18 // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 19 // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 20 // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 21 // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 22 // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 23 // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 24 // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 25 // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 26 // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 27 28 #ifndef V8_V8_DEBUG_H_ 29 #define V8_V8_DEBUG_H_ 30 31 #include "v8.h" 32 33 /** 34 * Debugger support for the V8 JavaScript engine. 35 */ 36 namespace v8 { 37 38 // Debug events which can occur in the V8 JavaScript engine. 39 enum DebugEvent { 40 Break = 1, 41 Exception = 2, 42 NewFunction = 3, 43 BeforeCompile = 4, 44 AfterCompile = 5, 45 ScriptCollected = 6, 46 BreakForCommand = 7 47 }; 48 49 50 class V8_EXPORT Debug { 51 public: 52 /** 53 * A client object passed to the v8 debugger whose ownership will be taken by 54 * it. v8 is always responsible for deleting the object. 55 */ 56 class ClientData { 57 public: 58 virtual ~ClientData() {} 59 }; 60 61 62 /** 63 * A message object passed to the debug message handler. 64 */ 65 class Message { 66 public: 67 /** 68 * Check type of message. 69 */ 70 virtual bool IsEvent() const = 0; 71 virtual bool IsResponse() const = 0; 72 virtual DebugEvent GetEvent() const = 0; 73 74 /** 75 * Indicate whether this is a response to a continue command which will 76 * start the VM running after this is processed. 77 */ 78 virtual bool WillStartRunning() const = 0; 79 80 /** 81 * Access to execution state and event data. Don't store these cross 82 * callbacks as their content becomes invalid. These objects are from the 83 * debugger event that started the debug message loop. 84 */ 85 virtual Handle<Object> GetExecutionState() const = 0; 86 virtual Handle<Object> GetEventData() const = 0; 87 88 /** 89 * Get the debugger protocol JSON. 90 */ 91 virtual Handle<String> GetJSON() const = 0; 92 93 /** 94 * Get the context active when the debug event happened. Note this is not 95 * the current active context as the JavaScript part of the debugger is 96 * running in its own context which is entered at this point. 97 */ 98 virtual Handle<Context> GetEventContext() const = 0; 99 100 /** 101 * Client data passed with the corresponding request if any. This is the 102 * client_data data value passed into Debug::SendCommand along with the 103 * request that led to the message or NULL if the message is an event. The 104 * debugger takes ownership of the data and will delete it even if there is 105 * no message handler. 106 */ 107 virtual ClientData* GetClientData() const = 0; 108 109 virtual ~Message() {} 110 }; 111 112 113 /** 114 * An event details object passed to the debug event listener. 115 */ 116 class EventDetails { 117 public: 118 /** 119 * Event type. 120 */ 121 virtual DebugEvent GetEvent() const = 0; 122 123 /** 124 * Access to execution state and event data of the debug event. Don't store 125 * these cross callbacks as their content becomes invalid. 126 */ 127 virtual Handle<Object> GetExecutionState() const = 0; 128 virtual Handle<Object> GetEventData() const = 0; 129 130 /** 131 * Get the context active when the debug event happened. Note this is not 132 * the current active context as the JavaScript part of the debugger is 133 * running in its own context which is entered at this point. 134 */ 135 virtual Handle<Context> GetEventContext() const = 0; 136 137 /** 138 * Client data passed with the corresponding callback when it was 139 * registered. 140 */ 141 virtual Handle<Value> GetCallbackData() const = 0; 142 143 /** 144 * Client data passed to DebugBreakForCommand function. The 145 * debugger takes ownership of the data and will delete it even if 146 * there is no message handler. 147 */ 148 virtual ClientData* GetClientData() const = 0; 149 150 virtual ~EventDetails() {} 151 }; 152 153 154 /** 155 * Debug event callback function. 156 * 157 * \param event the type of the debug event that triggered the callback 158 * (enum DebugEvent) 159 * \param exec_state execution state (JavaScript object) 160 * \param event_data event specific data (JavaScript object) 161 * \param data value passed by the user to SetDebugEventListener 162 */ 163 typedef void (*EventCallback)(DebugEvent event, 164 Handle<Object> exec_state, 165 Handle<Object> event_data, 166 Handle<Value> data); 167 168 /** 169 * Debug event callback function. 170 * 171 * \param event_details object providing information about the debug event 172 * 173 * A EventCallback2 does not take possession of the event data, 174 * and must not rely on the data persisting after the handler returns. 175 */ 176 typedef void (*EventCallback2)(const EventDetails& event_details); 177 178 /** 179 * Debug message callback function. 180 * 181 * \param message the debug message handler message object 182 * \param length length of the message 183 * \param client_data the data value passed when registering the message handler 184 185 * A MessageHandler does not take possession of the message string, 186 * and must not rely on the data persisting after the handler returns. 187 * 188 * This message handler is deprecated. Use MessageHandler2 instead. 189 */ 190 typedef void (*MessageHandler)(const uint16_t* message, int length, 191 ClientData* client_data); 192 193 /** 194 * Debug message callback function. 195 * 196 * \param message the debug message handler message object 197 * 198 * A MessageHandler does not take possession of the message data, 199 * and must not rely on the data persisting after the handler returns. 200 */ 201 typedef void (*MessageHandler2)(const Message& message); 202 203 /** 204 * Debug host dispatch callback function. 205 */ 206 typedef void (*HostDispatchHandler)(); 207 208 /** 209 * Callback function for the host to ensure debug messages are processed. 210 */ 211 typedef void (*DebugMessageDispatchHandler)(); 212 213 // Set a C debug event listener. 214 V8_DEPRECATED(static bool SetDebugEventListener( 215 EventCallback that, 216 Handle<Value> data = Handle<Value>())); 217 static bool SetDebugEventListener2(EventCallback2 that, 218 Handle<Value> data = Handle<Value>()); 219 220 // Set a JavaScript debug event listener. 221 static bool SetDebugEventListener(v8::Handle<v8::Object> that, 222 Handle<Value> data = Handle<Value>()); 223 224 // Schedule a debugger break to happen when JavaScript code is run 225 // in the given isolate. If no isolate is provided the default 226 // isolate is used. 227 static void DebugBreak(Isolate* isolate = NULL); 228 229 // Remove scheduled debugger break in given isolate if it has not 230 // happened yet. If no isolate is provided the default isolate is 231 // used. 232 static void CancelDebugBreak(Isolate* isolate = NULL); 233 234 // Break execution of JavaScript in the given isolate (this method 235 // can be invoked from a non-VM thread) for further client command 236 // execution on a VM thread. Client data is then passed in 237 // EventDetails to EventCallback at the moment when the VM actually 238 // stops. If no isolate is provided the default isolate is used. 239 static void DebugBreakForCommand(ClientData* data = NULL, 240 Isolate* isolate = NULL); 241 242 // Message based interface. The message protocol is JSON. NOTE the message 243 // handler thread is not supported any more parameter must be false. 244 V8_DEPRECATED(static void SetMessageHandler( 245 MessageHandler handler, 246 bool message_handler_thread = false)); 247 static void SetMessageHandler2(MessageHandler2 handler); 248 249 // If no isolate is provided the default isolate is 250 // used. 251 static void SendCommand(const uint16_t* command, int length, 252 ClientData* client_data = NULL, 253 Isolate* isolate = NULL); 254 255 // Dispatch interface. 256 static void SetHostDispatchHandler(HostDispatchHandler handler, 257 int period = 100); 258 259 /** 260 * Register a callback function to be called when a debug message has been 261 * received and is ready to be processed. For the debug messages to be 262 * processed V8 needs to be entered, and in certain embedding scenarios this 263 * callback can be used to make sure V8 is entered for the debug message to 264 * be processed. Note that debug messages will only be processed if there is 265 * a V8 break. This can happen automatically by using the option 266 * --debugger-auto-break. 267 * \param provide_locker requires that V8 acquires v8::Locker for you before 268 * calling handler 269 */ 270 static void SetDebugMessageDispatchHandler( 271 DebugMessageDispatchHandler handler, bool provide_locker = false); 272 273 /** 274 * Run a JavaScript function in the debugger. 275 * \param fun the function to call 276 * \param data passed as second argument to the function 277 * With this call the debugger is entered and the function specified is called 278 * with the execution state as the first argument. This makes it possible to 279 * get access to information otherwise not available during normal JavaScript 280 * execution e.g. details on stack frames. Receiver of the function call will 281 * be the debugger context global object, however this is a subject to change. 282 * The following example shows a JavaScript function which when passed to 283 * v8::Debug::Call will return the current line of JavaScript execution. 284 * 285 * \code 286 * function frame_source_line(exec_state) { 287 * return exec_state.frame(0).sourceLine(); 288 * } 289 * \endcode 290 */ 291 static Local<Value> Call(v8::Handle<v8::Function> fun, 292 Handle<Value> data = Handle<Value>()); 293 294 /** 295 * Returns a mirror object for the given object. 296 */ 297 static Local<Value> GetMirror(v8::Handle<v8::Value> obj); 298 299 /** 300 * Enable the V8 builtin debug agent. The debugger agent will listen on the 301 * supplied TCP/IP port for remote debugger connection. 302 * \param name the name of the embedding application 303 * \param port the TCP/IP port to listen on 304 * \param wait_for_connection whether V8 should pause on a first statement 305 * allowing remote debugger to connect before anything interesting happened 306 */ 307 static bool EnableAgent(const char* name, int port, 308 bool wait_for_connection = false); 309 310 /** 311 * Disable the V8 builtin debug agent. The TCP/IP connection will be closed. 312 */ 313 static void DisableAgent(); 314 315 /** 316 * Makes V8 process all pending debug messages. 317 * 318 * From V8 point of view all debug messages come asynchronously (e.g. from 319 * remote debugger) but they all must be handled synchronously: V8 cannot 320 * do 2 things at one time so normal script execution must be interrupted 321 * for a while. 322 * 323 * Generally when message arrives V8 may be in one of 3 states: 324 * 1. V8 is running script; V8 will automatically interrupt and process all 325 * pending messages (however auto_break flag should be enabled); 326 * 2. V8 is suspended on debug breakpoint; in this state V8 is dedicated 327 * to reading and processing debug messages; 328 * 3. V8 is not running at all or has called some long-working C++ function; 329 * by default it means that processing of all debug messages will be deferred 330 * until V8 gets control again; however, embedding application may improve 331 * this by manually calling this method. 332 * 333 * It makes sense to call this method whenever a new debug message arrived and 334 * V8 is not already running. Method v8::Debug::SetDebugMessageDispatchHandler 335 * should help with the former condition. 336 * 337 * Technically this method in many senses is equivalent to executing empty 338 * script: 339 * 1. It does nothing except for processing all pending debug messages. 340 * 2. It should be invoked with the same precautions and from the same context 341 * as V8 script would be invoked from, because: 342 * a. with "evaluate" command it can do whatever normal script can do, 343 * including all native calls; 344 * b. no other thread should call V8 while this method is running 345 * (v8::Locker may be used here). 346 * 347 * "Evaluate" debug command behavior currently is not specified in scope 348 * of this method. 349 */ 350 static void ProcessDebugMessages(); 351 352 /** 353 * Debugger is running in its own context which is entered while debugger 354 * messages are being dispatched. This is an explicit getter for this 355 * debugger context. Note that the content of the debugger context is subject 356 * to change. 357 */ 358 static Local<Context> GetDebugContext(); 359 360 361 /** 362 * Enable/disable LiveEdit functionality for the given Isolate 363 * (default Isolate if not provided). V8 will abort if LiveEdit is 364 * unexpectedly used. LiveEdit is enabled by default. 365 */ 366 static void SetLiveEditEnabled(bool enable, Isolate* isolate = NULL); 367 }; 368 369 370 } // namespace v8 371 372 373 #undef EXPORT 374 375 376 #endif // V8_V8_DEBUG_H_ 377