| OLD | NEW |
| 1 /* | 1 /* |
| 2 * Copyright (c) 2010-2011 Google Inc. All rights reserved. | 2 * Copyright (c) 2010-2011 Google Inc. All rights reserved. |
| 3 * | 3 * |
| 4 * Redistribution and use in source and binary forms, with or without | 4 * Redistribution and use in source and binary forms, with or without |
| 5 * modification, are permitted provided that the following conditions are | 5 * modification, are permitted provided that the following conditions are |
| 6 * met: | 6 * met: |
| 7 * | 7 * |
| 8 * * Redistributions of source code must retain the above copyright | 8 * * Redistributions of source code must retain the above copyright |
| 9 * notice, this list of conditions and the following disclaimer. | 9 * notice, this list of conditions and the following disclaimer. |
| 10 * * Redistributions in binary form must reproduce the above | 10 * * Redistributions in binary form must reproduce the above |
| (...skipping 18 matching lines...) Expand all Loading... |
| 29 */ | 29 */ |
| 30 | 30 |
| 31 #include "platform/v8_inspector/V8DebuggerImpl.h" | 31 #include "platform/v8_inspector/V8DebuggerImpl.h" |
| 32 | 32 |
| 33 #include "platform/inspector_protocol/Values.h" | 33 #include "platform/inspector_protocol/Values.h" |
| 34 #include "platform/v8_inspector/Atomics.h" | 34 #include "platform/v8_inspector/Atomics.h" |
| 35 #include "platform/v8_inspector/DebuggerScript.h" | 35 #include "platform/v8_inspector/DebuggerScript.h" |
| 36 #include "platform/v8_inspector/InspectedContext.h" | 36 #include "platform/v8_inspector/InspectedContext.h" |
| 37 #include "platform/v8_inspector/ScriptBreakpoint.h" | 37 #include "platform/v8_inspector/ScriptBreakpoint.h" |
| 38 #include "platform/v8_inspector/V8Compat.h" | 38 #include "platform/v8_inspector/V8Compat.h" |
| 39 #include "platform/v8_inspector/V8ConsoleAgentImpl.h" |
| 40 #include "platform/v8_inspector/V8ConsoleMessage.h" |
| 39 #include "platform/v8_inspector/V8DebuggerAgentImpl.h" | 41 #include "platform/v8_inspector/V8DebuggerAgentImpl.h" |
| 40 #include "platform/v8_inspector/V8InspectorSessionImpl.h" | 42 #include "platform/v8_inspector/V8InspectorSessionImpl.h" |
| 41 #include "platform/v8_inspector/V8RuntimeAgentImpl.h" | 43 #include "platform/v8_inspector/V8RuntimeAgentImpl.h" |
| 42 #include "platform/v8_inspector/V8StackTraceImpl.h" | 44 #include "platform/v8_inspector/V8StackTraceImpl.h" |
| 43 #include "platform/v8_inspector/V8StringUtil.h" | 45 #include "platform/v8_inspector/V8StringUtil.h" |
| 44 #include "platform/v8_inspector/public/V8DebuggerClient.h" | 46 #include "platform/v8_inspector/public/V8DebuggerClient.h" |
| 45 #include <v8-profiler.h> | 47 #include <v8-profiler.h> |
| 46 | 48 |
| 47 namespace blink { | 49 namespace blink { |
| 48 | 50 |
| (...skipping 21 matching lines...) Expand all Loading... |
| 70 } | 72 } |
| 71 | 73 |
| 72 std::unique_ptr<V8Debugger> V8Debugger::create(v8::Isolate* isolate, V8DebuggerC
lient* client) | 74 std::unique_ptr<V8Debugger> V8Debugger::create(v8::Isolate* isolate, V8DebuggerC
lient* client) |
| 73 { | 75 { |
| 74 return wrapUnique(new V8DebuggerImpl(isolate, client)); | 76 return wrapUnique(new V8DebuggerImpl(isolate, client)); |
| 75 } | 77 } |
| 76 | 78 |
| 77 V8DebuggerImpl::V8DebuggerImpl(v8::Isolate* isolate, V8DebuggerClient* client) | 79 V8DebuggerImpl::V8DebuggerImpl(v8::Isolate* isolate, V8DebuggerClient* client) |
| 78 : m_isolate(isolate) | 80 : m_isolate(isolate) |
| 79 , m_client(client) | 81 , m_client(client) |
| 82 , m_capturingStackTracesCount(0) |
| 83 , m_muteConsoleCount(0) |
| 84 , m_lastConsoleMessageId(0) |
| 80 , m_enabledAgentsCount(0) | 85 , m_enabledAgentsCount(0) |
| 81 , m_breakpointsActivated(true) | 86 , m_breakpointsActivated(true) |
| 82 , m_runningNestedMessageLoop(false) | 87 , m_runningNestedMessageLoop(false) |
| 83 { | 88 { |
| 84 } | 89 } |
| 85 | 90 |
| 86 V8DebuggerImpl::~V8DebuggerImpl() | 91 V8DebuggerImpl::~V8DebuggerImpl() |
| 87 { | 92 { |
| 88 } | 93 } |
| 89 | 94 |
| (...skipping 13 matching lines...) Expand all Loading... |
| 103 m_debuggerScript.Reset(); | 108 m_debuggerScript.Reset(); |
| 104 m_debuggerContext.Reset(); | 109 m_debuggerContext.Reset(); |
| 105 v8::Debug::SetDebugEventListener(m_isolate, nullptr); | 110 v8::Debug::SetDebugEventListener(m_isolate, nullptr); |
| 106 } | 111 } |
| 107 | 112 |
| 108 bool V8DebuggerImpl::enabled() const | 113 bool V8DebuggerImpl::enabled() const |
| 109 { | 114 { |
| 110 return !m_debuggerScript.IsEmpty(); | 115 return !m_debuggerScript.IsEmpty(); |
| 111 } | 116 } |
| 112 | 117 |
| 113 int V8Debugger::contextId(v8::Local<v8::Context> context) | 118 int V8DebuggerImpl::contextId(v8::Local<v8::Context> context) |
| 114 { | 119 { |
| 115 v8::Local<v8::Value> data = context->GetEmbedderData(static_cast<int>(v8::Co
ntext::kDebugIdIndex)); | 120 v8::Local<v8::Value> data = context->GetEmbedderData(static_cast<int>(v8::Co
ntext::kDebugIdIndex)); |
| 116 if (data.IsEmpty() || !data->IsString()) | 121 if (data.IsEmpty() || !data->IsString()) |
| 117 return 0; | 122 return 0; |
| 118 String16 dataString = toProtocolString(data.As<v8::String>()); | 123 String16 dataString = toProtocolString(data.As<v8::String>()); |
| 119 if (dataString.isEmpty()) | 124 if (dataString.isEmpty()) |
| 120 return 0; | 125 return 0; |
| 121 size_t commaPos = dataString.find(","); | 126 size_t commaPos = dataString.find(","); |
| 122 if (commaPos == kNotFound) | 127 if (commaPos == kNotFound) |
| 123 return 0; | 128 return 0; |
| (...skipping 594 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 718 v8::True(m_isolate), // internal | 723 v8::True(m_isolate), // internal |
| 719 toV8String(m_isolate, String16()), // sourceMap | 724 toV8String(m_isolate, String16()), // sourceMap |
| 720 v8::True(m_isolate)); // opaqueresource | 725 v8::True(m_isolate)); // opaqueresource |
| 721 v8::ScriptCompiler::Source source(code, origin); | 726 v8::ScriptCompiler::Source source(code, origin); |
| 722 v8::Local<v8::Script> script; | 727 v8::Local<v8::Script> script; |
| 723 if (!v8::ScriptCompiler::Compile(context, &source, v8::ScriptCompiler::kNoCo
mpileOptions).ToLocal(&script)) | 728 if (!v8::ScriptCompiler::Compile(context, &source, v8::ScriptCompiler::kNoCo
mpileOptions).ToLocal(&script)) |
| 724 return v8::Local<v8::Script>(); | 729 return v8::Local<v8::Script>(); |
| 725 return script; | 730 return script; |
| 726 } | 731 } |
| 727 | 732 |
| 733 void V8DebuggerImpl::enableStackCapturingIfNeeded() |
| 734 { |
| 735 if (!m_capturingStackTracesCount) |
| 736 V8StackTraceImpl::setCaptureStackTraceForUncaughtExceptions(m_isolate, t
rue); |
| 737 ++m_capturingStackTracesCount; |
| 738 } |
| 739 |
| 740 void V8DebuggerImpl::disableStackCapturingIfNeeded() |
| 741 { |
| 742 if (!(--m_capturingStackTracesCount)) |
| 743 V8StackTraceImpl::setCaptureStackTraceForUncaughtExceptions(m_isolate, f
alse); |
| 744 } |
| 745 |
| 746 V8ConsoleMessageStorage* V8DebuggerImpl::ensureConsoleMessageStorage(int context
GroupId) |
| 747 { |
| 748 if (!m_consoleStorageMap.contains(contextGroupId)) |
| 749 m_consoleStorageMap.set(contextGroupId, wrapUnique(new V8ConsoleMessageS
torage(this, contextGroupId))); |
| 750 return m_consoleStorageMap.get(contextGroupId); |
| 751 } |
| 752 |
| 728 std::unique_ptr<V8StackTrace> V8DebuggerImpl::createStackTrace(v8::Local<v8::Sta
ckTrace> stackTrace) | 753 std::unique_ptr<V8StackTrace> V8DebuggerImpl::createStackTrace(v8::Local<v8::Sta
ckTrace> stackTrace) |
| 729 { | 754 { |
| 730 V8DebuggerAgentImpl* agent = findEnabledDebuggerAgent(m_isolate->GetCurrentC
ontext()); | 755 V8DebuggerAgentImpl* agent = findEnabledDebuggerAgent(m_isolate->GetCurrentC
ontext()); |
| 731 return V8StackTraceImpl::create(agent, stackTrace, V8StackTrace::maxCallStac
kSizeToCapture); | 756 return V8StackTraceImpl::create(agent, stackTrace, V8StackTraceImpl::maxCall
StackSizeToCapture); |
| 732 } | 757 } |
| 733 | 758 |
| 734 std::unique_ptr<V8InspectorSession> V8DebuggerImpl::connect(int contextGroupId,
protocol::FrontendChannel* channel, V8InspectorSessionClient* client, const Stri
ng16* state) | 759 std::unique_ptr<V8InspectorSession> V8DebuggerImpl::connect(int contextGroupId,
protocol::FrontendChannel* channel, V8InspectorSessionClient* client, const Stri
ng16* state) |
| 735 { | 760 { |
| 736 DCHECK(!m_sessions.contains(contextGroupId)); | 761 DCHECK(!m_sessions.contains(contextGroupId)); |
| 737 std::unique_ptr<V8InspectorSessionImpl> session = V8InspectorSessionImpl::cr
eate(this, contextGroupId, channel, client, state); | 762 std::unique_ptr<V8InspectorSessionImpl> session = V8InspectorSessionImpl::cr
eate(this, contextGroupId, channel, client, state); |
| 738 m_sessions.set(contextGroupId, session.get()); | 763 m_sessions.set(contextGroupId, session.get()); |
| 739 return std::move(session); | 764 return std::move(session); |
| 740 } | 765 } |
| 741 | 766 |
| (...skipping 20 matching lines...) Expand all Loading... |
| 762 std::unique_ptr<InspectedContext> contextOwner(new InspectedContext(this, in
fo, contextId)); | 787 std::unique_ptr<InspectedContext> contextOwner(new InspectedContext(this, in
fo, contextId)); |
| 763 InspectedContext* inspectedContext = contextOwner.get(); | 788 InspectedContext* inspectedContext = contextOwner.get(); |
| 764 m_contexts.get(info.contextGroupId)->set(contextId, std::move(contextOwner))
; | 789 m_contexts.get(info.contextGroupId)->set(contextId, std::move(contextOwner))
; |
| 765 | 790 |
| 766 if (V8InspectorSessionImpl* session = m_sessions.get(info.contextGroupId)) | 791 if (V8InspectorSessionImpl* session = m_sessions.get(info.contextGroupId)) |
| 767 session->runtimeAgent()->reportExecutionContextCreated(inspectedContext)
; | 792 session->runtimeAgent()->reportExecutionContextCreated(inspectedContext)
; |
| 768 } | 793 } |
| 769 | 794 |
| 770 void V8DebuggerImpl::contextDestroyed(v8::Local<v8::Context> context) | 795 void V8DebuggerImpl::contextDestroyed(v8::Local<v8::Context> context) |
| 771 { | 796 { |
| 772 int contextId = V8Debugger::contextId(context); | 797 int contextId = V8DebuggerImpl::contextId(context); |
| 773 int contextGroupId = getGroupId(context); | 798 int contextGroupId = getGroupId(context); |
| 799 if (m_consoleStorageMap.contains(contextGroupId)) |
| 800 m_consoleStorageMap.get(contextGroupId)->contextDestroyed(contextId); |
| 801 |
| 774 if (!m_contexts.contains(contextGroupId) || !m_contexts.get(contextGroupId)-
>contains(contextId)) | 802 if (!m_contexts.contains(contextGroupId) || !m_contexts.get(contextGroupId)-
>contains(contextId)) |
| 775 return; | 803 return; |
| 776 | 804 |
| 777 InspectedContext* inspectedContext = m_contexts.get(contextGroupId)->get(con
textId); | 805 InspectedContext* inspectedContext = m_contexts.get(contextGroupId)->get(con
textId); |
| 778 if (V8InspectorSessionImpl* session = m_sessions.get(contextGroupId)) | 806 if (V8InspectorSessionImpl* session = m_sessions.get(contextGroupId)) |
| 779 session->runtimeAgent()->reportExecutionContextDestroyed(inspectedContex
t); | 807 session->runtimeAgent()->reportExecutionContextDestroyed(inspectedContex
t); |
| 780 | 808 |
| 781 m_contexts.get(contextGroupId)->remove(contextId); | 809 m_contexts.get(contextGroupId)->remove(contextId); |
| 782 if (m_contexts.get(contextGroupId)->isEmpty()) | 810 if (m_contexts.get(contextGroupId)->isEmpty()) |
| 783 m_contexts.remove(contextGroupId); | 811 m_contexts.remove(contextGroupId); |
| 784 } | 812 } |
| 785 | 813 |
| 786 void V8DebuggerImpl::resetContextGroup(int contextGroupId) | 814 void V8DebuggerImpl::resetContextGroup(int contextGroupId) |
| 787 { | 815 { |
| 816 m_consoleStorageMap.remove(contextGroupId); |
| 788 if (V8InspectorSessionImpl* session = m_sessions.get(contextGroupId)) | 817 if (V8InspectorSessionImpl* session = m_sessions.get(contextGroupId)) |
| 789 session->reset(); | 818 session->reset(); |
| 790 m_contexts.remove(contextGroupId); | 819 m_contexts.remove(contextGroupId); |
| 791 } | 820 } |
| 792 | 821 |
| 793 void V8DebuggerImpl::willExecuteScript(v8::Local<v8::Context> context, int scrip
tId) | 822 void V8DebuggerImpl::willExecuteScript(v8::Local<v8::Context> context, int scrip
tId) |
| 794 { | 823 { |
| 795 if (V8DebuggerAgentImpl* agent = findEnabledDebuggerAgent(context)) | 824 if (V8DebuggerAgentImpl* agent = findEnabledDebuggerAgent(context)) |
| 796 agent->willExecuteScript(scriptId); | 825 agent->willExecuteScript(scriptId); |
| 797 } | 826 } |
| 798 | 827 |
| 799 void V8DebuggerImpl::didExecuteScript(v8::Local<v8::Context> context) | 828 void V8DebuggerImpl::didExecuteScript(v8::Local<v8::Context> context) |
| 800 { | 829 { |
| 801 if (V8DebuggerAgentImpl* agent = findEnabledDebuggerAgent(context)) | 830 if (V8DebuggerAgentImpl* agent = findEnabledDebuggerAgent(context)) |
| 802 agent->didExecuteScript(); | 831 agent->didExecuteScript(); |
| 803 } | 832 } |
| 804 | 833 |
| 805 void V8DebuggerImpl::idleStarted() | 834 void V8DebuggerImpl::idleStarted() |
| 806 { | 835 { |
| 807 m_isolate->GetCpuProfiler()->SetIdle(true); | 836 m_isolate->GetCpuProfiler()->SetIdle(true); |
| 808 } | 837 } |
| 809 | 838 |
| 810 void V8DebuggerImpl::idleFinished() | 839 void V8DebuggerImpl::idleFinished() |
| 811 { | 840 { |
| 812 m_isolate->GetCpuProfiler()->SetIdle(false); | 841 m_isolate->GetCpuProfiler()->SetIdle(false); |
| 813 } | 842 } |
| 814 | 843 |
| 815 std::unique_ptr<V8StackTrace> V8DebuggerImpl::captureStackTrace(size_t maxStackS
ize) | 844 bool V8DebuggerImpl::addConsoleMessage(int contextGroupId, MessageSource source,
MessageLevel level, const String16& message, const String16& url, unsigned line
Number, unsigned columnNumber, std::unique_ptr<V8StackTrace> stackTrace, int scr
iptId, const String16& requestIdentifier) |
| 816 { | 845 { |
| 817 V8DebuggerAgentImpl* agent = findEnabledDebuggerAgent(m_isolate->GetCurrentC
ontext()); | 846 if (m_muteConsoleCount) |
| 818 return V8StackTraceImpl::capture(agent, maxStackSize); | 847 return false; |
| 848 ensureConsoleMessageStorage(contextGroupId)->addMessage(wrapUnique(new V8Con
soleMessage(m_client->currentTimeMS(), source, level, message, url, lineNumber,
columnNumber, std::move(stackTrace), scriptId, requestIdentifier))); |
| 849 return true; |
| 850 } |
| 851 |
| 852 void V8DebuggerImpl::logToConsole(v8::Local<v8::Context> context, const String16
& message, protocol::Vector<v8::Local<v8::Value>>* arguments) |
| 853 { |
| 854 int contextGroupId = getGroupId(context); |
| 855 if (!contextGroupId || !m_contexts.contains(contextGroupId)) |
| 856 return; |
| 857 InspectedContext* inspectedContext = m_contexts.get(contextGroupId)->get(con
textId(context)); |
| 858 if (!inspectedContext) |
| 859 return; |
| 860 ensureConsoleMessageStorage(contextGroupId)->addMessage(V8ConsoleMessage::cr
eateForConsoleAPI(m_client->currentTimeMS(), LogMessageType, LogMessageLevel, me
ssage, arguments, captureStackTrace(false), inspectedContext)); |
| 861 } |
| 862 |
| 863 unsigned V8DebuggerImpl::promiseRejected(v8::Local<v8::Context> context, const S
tring16& errorMessage, v8::Local<v8::Value> reason, const String16& url, unsigne
d lineNumber, unsigned columnNumber, std::unique_ptr<V8StackTrace> stackTrace, i
nt scriptId) |
| 864 { |
| 865 if (m_muteConsoleCount) |
| 866 return 0; |
| 867 int contextGroupId = getGroupId(context); |
| 868 if (!contextGroupId) |
| 869 return 0; |
| 870 |
| 871 const String16 defaultMessage = "Uncaught (in promise)"; |
| 872 String16 message = errorMessage; |
| 873 if (message.isEmpty()) |
| 874 message = defaultMessage; |
| 875 else if (message.startWith("Uncaught ")) |
| 876 message = message.substring(0, 8) + " (in promise)" + message.substring(
8); |
| 877 |
| 878 m_client->messageAddedToConsole(contextGroupId, JSMessageSource, ErrorMessag
eLevel, message, url, lineNumber, columnNumber, stackTrace.get()); |
| 879 std::unique_ptr<V8ConsoleMessage> consoleMessage = wrapUnique(new V8ConsoleM
essage(m_client->currentTimeMS(), JSMessageSource, ErrorMessageLevel, message, u
rl, lineNumber, columnNumber, std::move(stackTrace), scriptId, String16())); |
| 880 unsigned id = ++m_lastConsoleMessageId; |
| 881 consoleMessage->assignId(id); |
| 882 |
| 883 protocol::Vector<v8::Local<v8::Value>> arguments; |
| 884 arguments.append(toV8String(m_isolate, defaultMessage)); |
| 885 arguments.append(reason); |
| 886 consoleMessage->addArguments(m_isolate, contextId(context), &arguments); |
| 887 |
| 888 ensureConsoleMessageStorage(contextGroupId)->addMessage(std::move(consoleMes
sage)); |
| 889 return id; |
| 890 } |
| 891 |
| 892 void V8DebuggerImpl::promiseRejectionRevoked(v8::Local<v8::Context> context, uns
igned promiseRejectionId) |
| 893 { |
| 894 if (m_muteConsoleCount) |
| 895 return; |
| 896 int contextGroupId = getGroupId(context); |
| 897 if (!contextGroupId) |
| 898 return; |
| 899 |
| 900 const String16 message = "Handler added to rejected promise"; |
| 901 m_client->messageAddedToConsole(contextGroupId, JSMessageSource, RevokedErro
rMessageLevel, message, String16(), 0, 0, nullptr); |
| 902 std::unique_ptr<V8ConsoleMessage> consoleMessage = wrapUnique(new V8ConsoleM
essage(m_client->currentTimeMS(), JSMessageSource, RevokedErrorMessageLevel, mes
sage, String16(), 0, 0, nullptr, 0, String16())); |
| 903 consoleMessage->assignRelatedId(promiseRejectionId); |
| 904 ensureConsoleMessageStorage(contextGroupId)->addMessage(std::move(consoleMes
sage)); |
| 905 } |
| 906 |
| 907 protocol::Vector<unsigned> V8DebuggerImpl::consoleMessageArgumentCounts(int cont
extGroupId) |
| 908 { |
| 909 if (!m_consoleStorageMap.contains(contextGroupId)) |
| 910 return protocol::Vector<unsigned>(); |
| 911 return m_consoleStorageMap.get(contextGroupId)->consoleMessageArgumentCounts
(); |
| 912 } |
| 913 |
| 914 std::unique_ptr<V8StackTrace> V8DebuggerImpl::captureStackTrace(bool fullStack) |
| 915 { |
| 916 if (!m_isolate->InContext()) |
| 917 return nullptr; |
| 918 |
| 919 v8::HandleScope handles(m_isolate); |
| 920 v8::Local<v8::Context> context = m_isolate->GetCurrentContext(); |
| 921 int contextGroupId = getGroupId(context); |
| 922 if (!contextGroupId) |
| 923 return nullptr; |
| 924 |
| 925 V8InspectorSessionImpl* session = m_sessions.get(contextGroupId); |
| 926 size_t stackSize = fullStack ? V8StackTraceImpl::maxCallStackSizeToCapture :
1; |
| 927 if (session && session->consoleAgent()->enabled()) |
| 928 stackSize = V8StackTraceImpl::maxCallStackSizeToCapture; |
| 929 |
| 930 V8DebuggerAgentImpl* agent = findEnabledDebuggerAgent(context); |
| 931 return V8StackTraceImpl::capture(agent, stackSize); |
| 819 } | 932 } |
| 820 | 933 |
| 821 v8::Local<v8::Context> V8DebuggerImpl::regexContext() | 934 v8::Local<v8::Context> V8DebuggerImpl::regexContext() |
| 822 { | 935 { |
| 823 if (m_regexContext.IsEmpty()) | 936 if (m_regexContext.IsEmpty()) |
| 824 m_regexContext.Reset(m_isolate, v8::Context::New(m_isolate)); | 937 m_regexContext.Reset(m_isolate, v8::Context::New(m_isolate)); |
| 825 return m_regexContext.Get(m_isolate); | 938 return m_regexContext.Get(m_isolate); |
| 826 } | 939 } |
| 827 | 940 |
| 828 void V8DebuggerImpl::discardInspectedContext(int contextGroupId, int contextId) | 941 void V8DebuggerImpl::discardInspectedContext(int contextGroupId, int contextId) |
| (...skipping 11 matching lines...) Expand all Loading... |
| 840 return nullptr; | 953 return nullptr; |
| 841 return m_contexts.get(contextGroupId); | 954 return m_contexts.get(contextGroupId); |
| 842 } | 955 } |
| 843 | 956 |
| 844 V8InspectorSessionImpl* V8DebuggerImpl::sessionForContextGroup(int contextGroupI
d) | 957 V8InspectorSessionImpl* V8DebuggerImpl::sessionForContextGroup(int contextGroupI
d) |
| 845 { | 958 { |
| 846 return contextGroupId ? m_sessions.get(contextGroupId) : nullptr; | 959 return contextGroupId ? m_sessions.get(contextGroupId) : nullptr; |
| 847 } | 960 } |
| 848 | 961 |
| 849 } // namespace blink | 962 } // namespace blink |
| OLD | NEW |