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

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

Issue 2622253004: [inspector] introduced debug::SetBreakEventListener,SetExceptionEventListener (Closed)
Patch Set: fixed compilation 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 1705 matching lines...) Expand 10 before | Expand all | Expand 10 after
1716 HandleScope scope(isolate_); 1716 HandleScope scope(isolate_);
1717 // Check whether the promise has been marked as having triggered a message. 1717 // Check whether the promise has been marked as having triggered a message.
1718 Handle<Symbol> key = isolate_->factory()->promise_debug_marker_symbol(); 1718 Handle<Symbol> key = isolate_->factory()->promise_debug_marker_symbol();
1719 if (!promise->IsJSObject() || 1719 if (!promise->IsJSObject() ||
1720 JSReceiver::GetDataProperty(Handle<JSObject>::cast(promise), key) 1720 JSReceiver::GetDataProperty(Handle<JSObject>::cast(promise), key)
1721 ->IsUndefined(isolate_)) { 1721 ->IsUndefined(isolate_)) {
1722 OnException(value, promise); 1722 OnException(value, promise);
1723 } 1723 }
1724 } 1724 }
1725 1725
1726 namespace {
1727 v8::Local<v8::Context> GetDebugEventContext(Isolate* isolate) {
1728 Handle<Context> context = isolate->debug()->debugger_entry()->GetContext();
1729 // Isolate::context() may have been NULL when "script collected" event
1730 // occured.
1731 if (context.is_null()) return v8::Local<v8::Context>();
1732 Handle<Context> native_context(context->native_context());
1733 return v8::Utils::ToLocal(native_context);
1734 }
1735 } // anonymous namespace
1726 1736
1727 void Debug::OnException(Handle<Object> exception, Handle<Object> promise) { 1737 void Debug::OnException(Handle<Object> exception, Handle<Object> promise) {
1728 // We cannot generate debug events when JS execution is disallowed. 1738 // We cannot generate debug events when JS execution is disallowed.
1729 // TODO(5530): Reenable debug events within DisallowJSScopes once relevant 1739 // TODO(5530): Reenable debug events within DisallowJSScopes once relevant
1730 // code (MakeExceptionEvent and ProcessDebugEvent) have been moved to C++. 1740 // code (MakeExceptionEvent and ProcessDebugEvent) have been moved to C++.
1731 if (!AllowJavascriptExecution::IsAllowed(isolate_)) return; 1741 if (!AllowJavascriptExecution::IsAllowed(isolate_)) return;
1732 1742
1733 Isolate::CatchType catch_type = isolate_->PredictExceptionCatcher(); 1743 Isolate::CatchType catch_type = isolate_->PredictExceptionCatcher();
1734 1744
1735 // Don't notify listener of exceptions that are internal to a desugaring. 1745 // Don't notify listener of exceptions that are internal to a desugaring.
(...skipping 19 matching lines...) Expand all
1755 1765
1756 { 1766 {
1757 // Check whether the break location is muted. 1767 // Check whether the break location is muted.
1758 JavaScriptFrameIterator it(isolate_); 1768 JavaScriptFrameIterator it(isolate_);
1759 if (!it.done() && IsMutedAtCurrentLocation(it.frame())) return; 1769 if (!it.done() && IsMutedAtCurrentLocation(it.frame())) return;
1760 } 1770 }
1761 1771
1762 DebugScope debug_scope(this); 1772 DebugScope debug_scope(this);
1763 if (debug_scope.failed()) return; 1773 if (debug_scope.failed()) return;
1764 1774
1775 if (debug_event_listener_) {
1776 HandleScope scope(isolate_);
1777
1778 // Create the execution state.
1779 Handle<Object> exec_state;
1780 // Bail out and don't call debugger if exception.
1781 if (!MakeExecutionState().ToHandle(&exec_state)) return;
1782
1783 debug_event_listener_->OnExceptionEvent(
1784 GetDebugEventContext(isolate_),
1785 v8::Utils::ToLocal(Handle<JSObject>::cast(exec_state)),
1786 v8::Utils::ToLocal(exception), promise->IsJSObject(), uncaught);
1787 if (!non_inspector_listener_exists()) return;
1788 }
1789
1765 // Create the event data object. 1790 // Create the event data object.
1766 Handle<Object> event_data; 1791 Handle<Object> event_data;
1767 // Bail out and don't call debugger if exception. 1792 // Bail out and don't call debugger if exception.
1768 if (!MakeExceptionEvent( 1793 if (!MakeExceptionEvent(
1769 exception, uncaught, promise).ToHandle(&event_data)) { 1794 exception, uncaught, promise).ToHandle(&event_data)) {
1770 return; 1795 return;
1771 } 1796 }
1772 1797
1773 // Process debug event. 1798 // Process debug event.
1774 ProcessDebugEvent(v8::Exception, Handle<JSObject>::cast(event_data), false); 1799 ProcessDebugEvent(v8::Exception, Handle<JSObject>::cast(event_data), false);
1775 // Return to continue execution from where the exception was thrown. 1800 // Return to continue execution from where the exception was thrown.
1776 } 1801 }
1777 1802
1778 void Debug::OnDebugBreak(Handle<Object> break_points_hit, bool auto_continue) { 1803 void Debug::OnDebugBreak(Handle<Object> break_points_hit, bool auto_continue) {
1779 // The caller provided for DebugScope. 1804 // The caller provided for DebugScope.
1780 AssertDebugContext(); 1805 AssertDebugContext();
1781 // Bail out if there is no listener for this event 1806 // Bail out if there is no listener for this event
1782 if (ignore_events()) return; 1807 if (ignore_events()) return;
1783 1808
1784 #ifdef DEBUG 1809 #ifdef DEBUG
1785 PrintBreakLocation(); 1810 PrintBreakLocation();
1786 #endif // DEBUG 1811 #endif // DEBUG
1787 1812
1813 if (debug_event_listener_) {
1814 HandleScope scope(isolate_);
1815
1816 // Create the execution state.
1817 Handle<Object> exec_state;
1818 // Bail out and don't call debugger if exception.
1819 if (!MakeExecutionState().ToHandle(&exec_state)) return;
1820
1821 bool previous = in_debug_event_listener_;
1822 in_debug_event_listener_ = true;
1823 debug_event_listener_->OnBreakEvent(
1824 GetDebugEventContext(isolate_),
1825 v8::Utils::ToLocal(Handle<JSObject>::cast(exec_state)),
1826 v8::Utils::ToLocal(break_points_hit));
1827 in_debug_event_listener_ = previous;
1828 if (!non_inspector_listener_exists()) return;
1829 }
1830
1788 HandleScope scope(isolate_); 1831 HandleScope scope(isolate_);
1789 // Create the event data object. 1832 // Create the event data object.
1790 Handle<Object> event_data; 1833 Handle<Object> event_data;
1791 // Bail out and don't call debugger if exception. 1834 // Bail out and don't call debugger if exception.
1792 if (!MakeBreakEvent(break_points_hit).ToHandle(&event_data)) return; 1835 if (!MakeBreakEvent(break_points_hit).ToHandle(&event_data)) return;
1793 1836
1794 // Process debug event. 1837 // Process debug event.
1795 ProcessDebugEvent(v8::Break, Handle<JSObject>::cast(event_data), 1838 ProcessDebugEvent(v8::Break, Handle<JSObject>::cast(event_data),
1796 auto_continue); 1839 auto_continue);
1797 } 1840 }
(...skipping 57 matching lines...) Expand 10 before | Expand all | Expand 10 after
1855 // Since we holding promise when at least one microtask is scheduled (inside 1898 // Since we holding promise when at least one microtask is scheduled (inside
1856 // PromiseReactionJobInfo), we can send cancel event in weak callback. 1899 // PromiseReactionJobInfo), we can send cancel event in weak callback.
1857 GlobalHandles::MakeWeak( 1900 GlobalHandles::MakeWeak(
1858 global_handle.location(), 1901 global_handle.location(),
1859 new CollectedCallbackData(global_handle.location(), async_id->value(), 1902 new CollectedCallbackData(global_handle.location(), async_id->value(),
1860 this, isolate_), 1903 this, isolate_),
1861 &ResetPromiseHandle, v8::WeakCallbackType::kParameter); 1904 &ResetPromiseHandle, v8::WeakCallbackType::kParameter);
1862 return async_id->value(); 1905 return async_id->value();
1863 } 1906 }
1864 1907
1865 void Debug::SetAsyncTaskListener(debug::AsyncTaskListener listener,
1866 void* data) {
1867 async_task_listener_ = listener;
1868 async_task_listener_data_ = data;
1869 UpdateState();
1870 }
1871
1872 void Debug::OnAsyncTaskEvent(debug::PromiseDebugActionType type, int id) { 1908 void Debug::OnAsyncTaskEvent(debug::PromiseDebugActionType type, int id) {
1873 if (in_debug_scope() || ignore_events()) return; 1909 if (in_debug_scope() || ignore_events()) return;
1874 1910
1875 if (async_task_listener_) { 1911 if (debug_event_listener_) {
1876 async_task_listener_(type, id, async_task_listener_data_); 1912 debug_event_listener_->OnAsyncTaskEvent(type, id);
1877 if (!non_inspector_listener_exists()) return; 1913 if (!non_inspector_listener_exists()) return;
1878 } 1914 }
1879 1915
1880 HandleScope scope(isolate_); 1916 HandleScope scope(isolate_);
1881 DebugScope debug_scope(this); 1917 DebugScope debug_scope(this);
1882 if (debug_scope.failed()) return; 1918 if (debug_scope.failed()) return;
1883 1919
1884 // Create the script collected state object. 1920 // Create the script collected state object.
1885 Handle<Object> event_data; 1921 Handle<Object> event_data;
1886 // Bail out and don't call debugger if exception. 1922 // Bail out and don't call debugger if exception.
(...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after
1921 Handle<Object> exec_state, 1957 Handle<Object> exec_state,
1922 Handle<Object> event_data, 1958 Handle<Object> event_data,
1923 v8::Debug::ClientData* client_data) { 1959 v8::Debug::ClientData* client_data) {
1924 // Prevent other interrupts from triggering, for example API callbacks, 1960 // Prevent other interrupts from triggering, for example API callbacks,
1925 // while dispatching event listners. 1961 // while dispatching event listners.
1926 PostponeInterruptsScope postpone(isolate_); 1962 PostponeInterruptsScope postpone(isolate_);
1927 bool previous = in_debug_event_listener_; 1963 bool previous = in_debug_event_listener_;
1928 in_debug_event_listener_ = true; 1964 in_debug_event_listener_ = true;
1929 if (event_listener_->IsForeign()) { 1965 if (event_listener_->IsForeign()) {
1930 // Invoke the C debug event listener. 1966 // Invoke the C debug event listener.
1931 debug::EventCallback callback = FUNCTION_CAST<debug::EventCallback>( 1967 v8::Debug::EventCallback callback = FUNCTION_CAST<v8::Debug::EventCallback>(
1932 Handle<Foreign>::cast(event_listener_)->foreign_address()); 1968 Handle<Foreign>::cast(event_listener_)->foreign_address());
1933 EventDetailsImpl event_details(event, 1969 EventDetailsImpl event_details(event,
1934 Handle<JSObject>::cast(exec_state), 1970 Handle<JSObject>::cast(exec_state),
1935 Handle<JSObject>::cast(event_data), 1971 Handle<JSObject>::cast(event_data),
1936 event_listener_data_, 1972 event_listener_data_,
1937 client_data); 1973 client_data);
1938 callback(event_details); 1974 callback(event_details);
1939 CHECK(!isolate_->has_scheduled_exception()); 1975 CHECK(!isolate_->has_scheduled_exception());
1940 } else { 1976 } else {
1941 // Invoke the JavaScript debug event listener. 1977 // Invoke the JavaScript debug event listener.
1942 DCHECK(event_listener_->IsJSFunction()); 1978 DCHECK(event_listener_->IsJSFunction());
1943 Handle<Object> argv[] = { Handle<Object>(Smi::FromInt(event), isolate_), 1979 Handle<Object> argv[] = { Handle<Object>(Smi::FromInt(event), isolate_),
1944 exec_state, 1980 exec_state,
1945 event_data, 1981 event_data,
1946 event_listener_data_ }; 1982 event_listener_data_ };
1947 Handle<JSReceiver> global = isolate_->global_proxy(); 1983 Handle<JSReceiver> global = isolate_->global_proxy();
1948 MaybeHandle<Object> result = 1984 MaybeHandle<Object> result =
1949 Execution::Call(isolate_, Handle<JSFunction>::cast(event_listener_), 1985 Execution::Call(isolate_, Handle<JSFunction>::cast(event_listener_),
1950 global, arraysize(argv), argv); 1986 global, arraysize(argv), argv);
1951 CHECK(!result.is_null()); // Listeners must not throw. 1987 CHECK(!result.is_null()); // Listeners must not throw.
1952 } 1988 }
1953 in_debug_event_listener_ = previous; 1989 in_debug_event_listener_ = previous;
1954 } 1990 }
1955 1991
1956 void Debug::SetCompileEventListener(debug::CompileEventListener listener,
1957 void* data) {
1958 compile_event_listener_ = listener;
1959 compile_event_listener_data_ = data;
1960 UpdateState();
1961 }
1962
1963 void Debug::ProcessCompileEvent(v8::DebugEvent event, Handle<Script> script) { 1992 void Debug::ProcessCompileEvent(v8::DebugEvent event, Handle<Script> script) {
1964 if (ignore_events()) return; 1993 if (ignore_events()) return;
1965 if (script->type() != i::Script::TYPE_NORMAL && 1994 if (script->type() != i::Script::TYPE_NORMAL &&
1966 script->type() != i::Script::TYPE_WASM) { 1995 script->type() != i::Script::TYPE_WASM) {
1967 return; 1996 return;
1968 } 1997 }
1969 SuppressDebug while_processing(this); 1998 SuppressDebug while_processing(this);
1970 1999
1971 if (compile_event_listener_) { 2000 if (debug_event_listener_) {
1972 compile_event_listener_(ToApiHandle<debug::Script>(script), 2001 debug_event_listener_->OnCompileEvent(ToApiHandle<debug::Script>(script),
1973 event != v8::AfterCompile, 2002 event != v8::AfterCompile);
1974 compile_event_listener_data_);
1975 if (!non_inspector_listener_exists()) return; 2003 if (!non_inspector_listener_exists()) return;
1976 } 2004 }
1977 2005
1978 bool in_nested_debug_scope = in_debug_scope(); 2006 bool in_nested_debug_scope = in_debug_scope();
1979 HandleScope scope(isolate_); 2007 HandleScope scope(isolate_);
1980 DebugScope debug_scope(this); 2008 DebugScope debug_scope(this);
1981 if (debug_scope.failed()) return; 2009 if (debug_scope.failed()) return;
1982 2010
1983 // Create the compile state object. 2011 // Create the compile state object.
1984 Handle<Object> event_data; 2012 Handle<Object> event_data;
(...skipping 179 matching lines...) Expand 10 before | Expand all | Expand 10 after
2164 void Debug::SetMessageHandler(v8::Debug::MessageHandler handler) { 2192 void Debug::SetMessageHandler(v8::Debug::MessageHandler handler) {
2165 message_handler_ = handler; 2193 message_handler_ = handler;
2166 UpdateState(); 2194 UpdateState();
2167 if (handler == NULL && in_debug_scope()) { 2195 if (handler == NULL && in_debug_scope()) {
2168 // Send an empty command to the debugger if in a break to make JavaScript 2196 // Send an empty command to the debugger if in a break to make JavaScript
2169 // run again if the debugger is closed. 2197 // run again if the debugger is closed.
2170 EnqueueCommandMessage(Vector<const uint16_t>::empty()); 2198 EnqueueCommandMessage(Vector<const uint16_t>::empty());
2171 } 2199 }
2172 } 2200 }
2173 2201
2202 void Debug::SetDebugEventListener(debug::DebugEventListener* listener) {
2203 debug_event_listener_ = listener;
2204 UpdateState();
2205 }
2206
2174 void Debug::UpdateState() { 2207 void Debug::UpdateState() {
2175 bool is_active = message_handler_ != nullptr || !event_listener_.is_null() || 2208 bool is_active = message_handler_ != nullptr || !event_listener_.is_null() ||
2176 async_task_listener_ != nullptr || 2209 debug_event_listener_ != nullptr;
2177 compile_event_listener_ != nullptr;
2178 if (is_active || in_debug_scope()) { 2210 if (is_active || in_debug_scope()) {
2179 // Note that the debug context could have already been loaded to 2211 // Note that the debug context could have already been loaded to
2180 // bootstrap test cases. 2212 // bootstrap test cases.
2181 isolate_->compilation_cache()->Disable(); 2213 isolate_->compilation_cache()->Disable();
2182 is_active = Load(); 2214 is_active = Load();
2183 } else if (is_loaded()) { 2215 } else if (is_loaded()) {
2184 isolate_->compilation_cache()->Enable(); 2216 isolate_->compilation_cache()->Enable();
2185 Unload(); 2217 Unload();
2186 } 2218 }
2187 is_active_ = is_active; 2219 is_active_ = is_active;
(...skipping 317 matching lines...) Expand 10 before | Expand all | Expand 10 after
2505 Handle<Object> json; 2537 Handle<Object> json;
2506 if (!maybe_json.ToHandle(&json) || !json->IsString()) { 2538 if (!maybe_json.ToHandle(&json) || !json->IsString()) {
2507 return v8::Local<v8::String>(); 2539 return v8::Local<v8::String>();
2508 } 2540 }
2509 return scope.Escape(v8::Utils::ToLocal(Handle<String>::cast(json))); 2541 return scope.Escape(v8::Utils::ToLocal(Handle<String>::cast(json)));
2510 } else { 2542 } else {
2511 return v8::Utils::ToLocal(response_json_); 2543 return v8::Utils::ToLocal(response_json_);
2512 } 2544 }
2513 } 2545 }
2514 2546
2515 namespace {
2516 v8::Local<v8::Context> GetDebugEventContext(Isolate* isolate) {
2517 Handle<Context> context = isolate->debug()->debugger_entry()->GetContext();
2518 // Isolate::context() may have been NULL when "script collected" event
2519 // occured.
2520 if (context.is_null()) return v8::Local<v8::Context>();
2521 Handle<Context> native_context(context->native_context());
2522 return v8::Utils::ToLocal(native_context);
2523 }
2524 } // anonymous namespace
2525
2526 v8::Local<v8::Context> MessageImpl::GetEventContext() const { 2547 v8::Local<v8::Context> MessageImpl::GetEventContext() const {
2527 Isolate* isolate = event_data_->GetIsolate(); 2548 Isolate* isolate = event_data_->GetIsolate();
2528 v8::Local<v8::Context> context = GetDebugEventContext(isolate); 2549 v8::Local<v8::Context> context = GetDebugEventContext(isolate);
2529 // Isolate::context() may be NULL when "script collected" event occurs. 2550 // Isolate::context() may be NULL when "script collected" event occurs.
2530 DCHECK(!context.IsEmpty()); 2551 DCHECK(!context.IsEmpty());
2531 return context; 2552 return context;
2532 } 2553 }
2533 2554
2534 v8::Debug::ClientData* MessageImpl::GetClientData() const { 2555 v8::Debug::ClientData* MessageImpl::GetClientData() const {
2535 return client_data_; 2556 return client_data_;
(...skipping 121 matching lines...) Expand 10 before | Expand all | Expand 10 after
2657 logger_->DebugEvent("Put", message.text()); 2678 logger_->DebugEvent("Put", message.text());
2658 } 2679 }
2659 2680
2660 void LockingCommandMessageQueue::Clear() { 2681 void LockingCommandMessageQueue::Clear() {
2661 base::LockGuard<base::Mutex> lock_guard(&mutex_); 2682 base::LockGuard<base::Mutex> lock_guard(&mutex_);
2662 queue_.Clear(); 2683 queue_.Clear();
2663 } 2684 }
2664 2685
2665 } // namespace internal 2686 } // namespace internal
2666 } // namespace v8 2687 } // namespace v8
OLDNEW
« no previous file with comments | « src/debug/debug.h ('k') | src/debug/debug-interface.h » ('j') | src/debug/debug-interface.h » ('J')

Powered by Google App Engine
This is Rietveld 408576698