1 // Copyright 2012 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_DEBUG_H_ 29 #define V8_DEBUG_H_ 30 31 #include "allocation.h" 32 #include "arguments.h" 33 #include "assembler.h" 34 #include "debug-agent.h" 35 #include "execution.h" 36 #include "factory.h" 37 #include "flags.h" 38 #include "frames-inl.h" 39 #include "hashmap.h" 40 #include "platform.h" 41 #include "platform/socket.h" 42 #include "string-stream.h" 43 #include "v8threads.h" 44 45 #ifdef ENABLE_DEBUGGER_SUPPORT 46 #include "../include/v8-debug.h" 47 48 namespace v8 { 49 namespace internal { 50 51 52 // Forward declarations. 53 class EnterDebugger; 54 55 56 // Step actions. NOTE: These values are in macros.py as well. 57 enum StepAction { 58 StepNone = -1, // Stepping not prepared. 59 StepOut = 0, // Step out of the current function. 60 StepNext = 1, // Step to the next statement in the current function. 61 StepIn = 2, // Step into new functions invoked or the next statement 62 // in the current function. 63 StepMin = 3, // Perform a minimum step in the current function. 64 StepInMin = 4 // Step into new functions invoked or perform a minimum step 65 // in the current function. 66 }; 67 68 69 // Type of exception break. NOTE: These values are in macros.py as well. 70 enum ExceptionBreakType { 71 BreakException = 0, 72 BreakUncaughtException = 1 73 }; 74 75 76 // Type of exception break. NOTE: These values are in macros.py as well. 77 enum BreakLocatorType { 78 ALL_BREAK_LOCATIONS = 0, 79 SOURCE_BREAK_LOCATIONS = 1 80 }; 81 82 83 // The different types of breakpoint position alignments. 84 // Must match Debug.BreakPositionAlignment in debug-debugger.js 85 enum BreakPositionAlignment { 86 STATEMENT_ALIGNED = 0, 87 BREAK_POSITION_ALIGNED = 1 88 }; 89 90 91 // Class for iterating through the break points in a function and changing 92 // them. 93 class BreakLocationIterator { 94 public: 95 explicit BreakLocationIterator(Handle<DebugInfo> debug_info, 96 BreakLocatorType type); 97 virtual ~BreakLocationIterator(); 98 99 void Next(); 100 void Next(int count); 101 void FindBreakLocationFromAddress(Address pc); 102 void FindBreakLocationFromPosition(int position, 103 BreakPositionAlignment alignment); 104 void Reset(); 105 bool Done() const; 106 void SetBreakPoint(Handle<Object> break_point_object); 107 void ClearBreakPoint(Handle<Object> break_point_object); 108 void SetOneShot(); 109 void ClearOneShot(); 110 bool IsStepInLocation(Isolate* isolate); 111 void PrepareStepIn(Isolate* isolate); 112 bool IsExit() const; 113 bool HasBreakPoint(); 114 bool IsDebugBreak(); 115 Object* BreakPointObjects(); 116 void ClearAllDebugBreak(); 117 118 119 inline int code_position() { 120 return static_cast<int>(pc() - debug_info_->code()->entry()); 121 } 122 inline int break_point() { return break_point_; } 123 inline int position() { return position_; } 124 inline int statement_position() { return statement_position_; } 125 inline Address pc() { return reloc_iterator_->rinfo()->pc(); } 126 inline Code* code() { return debug_info_->code(); } 127 inline RelocInfo* rinfo() { return reloc_iterator_->rinfo(); } 128 inline RelocInfo::Mode rmode() const { 129 return reloc_iterator_->rinfo()->rmode(); 130 } 131 inline RelocInfo* original_rinfo() { 132 return reloc_iterator_original_->rinfo(); 133 } 134 inline RelocInfo::Mode original_rmode() const { 135 return reloc_iterator_original_->rinfo()->rmode(); 136 } 137 138 bool IsDebuggerStatement(); 139 140 protected: 141 bool RinfoDone() const; 142 void RinfoNext(); 143 144 BreakLocatorType type_; 145 int break_point_; 146 int position_; 147 int statement_position_; 148 Handle<DebugInfo> debug_info_; 149 RelocIterator* reloc_iterator_; 150 RelocIterator* reloc_iterator_original_; 151 152 private: 153 void SetDebugBreak(); 154 void ClearDebugBreak(); 155 156 void SetDebugBreakAtIC(); 157 void ClearDebugBreakAtIC(); 158 159 bool IsDebugBreakAtReturn(); 160 void SetDebugBreakAtReturn(); 161 void ClearDebugBreakAtReturn(); 162 163 bool IsDebugBreakSlot(); 164 bool IsDebugBreakAtSlot(); 165 void SetDebugBreakAtSlot(); 166 void ClearDebugBreakAtSlot(); 167 168 DISALLOW_COPY_AND_ASSIGN(BreakLocationIterator); 169 }; 170 171 172 // Cache of all script objects in the heap. When a script is added a weak handle 173 // to it is created and that weak handle is stored in the cache. The weak handle 174 // callback takes care of removing the script from the cache. The key used in 175 // the cache is the script id. 176 class ScriptCache : private HashMap { 177 public: 178 explicit ScriptCache(Isolate* isolate) 179 : HashMap(ScriptMatch), isolate_(isolate), collected_scripts_(10) {} 180 virtual ~ScriptCache() { Clear(); } 181 182 // Add script to the cache. 183 void Add(Handle<Script> script); 184 185 // Return the scripts in the cache. 186 Handle<FixedArray> GetScripts(); 187 188 // Generate debugger events for collected scripts. 189 void ProcessCollectedScripts(); 190 191 private: 192 // Calculate the hash value from the key (script id). 193 static uint32_t Hash(int key) { 194 return ComputeIntegerHash(key, v8::internal::kZeroHashSeed); 195 } 196 197 // Scripts match if their keys (script id) match. 198 static bool ScriptMatch(void* key1, void* key2) { return key1 == key2; } 199 200 // Clear the cache releasing all the weak handles. 201 void Clear(); 202 203 // Weak handle callback for scripts in the cache. 204 static void HandleWeakScript(v8::Isolate* isolate, 205 v8::Persistent<v8::Value>* obj, 206 void* data); 207 208 Isolate* isolate_; 209 // List used during GC to temporarily store id's of collected scripts. 210 List<int> collected_scripts_; 211 }; 212 213 214 // Linked list holding debug info objects. The debug info objects are kept as 215 // weak handles to avoid a debug info object to keep a function alive. 216 class DebugInfoListNode { 217 public: 218 explicit DebugInfoListNode(DebugInfo* debug_info); 219 virtual ~DebugInfoListNode(); 220 221 DebugInfoListNode* next() { return next_; } 222 void set_next(DebugInfoListNode* next) { next_ = next; } 223 Handle<DebugInfo> debug_info() { return debug_info_; } 224 225 private: 226 // Global (weak) handle to the debug info object. 227 Handle<DebugInfo> debug_info_; 228 229 // Next pointer for linked list. 230 DebugInfoListNode* next_; 231 }; 232 233 // This class contains the debugger support. The main purpose is to handle 234 // setting break points in the code. 235 // 236 // This class controls the debug info for all functions which currently have 237 // active breakpoints in them. This debug info is held in the heap root object 238 // debug_info which is a FixedArray. Each entry in this list is of class 239 // DebugInfo. 240 class Debug { 241 public: 242 void SetUp(bool create_heap_objects); 243 bool Load(); 244 void Unload(); 245 bool IsLoaded() { return !debug_context_.is_null(); } 246 bool InDebugger() { return thread_local_.debugger_entry_ != NULL; } 247 void PreemptionWhileInDebugger(); 248 void Iterate(ObjectVisitor* v); 249 250 Object* Break(Arguments args); 251 void SetBreakPoint(Handle<JSFunction> function, 252 Handle<Object> break_point_object, 253 int* source_position); 254 bool SetBreakPointForScript(Handle<Script> script, 255 Handle<Object> break_point_object, 256 int* source_position, 257 BreakPositionAlignment alignment); 258 void ClearBreakPoint(Handle<Object> break_point_object); 259 void ClearAllBreakPoints(); 260 void FloodWithOneShot(Handle<JSFunction> function); 261 void FloodBoundFunctionWithOneShot(Handle<JSFunction> function); 262 void FloodHandlerWithOneShot(); 263 void ChangeBreakOnException(ExceptionBreakType type, bool enable); 264 bool IsBreakOnException(ExceptionBreakType type); 265 void PrepareStep(StepAction step_action, 266 int step_count, 267 StackFrame::Id frame_id); 268 void ClearStepping(); 269 void ClearStepOut(); 270 bool IsStepping() { return thread_local_.step_count_ > 0; } 271 bool StepNextContinue(BreakLocationIterator* break_location_iterator, 272 JavaScriptFrame* frame); 273 static Handle<DebugInfo> GetDebugInfo(Handle<SharedFunctionInfo> shared); 274 static bool HasDebugInfo(Handle<SharedFunctionInfo> shared); 275 276 void PrepareForBreakPoints(); 277 278 // This function is used in FunctionNameUsing* tests. 279 Object* FindSharedFunctionInfoInScript(Handle<Script> script, int position); 280 281 // Returns whether the operation succeeded. Compilation can only be triggered 282 // if a valid closure is passed as the second argument, otherwise the shared 283 // function needs to be compiled already. 284 bool EnsureDebugInfo(Handle<SharedFunctionInfo> shared, 285 Handle<JSFunction> function); 286 287 // Returns true if the current stub call is patched to call the debugger. 288 static bool IsDebugBreak(Address addr); 289 // Returns true if the current return statement has been patched to be 290 // a debugger breakpoint. 291 static bool IsDebugBreakAtReturn(RelocInfo* rinfo); 292 293 // Check whether a code stub with the specified major key is a possible break 294 // point location. 295 static bool IsSourceBreakStub(Code* code); 296 static bool IsBreakStub(Code* code); 297 298 // Find the builtin to use for invoking the debug break 299 static Handle<Code> FindDebugBreak(Handle<Code> code, RelocInfo::Mode mode); 300 301 static Handle<Object> GetSourceBreakLocations( 302 Handle<SharedFunctionInfo> shared, 303 BreakPositionAlignment position_aligment); 304 305 // Getter for the debug_context. 306 inline Handle<Context> debug_context() { return debug_context_; } 307 308 // Check whether a global object is the debug global object. 309 bool IsDebugGlobal(GlobalObject* global); 310 311 // Check whether this frame is just about to return. 312 bool IsBreakAtReturn(JavaScriptFrame* frame); 313 314 // Fast check to see if any break points are active. 315 inline bool has_break_points() { return has_break_points_; } 316 317 void NewBreak(StackFrame::Id break_frame_id); 318 void SetBreak(StackFrame::Id break_frame_id, int break_id); 319 StackFrame::Id break_frame_id() { 320 return thread_local_.break_frame_id_; 321 } 322 int break_id() { return thread_local_.break_id_; } 323 324 bool StepInActive() { return thread_local_.step_into_fp_ != 0; } 325 void HandleStepIn(Handle<JSFunction> function, 326 Handle<Object> holder, 327 Address fp, 328 bool is_constructor); 329 Address step_in_fp() { return thread_local_.step_into_fp_; } 330 Address* step_in_fp_addr() { return &thread_local_.step_into_fp_; } 331 332 bool StepOutActive() { return thread_local_.step_out_fp_ != 0; } 333 Address step_out_fp() { return thread_local_.step_out_fp_; } 334 335 EnterDebugger* debugger_entry() { 336 return thread_local_.debugger_entry_; 337 } 338 void set_debugger_entry(EnterDebugger* entry) { 339 thread_local_.debugger_entry_ = entry; 340 } 341 342 // Check whether any of the specified interrupts are pending. 343 bool is_interrupt_pending(InterruptFlag what) { 344 return (thread_local_.pending_interrupts_ & what) != 0; 345 } 346 347 // Set specified interrupts as pending. 348 void set_interrupts_pending(InterruptFlag what) { 349 thread_local_.pending_interrupts_ |= what; 350 } 351 352 // Clear specified interrupts from pending. 353 void clear_interrupt_pending(InterruptFlag what) { 354 thread_local_.pending_interrupts_ &= ~static_cast<int>(what); 355 } 356 357 // Getter and setter for the disable break state. 358 bool disable_break() { return disable_break_; } 359 void set_disable_break(bool disable_break) { 360 disable_break_ = disable_break; 361 } 362 363 // Getters for the current exception break state. 364 bool break_on_exception() { return break_on_exception_; } 365 bool break_on_uncaught_exception() { 366 return break_on_uncaught_exception_; 367 } 368 369 enum AddressId { 370 k_after_break_target_address, 371 k_debug_break_return_address, 372 k_debug_break_slot_address, 373 k_restarter_frame_function_pointer 374 }; 375 376 // Support for setting the address to jump to when returning from break point. 377 Address* after_break_target_address() { 378 return reinterpret_cast<Address*>(&thread_local_.after_break_target_); 379 } 380 Address* restarter_frame_function_pointer_address() { 381 Object*** address = &thread_local_.restarter_frame_function_pointer_; 382 return reinterpret_cast<Address*>(address); 383 } 384 385 // Support for saving/restoring registers when handling debug break calls. 386 Object** register_address(int r) { 387 return ®isters_[r]; 388 } 389 390 // Access to the debug break on return code. 391 Code* debug_break_return() { return debug_break_return_; } 392 Code** debug_break_return_address() { 393 return &debug_break_return_; 394 } 395 396 // Access to the debug break in debug break slot code. 397 Code* debug_break_slot() { return debug_break_slot_; } 398 Code** debug_break_slot_address() { 399 return &debug_break_slot_; 400 } 401 402 static const int kEstimatedNofDebugInfoEntries = 16; 403 static const int kEstimatedNofBreakPointsInFunction = 16; 404 405 // Passed to MakeWeak. 406 static void HandleWeakDebugInfo(v8::Isolate* isolate, 407 v8::Persistent<v8::Value>* obj, 408 void* data); 409 410 friend class Debugger; 411 friend Handle<FixedArray> GetDebuggedFunctions(); // In test-debug.cc 412 friend void CheckDebuggerUnloaded(bool check_functions); // In test-debug.cc 413 414 // Threading support. 415 char* ArchiveDebug(char* to); 416 char* RestoreDebug(char* from); 417 static int ArchiveSpacePerThread(); 418 void FreeThreadResources() { } 419 420 // Mirror cache handling. 421 void ClearMirrorCache(); 422 423 // Script cache handling. 424 void CreateScriptCache(); 425 void DestroyScriptCache(); 426 void AddScriptToScriptCache(Handle<Script> script); 427 Handle<FixedArray> GetLoadedScripts(); 428 429 // Garbage collection notifications. 430 void AfterGarbageCollection(); 431 432 // Code generator routines. 433 static void GenerateSlot(MacroAssembler* masm); 434 static void GenerateLoadICDebugBreak(MacroAssembler* masm); 435 static void GenerateStoreICDebugBreak(MacroAssembler* masm); 436 static void GenerateKeyedLoadICDebugBreak(MacroAssembler* masm); 437 static void GenerateKeyedStoreICDebugBreak(MacroAssembler* masm); 438 static void GenerateCompareNilICDebugBreak(MacroAssembler* masm); 439 static void GenerateReturnDebugBreak(MacroAssembler* masm); 440 static void GenerateCallFunctionStubDebugBreak(MacroAssembler* masm); 441 static void GenerateCallFunctionStubRecordDebugBreak(MacroAssembler* masm); 442 static void GenerateCallConstructStubDebugBreak(MacroAssembler* masm); 443 static void GenerateCallConstructStubRecordDebugBreak(MacroAssembler* masm); 444 static void GenerateSlotDebugBreak(MacroAssembler* masm); 445 static void GeneratePlainReturnLiveEdit(MacroAssembler* masm); 446 447 // FrameDropper is a code replacement for a JavaScript frame with possibly 448 // several frames above. 449 // There is no calling conventions here, because it never actually gets 450 // called, it only gets returned to. 451 static void GenerateFrameDropperLiveEdit(MacroAssembler* masm); 452 453 // Called from stub-cache.cc. 454 static void GenerateCallICDebugBreak(MacroAssembler* masm); 455 456 // Describes how exactly a frame has been dropped from stack. 457 enum FrameDropMode { 458 // No frame has been dropped. 459 FRAMES_UNTOUCHED, 460 // The top JS frame had been calling IC stub. IC stub mustn't be called now. 461 FRAME_DROPPED_IN_IC_CALL, 462 // The top JS frame had been calling debug break slot stub. Patch the 463 // address this stub jumps to in the end. 464 FRAME_DROPPED_IN_DEBUG_SLOT_CALL, 465 // The top JS frame had been calling some C++ function. The return address 466 // gets patched automatically. 467 FRAME_DROPPED_IN_DIRECT_CALL, 468 FRAME_DROPPED_IN_RETURN_CALL, 469 CURRENTLY_SET_MODE 470 }; 471 472 void FramesHaveBeenDropped(StackFrame::Id new_break_frame_id, 473 FrameDropMode mode, 474 Object** restarter_frame_function_pointer); 475 476 // Initializes an artificial stack frame. The data it contains is used for: 477 // a. successful work of frame dropper code which eventually gets control, 478 // b. being compatible with regular stack structure for various stack 479 // iterators. 480 // Returns address of stack allocated pointer to restarted function, 481 // the value that is called 'restarter_frame_function_pointer'. The value 482 // at this address (possibly updated by GC) may be used later when preparing 483 // 'step in' operation. 484 static Object** SetUpFrameDropperFrame(StackFrame* bottom_js_frame, 485 Handle<Code> code); 486 487 static const int kFrameDropperFrameSize; 488 489 // Architecture-specific constant. 490 static const bool kFrameDropperSupported; 491 492 /** 493 * Defines layout of a stack frame that supports padding. This is a regular 494 * internal frame that has a flexible stack structure. LiveEdit can shift 495 * its lower part up the stack, taking up the 'padding' space when additional 496 * stack memory is required. 497 * Such frame is expected immediately above the topmost JavaScript frame. 498 * 499 * Stack Layout: 500 * --- Top 501 * LiveEdit routine frames 502 * --- 503 * C frames of debug handler 504 * --- 505 * ... 506 * --- 507 * An internal frame that has n padding words: 508 * - any number of words as needed by code -- upper part of frame 509 * - padding size: a Smi storing n -- current size of padding 510 * - padding: n words filled with kPaddingValue in form of Smi 511 * - 3 context/type words of a regular InternalFrame 512 * - fp 513 * --- 514 * Topmost JavaScript frame 515 * --- 516 * ... 517 * --- Bottom 518 */ 519 class FramePaddingLayout : public AllStatic { 520 public: 521 // Architecture-specific constant. 522 static const bool kIsSupported; 523 524 // A size of frame base including fp. Padding words starts right above 525 // the base. 526 static const int kFrameBaseSize = 4; 527 528 // A number of words that should be reserved on stack for the LiveEdit use. 529 // Normally equals 1. Stored on stack in form of Smi. 530 static const int kInitialSize; 531 // A value that padding words are filled with (in form of Smi). Going 532 // bottom-top, the first word not having this value is a counter word. 533 static const int kPaddingValue; 534 }; 535 536 private: 537 explicit Debug(Isolate* isolate); 538 ~Debug(); 539 540 static bool CompileDebuggerScript(Isolate* isolate, int index); 541 void ClearOneShot(); 542 void ActivateStepIn(StackFrame* frame); 543 void ClearStepIn(); 544 void ActivateStepOut(StackFrame* frame); 545 void ClearStepNext(); 546 // Returns whether the compile succeeded. 547 void RemoveDebugInfo(Handle<DebugInfo> debug_info); 548 void SetAfterBreakTarget(JavaScriptFrame* frame); 549 Handle<Object> CheckBreakPoints(Handle<Object> break_point); 550 bool CheckBreakPoint(Handle<Object> break_point_object); 551 552 // Global handle to debug context where all the debugger JavaScript code is 553 // loaded. 554 Handle<Context> debug_context_; 555 556 // Boolean state indicating whether any break points are set. 557 bool has_break_points_; 558 559 // Cache of all scripts in the heap. 560 ScriptCache* script_cache_; 561 562 // List of active debug info objects. 563 DebugInfoListNode* debug_info_list_; 564 565 bool disable_break_; 566 bool break_on_exception_; 567 bool break_on_uncaught_exception_; 568 569 // Per-thread data. 570 class ThreadLocal { 571 public: 572 // Counter for generating next break id. 573 int break_count_; 574 575 // Current break id. 576 int break_id_; 577 578 // Frame id for the frame of the current break. 579 StackFrame::Id break_frame_id_; 580 581 // Step action for last step performed. 582 StepAction last_step_action_; 583 584 // Source statement position from last step next action. 585 int last_statement_position_; 586 587 // Number of steps left to perform before debug event. 588 int step_count_; 589 590 // Frame pointer from last step next action. 591 Address last_fp_; 592 593 // Number of queued steps left to perform before debug event. 594 int queued_step_count_; 595 596 // Frame pointer for frame from which step in was performed. 597 Address step_into_fp_; 598 599 // Frame pointer for the frame where debugger should be called when current 600 // step out action is completed. 601 Address step_out_fp_; 602 603 // Storage location for jump when exiting debug break calls. 604 Address after_break_target_; 605 606 // Stores the way how LiveEdit has patched the stack. It is used when 607 // debugger returns control back to user script. 608 FrameDropMode frame_drop_mode_; 609 610 // Top debugger entry. 611 EnterDebugger* debugger_entry_; 612 613 // Pending interrupts scheduled while debugging. 614 int pending_interrupts_; 615 616 // When restarter frame is on stack, stores the address 617 // of the pointer to function being restarted. Otherwise (most of the time) 618 // stores NULL. This pointer is used with 'step in' implementation. 619 Object** restarter_frame_function_pointer_; 620 }; 621 622 // Storage location for registers when handling debug break calls 623 JSCallerSavedBuffer registers_; 624 ThreadLocal thread_local_; 625 void ThreadInit(); 626 627 // Code to call for handling debug break on return. 628 Code* debug_break_return_; 629 630 // Code to call for handling debug break in debug break slots. 631 Code* debug_break_slot_; 632 633 Isolate* isolate_; 634 635 friend class Isolate; 636 637 DISALLOW_COPY_AND_ASSIGN(Debug); 638 }; 639 640 641 DECLARE_RUNTIME_FUNCTION(Object*, Debug_Break); 642 643 644 // Message delivered to the message handler callback. This is either a debugger 645 // event or the response to a command. 646 class MessageImpl: public v8::Debug::Message { 647 public: 648 // Create a message object for a debug event. 649 static MessageImpl NewEvent(DebugEvent event, 650 bool running, 651 Handle<JSObject> exec_state, 652 Handle<JSObject> event_data); 653 654 // Create a message object for the response to a debug command. 655 static MessageImpl NewResponse(DebugEvent event, 656 bool running, 657 Handle<JSObject> exec_state, 658 Handle<JSObject> event_data, 659 Handle<String> response_json, 660 v8::Debug::ClientData* client_data); 661 662 // Implementation of interface v8::Debug::Message. 663 virtual bool IsEvent() const; 664 virtual bool IsResponse() const; 665 virtual DebugEvent GetEvent() const; 666 virtual bool WillStartRunning() const; 667 virtual v8::Handle<v8::Object> GetExecutionState() const; 668 virtual v8::Handle<v8::Object> GetEventData() const; 669 virtual v8::Handle<v8::String> GetJSON() const; 670 virtual v8::Handle<v8::Context> GetEventContext() const; 671 virtual v8::Debug::ClientData* GetClientData() const; 672 virtual v8::Isolate* GetIsolate() const; 673 674 private: 675 MessageImpl(bool is_event, 676 DebugEvent event, 677 bool running, 678 Handle<JSObject> exec_state, 679 Handle<JSObject> event_data, 680 Handle<String> response_json, 681 v8::Debug::ClientData* client_data); 682 683 bool is_event_; // Does this message represent a debug event? 684 DebugEvent event_; // Debug event causing the break. 685 bool running_; // Will the VM start running after this event? 686 Handle<JSObject> exec_state_; // Current execution state. 687 Handle<JSObject> event_data_; // Data associated with the event. 688 Handle<String> response_json_; // Response JSON if message holds a response. 689 v8::Debug::ClientData* client_data_; // Client data passed with the request. 690 }; 691 692 693 // Details of the debug event delivered to the debug event listener. 694 class EventDetailsImpl : public v8::Debug::EventDetails { 695 public: 696 EventDetailsImpl(DebugEvent event, 697 Handle<JSObject> exec_state, 698 Handle<JSObject> event_data, 699 Handle<Object> callback_data, 700 v8::Debug::ClientData* client_data); 701 virtual DebugEvent GetEvent() const; 702 virtual v8::Handle<v8::Object> GetExecutionState() const; 703 virtual v8::Handle<v8::Object> GetEventData() const; 704 virtual v8::Handle<v8::Context> GetEventContext() const; 705 virtual v8::Handle<v8::Value> GetCallbackData() const; 706 virtual v8::Debug::ClientData* GetClientData() const; 707 private: 708 DebugEvent event_; // Debug event causing the break. 709 Handle<JSObject> exec_state_; // Current execution state. 710 Handle<JSObject> event_data_; // Data associated with the event. 711 Handle<Object> callback_data_; // User data passed with the callback 712 // when it was registered. 713 v8::Debug::ClientData* client_data_; // Data passed to DebugBreakForCommand. 714 }; 715 716 717 // Message send by user to v8 debugger or debugger output message. 718 // In addition to command text it may contain a pointer to some user data 719 // which are expected to be passed along with the command reponse to message 720 // handler. 721 class CommandMessage { 722 public: 723 static CommandMessage New(const Vector<uint16_t>& command, 724 v8::Debug::ClientData* data); 725 CommandMessage(); 726 ~CommandMessage(); 727 728 // Deletes user data and disposes of the text. 729 void Dispose(); 730 Vector<uint16_t> text() const { return text_; } 731 v8::Debug::ClientData* client_data() const { return client_data_; } 732 private: 733 CommandMessage(const Vector<uint16_t>& text, 734 v8::Debug::ClientData* data); 735 736 Vector<uint16_t> text_; 737 v8::Debug::ClientData* client_data_; 738 }; 739 740 // A Queue of CommandMessage objects. A thread-safe version is 741 // LockingCommandMessageQueue, based on this class. 742 class CommandMessageQueue BASE_EMBEDDED { 743 public: 744 explicit CommandMessageQueue(int size); 745 ~CommandMessageQueue(); 746 bool IsEmpty() const { return start_ == end_; } 747 CommandMessage Get(); 748 void Put(const CommandMessage& message); 749 void Clear() { start_ = end_ = 0; } // Queue is empty after Clear(). 750 private: 751 // Doubles the size of the message queue, and copies the messages. 752 void Expand(); 753 754 CommandMessage* messages_; 755 int start_; 756 int end_; 757 int size_; // The size of the queue buffer. Queue can hold size-1 messages. 758 }; 759 760 761 class MessageDispatchHelperThread; 762 763 764 // LockingCommandMessageQueue is a thread-safe circular buffer of CommandMessage 765 // messages. The message data is not managed by LockingCommandMessageQueue. 766 // Pointers to the data are passed in and out. Implemented by adding a 767 // Mutex to CommandMessageQueue. Includes logging of all puts and gets. 768 class LockingCommandMessageQueue BASE_EMBEDDED { 769 public: 770 LockingCommandMessageQueue(Logger* logger, int size); 771 bool IsEmpty() const; 772 CommandMessage Get(); 773 void Put(const CommandMessage& message); 774 void Clear(); 775 private: 776 Logger* logger_; 777 CommandMessageQueue queue_; 778 mutable Mutex mutex_; 779 DISALLOW_COPY_AND_ASSIGN(LockingCommandMessageQueue); 780 }; 781 782 783 class Debugger { 784 public: 785 ~Debugger(); 786 787 void DebugRequest(const uint16_t* json_request, int length); 788 789 Handle<Object> MakeJSObject(Vector<const char> constructor_name, 790 int argc, 791 Handle<Object> argv[], 792 bool* caught_exception); 793 Handle<Object> MakeExecutionState(bool* caught_exception); 794 Handle<Object> MakeBreakEvent(Handle<Object> exec_state, 795 Handle<Object> break_points_hit, 796 bool* caught_exception); 797 Handle<Object> MakeExceptionEvent(Handle<Object> exec_state, 798 Handle<Object> exception, 799 bool uncaught, 800 bool* caught_exception); 801 Handle<Object> MakeNewFunctionEvent(Handle<Object> func, 802 bool* caught_exception); 803 Handle<Object> MakeCompileEvent(Handle<Script> script, 804 bool before, 805 bool* caught_exception); 806 Handle<Object> MakeScriptCollectedEvent(int id, 807 bool* caught_exception); 808 void OnDebugBreak(Handle<Object> break_points_hit, bool auto_continue); 809 void OnException(Handle<Object> exception, bool uncaught); 810 void OnBeforeCompile(Handle<Script> script); 811 812 enum AfterCompileFlags { 813 NO_AFTER_COMPILE_FLAGS, 814 SEND_WHEN_DEBUGGING 815 }; 816 void OnAfterCompile(Handle<Script> script, 817 AfterCompileFlags after_compile_flags); 818 void OnScriptCollected(int id); 819 void ProcessDebugEvent(v8::DebugEvent event, 820 Handle<JSObject> event_data, 821 bool auto_continue); 822 void NotifyMessageHandler(v8::DebugEvent event, 823 Handle<JSObject> exec_state, 824 Handle<JSObject> event_data, 825 bool auto_continue); 826 void SetEventListener(Handle<Object> callback, Handle<Object> data); 827 void SetMessageHandler(v8::Debug::MessageHandler2 handler); 828 void SetHostDispatchHandler(v8::Debug::HostDispatchHandler handler, 829 TimeDelta period); 830 void SetDebugMessageDispatchHandler( 831 v8::Debug::DebugMessageDispatchHandler handler, 832 bool provide_locker); 833 834 // Invoke the message handler function. 835 void InvokeMessageHandler(MessageImpl message); 836 837 // Add a debugger command to the command queue. 838 void ProcessCommand(Vector<const uint16_t> command, 839 v8::Debug::ClientData* client_data = NULL); 840 841 // Check whether there are commands in the command queue. 842 bool HasCommands(); 843 844 // Enqueue a debugger command to the command queue for event listeners. 845 void EnqueueDebugCommand(v8::Debug::ClientData* client_data = NULL); 846 847 Handle<Object> Call(Handle<JSFunction> fun, 848 Handle<Object> data, 849 bool* pending_exception); 850 851 // Start the debugger agent listening on the provided port. 852 bool StartAgent(const char* name, int port, 853 bool wait_for_connection = false); 854 855 // Stop the debugger agent. 856 void StopAgent(); 857 858 // Blocks until the agent has started listening for connections 859 void WaitForAgent(); 860 861 void CallMessageDispatchHandler(); 862 863 Handle<Context> GetDebugContext(); 864 865 // Unload the debugger if possible. Only called when no debugger is currently 866 // active. 867 void UnloadDebugger(); 868 friend void ForceUnloadDebugger(); // In test-debug.cc 869 870 inline bool EventActive(v8::DebugEvent event) { 871 LockGuard<RecursiveMutex> lock_guard(debugger_access_); 872 873 // Check whether the message handler was been cleared. 874 if (debugger_unload_pending_) { 875 if (isolate_->debug()->debugger_entry() == NULL) { 876 UnloadDebugger(); 877 } 878 } 879 880 if (((event == v8::BeforeCompile) || (event == v8::AfterCompile)) && 881 !FLAG_debug_compile_events) { 882 return false; 883 884 } else if ((event == v8::ScriptCollected) && 885 !FLAG_debug_script_collected_events) { 886 return false; 887 } 888 889 // Currently argument event is not used. 890 return !compiling_natives_ && Debugger::IsDebuggerActive(); 891 } 892 893 void set_compiling_natives(bool compiling_natives) { 894 compiling_natives_ = compiling_natives; 895 } 896 bool compiling_natives() const { return compiling_natives_; } 897 void set_loading_debugger(bool v) { is_loading_debugger_ = v; } 898 bool is_loading_debugger() const { return is_loading_debugger_; } 899 void set_live_edit_enabled(bool v) { live_edit_enabled_ = v; } 900 bool live_edit_enabled() const { 901 return FLAG_enable_liveedit && live_edit_enabled_ ; 902 } 903 void set_force_debugger_active(bool force_debugger_active) { 904 force_debugger_active_ = force_debugger_active; 905 } 906 bool force_debugger_active() const { return force_debugger_active_; } 907 908 bool IsDebuggerActive(); 909 910 private: 911 explicit Debugger(Isolate* isolate); 912 913 void CallEventCallback(v8::DebugEvent event, 914 Handle<Object> exec_state, 915 Handle<Object> event_data, 916 v8::Debug::ClientData* client_data); 917 void CallCEventCallback(v8::DebugEvent event, 918 Handle<Object> exec_state, 919 Handle<Object> event_data, 920 v8::Debug::ClientData* client_data); 921 void CallJSEventCallback(v8::DebugEvent event, 922 Handle<Object> exec_state, 923 Handle<Object> event_data); 924 void ListenersChanged(); 925 926 RecursiveMutex* debugger_access_; // Mutex guarding debugger variables. 927 Handle<Object> event_listener_; // Global handle to listener. 928 Handle<Object> event_listener_data_; 929 bool compiling_natives_; // Are we compiling natives? 930 bool is_loading_debugger_; // Are we loading the debugger? 931 bool live_edit_enabled_; // Enable LiveEdit. 932 bool never_unload_debugger_; // Can we unload the debugger? 933 bool force_debugger_active_; // Activate debugger without event listeners. 934 v8::Debug::MessageHandler2 message_handler_; 935 bool debugger_unload_pending_; // Was message handler cleared? 936 v8::Debug::HostDispatchHandler host_dispatch_handler_; 937 Mutex dispatch_handler_access_; // Mutex guarding dispatch handler. 938 v8::Debug::DebugMessageDispatchHandler debug_message_dispatch_handler_; 939 MessageDispatchHelperThread* message_dispatch_helper_thread_; 940 TimeDelta host_dispatch_period_; 941 942 DebuggerAgent* agent_; 943 944 static const int kQueueInitialSize = 4; 945 LockingCommandMessageQueue command_queue_; 946 Semaphore command_received_; // Signaled for each command received. 947 LockingCommandMessageQueue event_command_queue_; 948 949 Isolate* isolate_; 950 951 friend class EnterDebugger; 952 friend class Isolate; 953 954 DISALLOW_COPY_AND_ASSIGN(Debugger); 955 }; 956 957 958 // This class is used for entering the debugger. Create an instance in the stack 959 // to enter the debugger. This will set the current break state, make sure the 960 // debugger is loaded and switch to the debugger context. If the debugger for 961 // some reason could not be entered FailedToEnter will return true. 962 class EnterDebugger BASE_EMBEDDED { 963 public: 964 explicit EnterDebugger(Isolate* isolate); 965 ~EnterDebugger(); 966 967 // Check whether the debugger could be entered. 968 inline bool FailedToEnter() { return load_failed_; } 969 970 // Check whether there are any JavaScript frames on the stack. 971 inline bool HasJavaScriptFrames() { return has_js_frames_; } 972 973 // Get the active context from before entering the debugger. 974 inline Handle<Context> GetContext() { return save_.context(); } 975 976 private: 977 Isolate* isolate_; 978 EnterDebugger* prev_; // Previous debugger entry if entered recursively. 979 JavaScriptFrameIterator it_; 980 const bool has_js_frames_; // Were there any JavaScript frames? 981 StackFrame::Id break_frame_id_; // Previous break frame id. 982 int break_id_; // Previous break id. 983 bool load_failed_; // Did the debugger fail to load? 984 SaveContext save_; // Saves previous context. 985 }; 986 987 988 // Stack allocated class for disabling break. 989 class DisableBreak BASE_EMBEDDED { 990 public: 991 explicit DisableBreak(Isolate* isolate, bool disable_break) 992 : isolate_(isolate) { 993 prev_disable_break_ = isolate_->debug()->disable_break(); 994 isolate_->debug()->set_disable_break(disable_break); 995 } 996 ~DisableBreak() { 997 isolate_->debug()->set_disable_break(prev_disable_break_); 998 } 999 1000 private: 1001 Isolate* isolate_; 1002 // The previous state of the disable break used to restore the value when this 1003 // object is destructed. 1004 bool prev_disable_break_; 1005 }; 1006 1007 1008 // Debug_Address encapsulates the Address pointers used in generating debug 1009 // code. 1010 class Debug_Address { 1011 public: 1012 explicit Debug_Address(Debug::AddressId id) : id_(id) { } 1013 1014 static Debug_Address AfterBreakTarget() { 1015 return Debug_Address(Debug::k_after_break_target_address); 1016 } 1017 1018 static Debug_Address DebugBreakReturn() { 1019 return Debug_Address(Debug::k_debug_break_return_address); 1020 } 1021 1022 static Debug_Address RestarterFrameFunctionPointer() { 1023 return Debug_Address(Debug::k_restarter_frame_function_pointer); 1024 } 1025 1026 Address address(Isolate* isolate) const { 1027 Debug* debug = isolate->debug(); 1028 switch (id_) { 1029 case Debug::k_after_break_target_address: 1030 return reinterpret_cast<Address>(debug->after_break_target_address()); 1031 case Debug::k_debug_break_return_address: 1032 return reinterpret_cast<Address>(debug->debug_break_return_address()); 1033 case Debug::k_debug_break_slot_address: 1034 return reinterpret_cast<Address>(debug->debug_break_slot_address()); 1035 case Debug::k_restarter_frame_function_pointer: 1036 return reinterpret_cast<Address>( 1037 debug->restarter_frame_function_pointer_address()); 1038 default: 1039 UNREACHABLE(); 1040 return NULL; 1041 } 1042 } 1043 1044 private: 1045 Debug::AddressId id_; 1046 }; 1047 1048 // The optional thread that Debug Agent may use to temporary call V8 to process 1049 // pending debug requests if debuggee is not running V8 at the moment. 1050 // Techincally it does not call V8 itself, rather it asks embedding program 1051 // to do this via v8::Debug::HostDispatchHandler 1052 class MessageDispatchHelperThread: public Thread { 1053 public: 1054 explicit MessageDispatchHelperThread(Isolate* isolate); 1055 ~MessageDispatchHelperThread() {} 1056 1057 void Schedule(); 1058 1059 private: 1060 void Run(); 1061 1062 Isolate* isolate_; 1063 Semaphore sem_; 1064 Mutex mutex_; 1065 bool already_signalled_; 1066 1067 DISALLOW_COPY_AND_ASSIGN(MessageDispatchHelperThread); 1068 }; 1069 1070 1071 } } // namespace v8::internal 1072 1073 #endif // ENABLE_DEBUGGER_SUPPORT 1074 1075 #endif // V8_DEBUG_H_ 1076