v8-debug.h revision f87a203d89e1bbb6708282e0b64dbd13d59b723d
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#ifdef _WIN32 34typedef int int32_t; 35typedef unsigned int uint32_t; 36typedef unsigned short uint16_t; // NOLINT 37typedef long long int64_t; // NOLINT 38 39// Setup for Windows DLL export/import. See v8.h in this directory for 40// information on how to build/use V8 as a DLL. 41#if defined(BUILDING_V8_SHARED) && defined(USING_V8_SHARED) 42#error both BUILDING_V8_SHARED and USING_V8_SHARED are set - please check the\ 43 build configuration to ensure that at most one of these is set 44#endif 45 46#ifdef BUILDING_V8_SHARED 47#define EXPORT __declspec(dllexport) 48#elif USING_V8_SHARED 49#define EXPORT __declspec(dllimport) 50#else 51#define EXPORT 52#endif 53 54#else // _WIN32 55 56// Setup for Linux shared library export. See v8.h in this directory for 57// information on how to build/use V8 as shared library. 58#if defined(__GNUC__) && (__GNUC__ >= 4) && defined(V8_SHARED) 59#define EXPORT __attribute__ ((visibility("default"))) 60#else // defined(__GNUC__) && (__GNUC__ >= 4) 61#define EXPORT 62#endif // defined(__GNUC__) && (__GNUC__ >= 4) 63 64#endif // _WIN32 65 66 67/** 68 * Debugger support for the V8 JavaScript engine. 69 */ 70namespace v8 { 71 72// Debug events which can occur in the V8 JavaScript engine. 73enum DebugEvent { 74 Break = 1, 75 Exception = 2, 76 NewFunction = 3, 77 BeforeCompile = 4, 78 AfterCompile = 5, 79 ScriptCollected = 6, 80 BreakForCommand = 7 81}; 82 83 84class EXPORT Debug { 85 public: 86 /** 87 * A client object passed to the v8 debugger whose ownership will be taken by 88 * it. v8 is always responsible for deleting the object. 89 */ 90 class ClientData { 91 public: 92 virtual ~ClientData() {} 93 }; 94 95 96 /** 97 * A message object passed to the debug message handler. 98 */ 99 class Message { 100 public: 101 /** 102 * Check type of message. 103 */ 104 virtual bool IsEvent() const = 0; 105 virtual bool IsResponse() const = 0; 106 virtual DebugEvent GetEvent() const = 0; 107 108 /** 109 * Indicate whether this is a response to a continue command which will 110 * start the VM running after this is processed. 111 */ 112 virtual bool WillStartRunning() const = 0; 113 114 /** 115 * Access to execution state and event data. Don't store these cross 116 * callbacks as their content becomes invalid. These objects are from the 117 * debugger event that started the debug message loop. 118 */ 119 virtual Handle<Object> GetExecutionState() const = 0; 120 virtual Handle<Object> GetEventData() const = 0; 121 122 /** 123 * Get the debugger protocol JSON. 124 */ 125 virtual Handle<String> GetJSON() const = 0; 126 127 /** 128 * Get the context active when the debug event happened. Note this is not 129 * the current active context as the JavaScript part of the debugger is 130 * running in it's own context which is entered at this point. 131 */ 132 virtual Handle<Context> GetEventContext() const = 0; 133 134 /** 135 * Client data passed with the corresponding request if any. This is the 136 * client_data data value passed into Debug::SendCommand along with the 137 * request that led to the message or NULL if the message is an event. The 138 * debugger takes ownership of the data and will delete it even if there is 139 * no message handler. 140 */ 141 virtual ClientData* GetClientData() const = 0; 142 143 virtual ~Message() {} 144 }; 145 146 147 /** 148 * An event details object passed to the debug event listener. 149 */ 150 class EventDetails { 151 public: 152 /** 153 * Event type. 154 */ 155 virtual DebugEvent GetEvent() const = 0; 156 157 /** 158 * Access to execution state and event data of the debug event. Don't store 159 * these cross callbacks as their content becomes invalid. 160 */ 161 virtual Handle<Object> GetExecutionState() const = 0; 162 virtual Handle<Object> GetEventData() const = 0; 163 164 /** 165 * Get the context active when the debug event happened. Note this is not 166 * the current active context as the JavaScript part of the debugger is 167 * running in it's own context which is entered at this point. 168 */ 169 virtual Handle<Context> GetEventContext() const = 0; 170 171 /** 172 * Client data passed with the corresponding callbak whet it was registered. 173 */ 174 virtual Handle<Value> GetCallbackData() const = 0; 175 176 /** 177 * Client data passed to DebugBreakForCommand function. The 178 * debugger takes ownership of the data and will delete it even if 179 * there is no message handler. 180 */ 181 virtual ClientData* GetClientData() const = 0; 182 183 virtual ~EventDetails() {} 184 }; 185 186 187 /** 188 * Debug event callback function. 189 * 190 * \param event the type of the debug event that triggered the callback 191 * (enum DebugEvent) 192 * \param exec_state execution state (JavaScript object) 193 * \param event_data event specific data (JavaScript object) 194 * \param data value passed by the user to SetDebugEventListener 195 */ 196 typedef void (*EventCallback)(DebugEvent event, 197 Handle<Object> exec_state, 198 Handle<Object> event_data, 199 Handle<Value> data); 200 201 /** 202 * Debug event callback function. 203 * 204 * \param event_details object providing information about the debug event 205 * 206 * A EventCallback2 does not take possession of the event data, 207 * and must not rely on the data persisting after the handler returns. 208 */ 209 typedef void (*EventCallback2)(const EventDetails& event_details); 210 211 /** 212 * Debug message callback function. 213 * 214 * \param message the debug message handler message object 215 * \param length length of the message 216 * \param client_data the data value passed when registering the message handler 217 218 * A MessageHandler does not take possession of the message string, 219 * and must not rely on the data persisting after the handler returns. 220 * 221 * This message handler is deprecated. Use MessageHandler2 instead. 222 */ 223 typedef void (*MessageHandler)(const uint16_t* message, int length, 224 ClientData* client_data); 225 226 /** 227 * Debug message callback function. 228 * 229 * \param message the debug message handler message object 230 231 * A MessageHandler does not take possession of the message data, 232 * and must not rely on the data persisting after the handler returns. 233 */ 234 typedef void (*MessageHandler2)(const Message& message); 235 236 /** 237 * Debug host dispatch callback function. 238 */ 239 typedef void (*HostDispatchHandler)(); 240 241 /** 242 * Callback function for the host to ensure debug messages are processed. 243 */ 244 typedef void (*DebugMessageDispatchHandler)(); 245 246 // Set a C debug event listener. 247 static bool SetDebugEventListener(EventCallback that, 248 Handle<Value> data = Handle<Value>()); 249 static bool SetDebugEventListener2(EventCallback2 that, 250 Handle<Value> data = Handle<Value>()); 251 252 // Set a JavaScript debug event listener. 253 static bool SetDebugEventListener(v8::Handle<v8::Object> that, 254 Handle<Value> data = Handle<Value>()); 255 256 // Schedule a debugger break to happen when JavaScript code is run. 257 static void DebugBreak(); 258 259 // Remove scheduled debugger break if it has not happened yet. 260 static void CancelDebugBreak(); 261 262 // Break execution of JavaScript (this method can be invoked from a 263 // non-VM thread) for further client command execution on a VM 264 // thread. Client data is then passed in EventDetails to 265 // EventCallback at the moment when the VM actually stops. 266 static void DebugBreakForCommand(ClientData* data = NULL); 267 268 // Message based interface. The message protocol is JSON. NOTE the message 269 // handler thread is not supported any more parameter must be false. 270 static void SetMessageHandler(MessageHandler handler, 271 bool message_handler_thread = false); 272 static void SetMessageHandler2(MessageHandler2 handler); 273 static void SendCommand(const uint16_t* command, int length, 274 ClientData* client_data = NULL); 275 276 // Dispatch interface. 277 static void SetHostDispatchHandler(HostDispatchHandler handler, 278 int period = 100); 279 280 /** 281 * Register a callback function to be called when a debug message has been 282 * received and is ready to be processed. For the debug messages to be 283 * processed V8 needs to be entered, and in certain embedding scenarios this 284 * callback can be used to make sure V8 is entered for the debug message to 285 * be processed. Note that debug messages will only be processed if there is 286 * a V8 break. This can happen automatically by using the option 287 * --debugger-auto-break. 288 * \param provide_locker requires that V8 acquires v8::Locker for you before 289 * calling handler 290 */ 291 static void SetDebugMessageDispatchHandler( 292 DebugMessageDispatchHandler handler, bool provide_locker = false); 293 294 /** 295 * Run a JavaScript function in the debugger. 296 * \param fun the function to call 297 * \param data passed as second argument to the function 298 * With this call the debugger is entered and the function specified is called 299 * with the execution state as the first argument. This makes it possible to 300 * get access to information otherwise not available during normal JavaScript 301 * execution e.g. details on stack frames. Receiver of the function call will 302 * be the debugger context global object, however this is a subject to change. 303 * The following example show a JavaScript function which when passed to 304 * v8::Debug::Call will return the current line of JavaScript execution. 305 * 306 * \code 307 * function frame_source_line(exec_state) { 308 * return exec_state.frame(0).sourceLine(); 309 * } 310 * \endcode 311 */ 312 static Local<Value> Call(v8::Handle<v8::Function> fun, 313 Handle<Value> data = Handle<Value>()); 314 315 /** 316 * Returns a mirror object for the given object. 317 */ 318 static Local<Value> GetMirror(v8::Handle<v8::Value> obj); 319 320 /** 321 * Enable the V8 builtin debug agent. The debugger agent will listen on the 322 * supplied TCP/IP port for remote debugger connection. 323 * \param name the name of the embedding application 324 * \param port the TCP/IP port to listen on 325 * \param wait_for_connection whether V8 should pause on a first statement 326 * allowing remote debugger to connect before anything interesting happened 327 */ 328 static bool EnableAgent(const char* name, int port, 329 bool wait_for_connection = false); 330 331 /** 332 * Makes V8 process all pending debug messages. 333 * 334 * From V8 point of view all debug messages come asynchronously (e.g. from 335 * remote debugger) but they all must be handled synchronously: V8 cannot 336 * do 2 things at one time so normal script execution must be interrupted 337 * for a while. 338 * 339 * Generally when message arrives V8 may be in one of 3 states: 340 * 1. V8 is running script; V8 will automatically interrupt and process all 341 * pending messages (however auto_break flag should be enabled); 342 * 2. V8 is suspended on debug breakpoint; in this state V8 is dedicated 343 * to reading and processing debug messages; 344 * 3. V8 is not running at all or has called some long-working C++ function; 345 * by default it means that processing of all debug message will be deferred 346 * until V8 gets control again; however, embedding application may improve 347 * this by manually calling this method. 348 * 349 * It makes sense to call this method whenever a new debug message arrived and 350 * V8 is not already running. Method v8::Debug::SetDebugMessageDispatchHandler 351 * should help with the former condition. 352 * 353 * Technically this method in many senses is equivalent to executing empty 354 * script: 355 * 1. It does nothing except for processing all pending debug messages. 356 * 2. It should be invoked with the same precautions and from the same context 357 * as V8 script would be invoked from, because: 358 * a. with "evaluate" command it can do whatever normal script can do, 359 * including all native calls; 360 * b. no other thread should call V8 while this method is running 361 * (v8::Locker may be used here). 362 * 363 * "Evaluate" debug command behavior currently is not specified in scope 364 * of this method. 365 */ 366 static void ProcessDebugMessages(); 367 368 /** 369 * Debugger is running in it's own context which is entered while debugger 370 * messages are being dispatched. This is an explicit getter for this 371 * debugger context. Note that the content of the debugger context is subject 372 * to change. 373 */ 374 static Local<Context> GetDebugContext(); 375}; 376 377 378} // namespace v8 379 380 381#undef EXPORT 382 383 384#endif // V8_V8_DEBUG_H_ 385