Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(44)

Side by Side Diff: src/debug/debug.cc

Issue 2622253004: [inspector] introduced debug::SetBreakEventListener,SetExceptionEventListener (Closed)
Patch Set: ready for review Created 3 years, 11 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
1 // Copyright 2012 the V8 project authors. All rights reserved. 1 // Copyright 2012 the V8 project authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include "src/debug/debug.h" 5 #include "src/debug/debug.h"
6 6
7 #include <memory> 7 #include <memory>
8 8
9 #include "src/api.h" 9 #include "src/api.h"
10 #include "src/arguments.h" 10 #include "src/arguments.h"
(...skipping 1702 matching lines...) Expand 10 before | Expand all | Expand 10 after
1713 HandleScope scope(isolate_); 1713 HandleScope scope(isolate_);
1714 // Check whether the promise has been marked as having triggered a message. 1714 // Check whether the promise has been marked as having triggered a message.
1715 Handle<Symbol> key = isolate_->factory()->promise_debug_marker_symbol(); 1715 Handle<Symbol> key = isolate_->factory()->promise_debug_marker_symbol();
1716 if (!promise->IsJSObject() || 1716 if (!promise->IsJSObject() ||
1717 JSReceiver::GetDataProperty(Handle<JSObject>::cast(promise), key) 1717 JSReceiver::GetDataProperty(Handle<JSObject>::cast(promise), key)
1718 ->IsUndefined(isolate_)) { 1718 ->IsUndefined(isolate_)) {
1719 OnException(value, promise); 1719 OnException(value, promise);
1720 } 1720 }
1721 } 1721 }
1722 1722
1723 namespace {
1724 v8::Local<v8::Context> GetDebugEventContext(Isolate* isolate) {
1725 Handle<Context> context = isolate->debug()->debugger_entry()->GetContext();
1726 // Isolate::context() may have been NULL when "script collected" event
1727 // occured.
1728 if (context.is_null()) return v8::Local<v8::Context>();
1729 Handle<Context> native_context(context->native_context());
1730 return v8::Utils::ToLocal(native_context);
1731 }
1732 } // anonymous namespace
1733
1734 void Debug::SetExceptionEventListener(debug::ExceptionEventListener listener,
1735 void* data) {
1736 exception_event_listener_ = listener;
1737 exception_event_listener_data_ = data;
1738 UpdateState();
1739 }
1723 1740
1724 void Debug::OnException(Handle<Object> exception, Handle<Object> promise) { 1741 void Debug::OnException(Handle<Object> exception, Handle<Object> promise) {
1725 // We cannot generate debug events when JS execution is disallowed. 1742 // We cannot generate debug events when JS execution is disallowed.
1726 // TODO(5530): Reenable debug events within DisallowJSScopes once relevant 1743 // TODO(5530): Reenable debug events within DisallowJSScopes once relevant
1727 // code (MakeExceptionEvent and ProcessDebugEvent) have been moved to C++. 1744 // code (MakeExceptionEvent and ProcessDebugEvent) have been moved to C++.
1728 if (!AllowJavascriptExecution::IsAllowed(isolate_)) return; 1745 if (!AllowJavascriptExecution::IsAllowed(isolate_)) return;
1729 1746
1730 Isolate::CatchType catch_type = isolate_->PredictExceptionCatcher(); 1747 Isolate::CatchType catch_type = isolate_->PredictExceptionCatcher();
1731 1748
1732 // Don't notify listener of exceptions that are internal to a desugaring. 1749 // Don't notify listener of exceptions that are internal to a desugaring.
(...skipping 19 matching lines...) Expand all
1752 1769
1753 { 1770 {
1754 // Check whether the break location is muted. 1771 // Check whether the break location is muted.
1755 JavaScriptFrameIterator it(isolate_); 1772 JavaScriptFrameIterator it(isolate_);
1756 if (!it.done() && IsMutedAtCurrentLocation(it.frame())) return; 1773 if (!it.done() && IsMutedAtCurrentLocation(it.frame())) return;
1757 } 1774 }
1758 1775
1759 DebugScope debug_scope(this); 1776 DebugScope debug_scope(this);
1760 if (debug_scope.failed()) return; 1777 if (debug_scope.failed()) return;
1761 1778
1779 if (exception_event_listener_) {
1780 HandleScope scope(isolate_);
1781
1782 // Create the execution state.
1783 Handle<Object> exec_state;
1784 // Bail out and don't call debugger if exception.
1785 if (!MakeExecutionState().ToHandle(&exec_state)) return;
1786
1787 exception_event_listener_(
1788 GetDebugEventContext(isolate_),
1789 v8::Utils::ToLocal(Handle<JSObject>::cast(exec_state)),
1790 v8::Utils::ToLocal(exception), promise->IsJSObject(), uncaught,
1791 exception_event_listener_data_);
1792 if (!non_inspector_listener_exists()) return;
1793 }
1794
1762 // Create the event data object. 1795 // Create the event data object.
1763 Handle<Object> event_data; 1796 Handle<Object> event_data;
1764 // Bail out and don't call debugger if exception. 1797 // Bail out and don't call debugger if exception.
1765 if (!MakeExceptionEvent( 1798 if (!MakeExceptionEvent(
1766 exception, uncaught, promise).ToHandle(&event_data)) { 1799 exception, uncaught, promise).ToHandle(&event_data)) {
1767 return; 1800 return;
1768 } 1801 }
1769 1802
1770 // Process debug event. 1803 // Process debug event.
1771 ProcessDebugEvent(v8::Exception, Handle<JSObject>::cast(event_data), false); 1804 ProcessDebugEvent(v8::Exception, Handle<JSObject>::cast(event_data), false);
1772 // Return to continue execution from where the exception was thrown. 1805 // Return to continue execution from where the exception was thrown.
1773 } 1806 }
1774 1807
1808 void Debug::SetBreakEventListener(debug::BreakEventListener listener,
1809 void* data) {
1810 break_event_listener_ = listener;
1811 break_event_listener_data_ = data;
1812 UpdateState();
1813 }
1814
1775 void Debug::OnDebugBreak(Handle<Object> break_points_hit, bool auto_continue) { 1815 void Debug::OnDebugBreak(Handle<Object> break_points_hit, bool auto_continue) {
1776 // The caller provided for DebugScope. 1816 // The caller provided for DebugScope.
1777 AssertDebugContext(); 1817 AssertDebugContext();
1778 // Bail out if there is no listener for this event 1818 // Bail out if there is no listener for this event
1779 if (ignore_events()) return; 1819 if (ignore_events()) return;
1780 1820
1781 #ifdef DEBUG 1821 #ifdef DEBUG
1782 PrintBreakLocation(); 1822 PrintBreakLocation();
1783 #endif // DEBUG 1823 #endif // DEBUG
1784 1824
1825 if (break_event_listener_) {
1826 HandleScope scope(isolate_);
1827
1828 // Create the execution state.
1829 Handle<Object> exec_state;
1830 // Bail out and don't call debugger if exception.
1831 if (!MakeExecutionState().ToHandle(&exec_state)) return;
1832
1833 break_event_listener_(
1834 GetDebugEventContext(isolate_),
1835 v8::Utils::ToLocal(Handle<JSObject>::cast(exec_state)),
1836 v8::Utils::ToLocal(break_points_hit), break_event_listener_data_);
1837 if (!non_inspector_listener_exists()) return;
1838 }
1839
1785 HandleScope scope(isolate_); 1840 HandleScope scope(isolate_);
1786 // Create the event data object. 1841 // Create the event data object.
1787 Handle<Object> event_data; 1842 Handle<Object> event_data;
1788 // Bail out and don't call debugger if exception. 1843 // Bail out and don't call debugger if exception.
1789 if (!MakeBreakEvent(break_points_hit).ToHandle(&event_data)) return; 1844 if (!MakeBreakEvent(break_points_hit).ToHandle(&event_data)) return;
1790 1845
1791 // Process debug event. 1846 // Process debug event.
1792 ProcessDebugEvent(v8::Break, Handle<JSObject>::cast(event_data), 1847 ProcessDebugEvent(v8::Break, Handle<JSObject>::cast(event_data),
1793 auto_continue); 1848 auto_continue);
1794 } 1849 }
(...skipping 130 matching lines...) Expand 10 before | Expand all | Expand 10 after
1925 Handle<Object> exec_state, 1980 Handle<Object> exec_state,
1926 Handle<Object> event_data, 1981 Handle<Object> event_data,
1927 v8::Debug::ClientData* client_data) { 1982 v8::Debug::ClientData* client_data) {
1928 // Prevent other interrupts from triggering, for example API callbacks, 1983 // Prevent other interrupts from triggering, for example API callbacks,
1929 // while dispatching event listners. 1984 // while dispatching event listners.
1930 PostponeInterruptsScope postpone(isolate_); 1985 PostponeInterruptsScope postpone(isolate_);
1931 bool previous = in_debug_event_listener_; 1986 bool previous = in_debug_event_listener_;
1932 in_debug_event_listener_ = true; 1987 in_debug_event_listener_ = true;
1933 if (event_listener_->IsForeign()) { 1988 if (event_listener_->IsForeign()) {
1934 // Invoke the C debug event listener. 1989 // Invoke the C debug event listener.
1935 debug::EventCallback callback = FUNCTION_CAST<debug::EventCallback>( 1990 v8::Debug::EventCallback callback = FUNCTION_CAST<v8::Debug::EventCallback>(
1936 Handle<Foreign>::cast(event_listener_)->foreign_address()); 1991 Handle<Foreign>::cast(event_listener_)->foreign_address());
1937 EventDetailsImpl event_details(event, 1992 EventDetailsImpl event_details(event,
1938 Handle<JSObject>::cast(exec_state), 1993 Handle<JSObject>::cast(exec_state),
1939 Handle<JSObject>::cast(event_data), 1994 Handle<JSObject>::cast(event_data),
1940 event_listener_data_, 1995 event_listener_data_,
1941 client_data); 1996 client_data);
1942 callback(event_details); 1997 callback(event_details);
1943 CHECK(!isolate_->has_scheduled_exception()); 1998 CHECK(!isolate_->has_scheduled_exception());
1944 } else { 1999 } else {
1945 // Invoke the JavaScript debug event listener. 2000 // Invoke the JavaScript debug event listener.
(...skipping 217 matching lines...) Expand 10 before | Expand all | Expand 10 after
2163 message_handler_ = handler; 2218 message_handler_ = handler;
2164 UpdateState(); 2219 UpdateState();
2165 if (handler == NULL && in_debug_scope()) { 2220 if (handler == NULL && in_debug_scope()) {
2166 // Send an empty command to the debugger if in a break to make JavaScript 2221 // Send an empty command to the debugger if in a break to make JavaScript
2167 // run again if the debugger is closed. 2222 // run again if the debugger is closed.
2168 EnqueueCommandMessage(Vector<const uint16_t>::empty()); 2223 EnqueueCommandMessage(Vector<const uint16_t>::empty());
2169 } 2224 }
2170 } 2225 }
2171 2226
2172 void Debug::UpdateState() { 2227 void Debug::UpdateState() {
2173 bool is_active = message_handler_ != nullptr || !event_listener_.is_null() || 2228 bool is_active =
2174 async_task_listener_ != nullptr || 2229 message_handler_ != nullptr || !event_listener_.is_null() ||
2175 compile_event_listener_ != nullptr; 2230 async_task_listener_ != nullptr || compile_event_listener_ != nullptr ||
2231 break_event_listener_ != nullptr || exception_event_listener_ != nullptr;
2176 if (is_active || in_debug_scope()) { 2232 if (is_active || in_debug_scope()) {
2177 // Note that the debug context could have already been loaded to 2233 // Note that the debug context could have already been loaded to
2178 // bootstrap test cases. 2234 // bootstrap test cases.
2179 isolate_->compilation_cache()->Disable(); 2235 isolate_->compilation_cache()->Disable();
2180 is_active = Load(); 2236 is_active = Load();
2181 } else if (is_loaded()) { 2237 } else if (is_loaded()) {
2182 isolate_->compilation_cache()->Enable(); 2238 isolate_->compilation_cache()->Enable();
2183 Unload(); 2239 Unload();
2184 } 2240 }
2185 is_active_ = is_active; 2241 is_active_ = is_active;
(...skipping 315 matching lines...) Expand 10 before | Expand all | Expand 10 after
2501 Handle<Object> json; 2557 Handle<Object> json;
2502 if (!maybe_json.ToHandle(&json) || !json->IsString()) { 2558 if (!maybe_json.ToHandle(&json) || !json->IsString()) {
2503 return v8::Local<v8::String>(); 2559 return v8::Local<v8::String>();
2504 } 2560 }
2505 return scope.Escape(v8::Utils::ToLocal(Handle<String>::cast(json))); 2561 return scope.Escape(v8::Utils::ToLocal(Handle<String>::cast(json)));
2506 } else { 2562 } else {
2507 return v8::Utils::ToLocal(response_json_); 2563 return v8::Utils::ToLocal(response_json_);
2508 } 2564 }
2509 } 2565 }
2510 2566
2511 namespace {
2512 v8::Local<v8::Context> GetDebugEventContext(Isolate* isolate) {
2513 Handle<Context> context = isolate->debug()->debugger_entry()->GetContext();
2514 // Isolate::context() may have been NULL when "script collected" event
2515 // occured.
2516 if (context.is_null()) return v8::Local<v8::Context>();
2517 Handle<Context> native_context(context->native_context());
2518 return v8::Utils::ToLocal(native_context);
2519 }
2520 } // anonymous namespace
2521
2522 v8::Local<v8::Context> MessageImpl::GetEventContext() const { 2567 v8::Local<v8::Context> MessageImpl::GetEventContext() const {
2523 Isolate* isolate = event_data_->GetIsolate(); 2568 Isolate* isolate = event_data_->GetIsolate();
2524 v8::Local<v8::Context> context = GetDebugEventContext(isolate); 2569 v8::Local<v8::Context> context = GetDebugEventContext(isolate);
2525 // Isolate::context() may be NULL when "script collected" event occurs. 2570 // Isolate::context() may be NULL when "script collected" event occurs.
2526 DCHECK(!context.IsEmpty()); 2571 DCHECK(!context.IsEmpty());
2527 return context; 2572 return context;
2528 } 2573 }
2529 2574
2530 v8::Debug::ClientData* MessageImpl::GetClientData() const { 2575 v8::Debug::ClientData* MessageImpl::GetClientData() const {
2531 return client_data_; 2576 return client_data_;
(...skipping 121 matching lines...) Expand 10 before | Expand all | Expand 10 after
2653 logger_->DebugEvent("Put", message.text()); 2698 logger_->DebugEvent("Put", message.text());
2654 } 2699 }
2655 2700
2656 void LockingCommandMessageQueue::Clear() { 2701 void LockingCommandMessageQueue::Clear() {
2657 base::LockGuard<base::Mutex> lock_guard(&mutex_); 2702 base::LockGuard<base::Mutex> lock_guard(&mutex_);
2658 queue_.Clear(); 2703 queue_.Clear();
2659 } 2704 }
2660 2705
2661 } // namespace internal 2706 } // namespace internal
2662 } // namespace v8 2707 } // namespace v8
OLDNEW
« no previous file with comments | « src/debug/debug.h ('k') | src/debug/debug-interface.h » ('j') | src/inspector/v8-debugger.cc » ('J')

Powered by Google App Engine
This is Rietveld 408576698