Hi Elmi,

thank you for checking. My biggest mistage was to write directly to a 
socket rather than use the WebSocket protocol. After doing so, i now see 
some messages in CDT. However, there are only 8 green and one last red 
message. I suppose the last message wasn't sent in full. The second last 
message was "Runtime.runIfWaitingForDebugger". There is no 
`Debugger.scriptExecuted` message, though.

Checking V8 code I couldn't find `schedulePauseOnNextStatement`, who is 
invoking that?

How do I attach an image to a Google Groups post?

Elmi Ahmadov schrieb am Donnerstag, 20. August 2020 um 11:59:17 UTC+2:

> I checked your code and you're missing 
> `runMessageLoopOnMessage`/`quitMessageLoopOnPause` and 
> `schedulePauseOnNextStatement` (this could be redundant), but in general, 
> these methods are necessary. in `runMessageLoopOnPause` method, you should 
> block the thread until there is a new message from CDT, in case there is a 
> breakpoint and CDT requires user action.
> Maybe your code does not wait for a user action and execution is done very 
> quickly.
>
> Could you please post WS messages from CDT Network monitor tab? There 
> should be such response messages: *`Debugger.scriptExecuted`* and 
> *`Debugger.paused`*.
> And one important thing is you have to execute your code after you got a 
> *`**Runtime.runIfWaitingForDebugger` *message from CDT.
>
>
> On Thursday, August 20, 2020 at 10:36:30 AM UTC+2 haffner....@gmail.com 
> wrote:
>
>> Ok, I figured the cause for the segmentation violation. I must dispose of 
>> the inspector and the session and channel before disposing of the isolate.  
>> I am still left with "WebSocket disconnected". The CDT Network monitor says 
>> "Connection closed before receiving a handshake response".  Maybe I did 
>> something wrong establishing a TCP connection?
>>
>> Immanuel Haffner schrieb am Donnerstag, 20. August 2020 um 10:07:27 UTC+2:
>>
>>>
>>> Hi again,
>>>
>>> I figured that the `chome-devtools://` part doesn't work in Chromium.  
>>> Using `devtools://` instead works. However, I get a segmentation violation. 
>>>
>>> Here is the code I wrote to connect the V8 inspector:
>>>
>>>     struct ServerChannel : v8_inspector::V8Inspector::Channel
>>>     {
>>>         private:
>>>         sockpp::tcp_socket *socket_;
>>>
>>>         public:
>>>         ServerChannel() { }
>>>
>>>         void set_socket(sockpp::tcp_socket *socket) { socket_ = socket; }
>>>
>>>         private:
>>>         void sendResponse(int, 
>>> std::unique_ptr<v8_inspector::StringBuffer> message) override {
>>>             auto v8_sv = message->string();
>>>             socket_->write_n(v8_sv.characters8(), v8_sv.length());
>>>         }
>>>
>>>         void 
>>> sendNotification(std::unique_ptr<v8_inspector::StringBuffer> message) 
>>> override {
>>>             auto v8_sv = message->string();
>>>             socket_->write_n(v8_sv.characters8(), v8_sv.length());
>>>         }
>>>
>>>         void flushProtocolNotifications() override { }
>>>     };
>>>
>>>     struct MyV8InspectorClient : v8_inspector::V8InspectorClient
>>>     {
>>>         private:
>>>         sockpp::tcp_acceptor acceptor_;
>>>         std::unique_ptr<ServerChannel> channel_;
>>>         std::unique_ptr<v8_inspector::V8Inspector> inspector_;
>>>         std::unique_ptr<v8_inspector::V8InspectorSession> session_;
>>>         int16_t port_;
>>>
>>>         public:
>>>         MyV8InspectorClient(int16_t port, v8::Isolate *isolate)
>>>             : acceptor_(port)
>>>             , port_(port)
>>>         {
>>>             if (not acceptor_)
>>>                 throw std::runtime_error("failed to initalize TCP 
>>> server");
>>>
>>>             channel_ = std::make_unique<ServerChannel>();
>>>             inspector_ = v8_inspector::V8Inspector::create(isolate, 
>>> this);
>>>
>>>             std::string state("mutable");
>>>             v8_inspector::StringView sv(reinterpret_cast<const 
>>> uint8_t*>(state.c_str()), state.length());
>>>             session_ = inspector_->connect(
>>>                 /* contextGroupId= */ 1,
>>>                 /* channel=        */ channel_.get(),
>>>                 /* state=          */ sv
>>>             );
>>>         }
>>>
>>>         MyV8InspectorClient(const MyV8InspectorClient&) = delete;
>>>         MyV8InspectorClient(MyV8InspectorClient&&) = default;
>>>
>>>         ~MyV8InspectorClient() {
>>>             session_.reset();
>>>             inspector_.reset();
>>>             channel_.reset();
>>>         }
>>>
>>>         void onMessage(std::string_view sv) {
>>>             v8_inspector::StringView msg(reinterpret_cast<const 
>>> uint8_t*>(sv.data()), sv.length());
>>>             session_->dispatchProtocolMessage(msg);
>>>         }
>>>
>>>         void launch() {
>>>             std::cout << "WebSocket based Inspector Agent started.\n"
>>>                       << "Open the following link in your 
>>> Chrome/Chromium browser:\n\n\t"
>>>                       << 
>>> "devtools://devtools/bundled/inspector.html?experiments=true&v8only=true&ws=
>>> 127.0.0.1:" <<  port_
>>>                       << '\n' << std::endl;
>>>
>>>             auto socket = 
>>> std::make_unique<sockpp::tcp_socket>(acceptor_.accept());
>>>             if (not *socket)
>>>                 throw std::runtime_error("failed to establish connection 
>>> to TCP client");
>>>             channel_->set_socket(socket.get());
>>>
>>>             auto thread = 
>>> std::thread([this](std::unique_ptr<sockpp::tcp_socket> socket) {
>>>                 uint8_t buf[512];
>>>                 std::vector<uint8_t> msg;
>>>                 msg.reserve(512);
>>>                 std::size_t n;
>>>
>>>                 for (;;) {
>>>                     std::cerr << "receiving bytes..." << std::endl;
>>>                     while ((n = socket->read_n(buf, ARR_SIZE(buf))) > 0)
>>>                         msg.insert(msg.end(), buf, buf + n); // append 
>>> recently read bytes to msg
>>>                     if (not msg.empty()) {
>>>                         std::cerr << "the received message is " << 
>>> msg.size() << " bytes" << std::endl;
>>>                         std::string_view 
>>> sv(reinterpret_cast<char*>(&msg[0]), msg.size());
>>>                         this->onMessage(sv);
>>>                         msg.clear();
>>>                     }
>>>                     std::this_thread::yield();
>>>                 }
>>>             },
>>>             std::move(socket));
>>>             thread.detach();
>>>         }
>>>     };
>>>
>>> It's mostly taken from your example and condensed into a single class.  
>>> Instead of boost, I use sockpp for socket programming.i
>>>
>>> After creating a `v8::Isolate`, I do the following:
>>>
>>>         inspector_ = std::make_unique<MyV8InspectorClient>(cdt_port, 
>>> isolate_);
>>>         inspector_->launch();
>>>
>>> However, when connecting to the inspector it says "WebSocket 
>>> disconnected" and the application crashes with a segmentation violation:
>>>
>>>     AddressSanitizer:DEADLYSIGNAL
>>>     =================================================================
>>>     ==13072==ERROR: AddressSanitizer: SEGV on unknown address 
>>> 0x1d580000a838 (pc 0x561c8173e6b4 bp 0x7fff75fa6430 sp 0x7fff75fa6430 T0)
>>>     ==13072==The signal is caused by a READ memory access.
>>>         #0 0x561c8173e6b4 in v8::Isolate::GetHeapProfiler() 
>>> ../../../../../third-party/v8/v8/src/execution/isolate.h:1059:48
>>>         #1 0x561c82d3fd77 in 
>>> v8_inspector::V8HeapProfilerAgentImpl::stopTrackingHeapObjectsInternal() 
>>> ../../../../../third-party/v8/v8/src/inspector/v8-heap-profiler-agent-impl.cc:316:14
>>>         #2 0x561c82d3feb9 in 
>>> v8_inspector::V8HeapProfilerAgentImpl::disable() 
>>> ../../../../../third-party/v8/v8/src/inspector/v8-heap-profiler-agent-impl.cc:204:3
>>>         #3 0x561c8208f095 in 
>>> v8_inspector::V8InspectorSessionImpl::~V8InspectorSessionImpl() 
>>> ../../../../../third-party/v8/v8/src/inspector/v8-inspector-session-impl.cc:151:24
>>>         #4 0x561c8208f33d in 
>>> v8_inspector::V8InspectorSessionImpl::~V8InspectorSessionImpl() 
>>> ../../../../../third-party/v8/v8/src/inspector/v8-inspector-session-impl.cc:147:51
>>>         #5 0x561c80ec9eff in 
>>> std::default_delete<v8_inspector::V8InspectorSession>::operator()(v8_inspector::V8InspectorSession*)
>>>  
>>> const 
>>> /usr/bin/../lib64/gcc/x86_64-pc-linux-gnu/10.1.0/../../../../include/c++/10.1.0/bits/unique_ptr.h:84:2
>>>         #6 0x561c80ec9d3e in 
>>> std::__uniq_ptr_impl<v8_inspector::V8InspectorSession, 
>>> std::default_delete<v8_inspector::V8InspectorSession> 
>>> >::reset(v8_inspector::V8InspectorSession*) 
>>> /usr/bin/../lib64/gcc/x86_64-pc-linux-gnu/10.1.0/../../../../include/c++/10.1.0/bits/unique_ptr.h:181:4
>>>         #7 0x561c80eca183 in 
>>> std::unique_ptr<v8_inspector::V8InspectorSession, 
>>> std::default_delete<v8_inspector::V8InspectorSession> 
>>> >::reset(v8_inspector::V8InspectorSession*) 
>>> /usr/bin/../lib64/gcc/x86_64-pc-linux-gnu/10.1.0/../../../../include/c++/10.1.0/bits/unique_ptr.h:455:7
>>>         #8 0x561c80ec7193 in 
>>> db::v8_helper::MyV8InspectorClient::~MyV8InspectorClient() 
>>> /home/immanuel/Documents/Work/PhD/mutable/mutable/build/debug/../../src/backend/V8Platform.hpp:74:18
>>>         #9 0x561c80ec723b in 
>>> db::v8_helper::MyV8InspectorClient::~MyV8InspectorClient() 
>>> /home/immanuel/Documents/Work/PhD/mutable/mutable/build/debug/../../src/backend/V8Platform.hpp:73:28
>>>         #10 0x561c80eb361f in 
>>> std::default_delete<db::v8_helper::MyV8InspectorClient>::operator()(db::v8_helper::MyV8InspectorClient*)
>>>  
>>> const 
>>> /usr/bin/../lib64/gcc/x86_64-pc-linux-gnu/10.1.0/../../../../include/c++/10.1.0/bits/unique_ptr.h:84:2
>>>         #11 0x561c80eaede6 in 
>>> std::unique_ptr<db::v8_helper::MyV8InspectorClient, 
>>> std::default_delete<db::v8_helper::MyV8InspectorClient> >::~unique_ptr() 
>>> /usr/bin/../lib64/gcc/x86_64-pc-linux-gnu/10.1.0/../../../../include/c++/10.1.0/bits/unique_ptr.h:360:4
>>>         #12 0x561c80ea6e97 in db::V8Platform::~V8Platform() 
>>> /home/immanuel/Documents/Work/PhD/mutable/mutable/build/debug/../../src/backend/V8Platform.cpp:221:1
>>>         #13 0x561c80ea6f2b in db::V8Platform::~V8Platform() 
>>> /home/immanuel/Documents/Work/PhD/mutable/mutable/build/debug/../../src/backend/V8Platform.cpp:218:1
>>>         #14 0x561c80e9ea3f in 
>>> std::default_delete<db::WasmPlatform>::operator()(db::WasmPlatform*) const 
>>> /usr/bin/../lib64/gcc/x86_64-pc-linux-gnu/10.1.0/../../../../include/c++/10.1.0/bits/unique_ptr.h:84:2
>>>         #15 0x561c80e9e8f6 in std::unique_ptr<db::WasmPlatform, 
>>> std::default_delete<db::WasmPlatform> >::~unique_ptr() 
>>> /usr/bin/../lib64/gcc/x86_64-pc-linux-gnu/10.1.0/../../../../include/c++/10.1.0/bits/unique_ptr.h:360:4
>>>         #16 0x561c80e8efbd in db::WasmBackend::~WasmBackend() 
>>> /home/immanuel/Documents/Work/PhD/mutable/mutable/build/debug/../../src/backend/WebAssembly.hpp:110:8
>>>         #17 0x561c80e8efeb in db::WasmBackend::~WasmBackend() 
>>> /home/immanuel/Documents/Work/PhD/mutable/mutable/build/debug/../../src/backend/WebAssembly.hpp:110:8
>>>         #18 0x561c80ccf1ff in 
>>> std::default_delete<db::Backend>::operator()(db::Backend*) const 
>>> /usr/bin/../lib64/gcc/x86_64-pc-linux-gnu/10.1.0/../../../../include/c++/10.1.0/bits/unique_ptr.h:84:2
>>>         #19 0x561c80ca8b16 in std::unique_ptr<db::Backend, 
>>> std::default_delete<db::Backend> >::~unique_ptr() 
>>> /usr/bin/../lib64/gcc/x86_64-pc-linux-gnu/10.1.0/../../../../include/c++/10.1.0/bits/unique_ptr.h:360:4
>>>         #20 0x561c80c86dd9 in process_stream(std::istream&, char const*, 
>>> db::Diagnostic) 
>>> /home/immanuel/Documents/Work/PhD/mutable/mutable/build/debug/../../src/shell.cpp:151:13
>>>         #21 0x561c80c9a265 in main 
>>> /home/immanuel/Documents/Work/PhD/mutable/mutable/build/debug/../../src/shell.cpp:675:13
>>>         #22 0x7f6259a37001 in __libc_start_main 
>>> (/usr/lib/libc.so.6+0x27001)
>>>         #23 0x561c80ba722d in _start 
>>> (/home/immanuel/Documents/Work/PhD/mutable/mutable/build/debug/bin/shell+0x117222d)
>>>
>>>     AddressSanitizer can not provide additional info.
>>>     SUMMARY: AddressSanitizer: SEGV 
>>> ../../../../../third-party/v8/v8/src/execution/isolate.h:1059:48 in 
>>> v8::Isolate::GetHeapProfiler()
>>>
>>> Can you spot what's going wrong?  I did not override 
>>> `V8InspectorClientImpl::runMessageLoopOnPause` like you did. Is this 
>>> necessary?
>>>
>>> Kind regards,
>>> Immanuel
>>> Elmi Ahmadov schrieb am Mittwoch, 19. August 2020 um 21:40:58 UTC+2:
>>>
>>>> Dear Immanuel,
>>>>
>>>> You've got the right idea from my example code. You need a websocket to 
>>>> create a communication channel between V8 Inspector and CDT.
>>>> The URL to debug the code is usually as follows and it works for me.
>>>>
>>>> devtools:
>>>> //devtools/bundled/inspector.html?experiments=true&v8only=true&ws=IP:WebSocketPort
>>>>
>>>> Without a minimal sample code it's difficult to say what you're 
>>>> missing. 
>>>> You can also use Chrome DevTools Network Activity tab (you need to open 
>>>> another Inspector console, see the screenshot), just filter *WS* to 
>>>> see what happens between your server and CDT, which helped me a lot.
>>>>  
>>>>
>>>> [image: Screenshot from 2020-08-19 21-37-48.png]
>>>>
>>>> There is another Chrome built-in feature that helped me is *Protocol 
>>>> Monitor*, you can here how to enable it: 
>>>> https://chromedevtools.github.io/devtools-protocol/
>>>>
>>>> On Wednesday, August 19, 2020 at 4:17:00 PM UTC+2, Immanuel Haffner 
>>>> wrote:
>>>>>
>>>>>
>>>>> Dear Elmi,
>>>>>
>>>>> thank you for your reply. I had a long look at your example. To be 
>>>>> honest, I find it a bit bloatet.
>>>>>
>>>>> Let me phrase in my own words what I have learned from your code:
>>>>>
>>>>> 1) I need a socket to receive messages from CDT and send responses 
>>>>> back to CDT.
>>>>> 2) I must implement `v8_inspector::V8Inspector::Channel` to have 
>>>>> `sendResponse()` and `sendNotification()` send the respective message 
>>>>> over 
>>>>> the socket to CDT.
>>>>> 3) I need an instance of `v8_inspector::V8InspectorClient`. I am not 
>>>>> sure whether I must overwrite anything from this class in a subclass. I 
>>>>> think the base class is actually fine...
>>>>> 4) I must use `v8_inspector::V8Inspector::create()` to create an 
>>>>> instance of `v8_inspector::V8Inspector`. I believe this is where all the 
>>>>> inspector logic is implemented...
>>>>> 5) Using the `V8Inspector` instance I create a 
>>>>> `v8_inspector::V8InspectorSession` by calling `connect()`. Here I must 
>>>>> pass 
>>>>> a reference to an instance of my `v8_inspector::V8Inspector::Channel` 
>>>>> subclass.
>>>>> This was the basic setup. Now it's time to run the server loop.
>>>>> 6) In a detached thread, read from the socket and pass the message on 
>>>>> by invoking `dispatchProtocolMessage()` on my instance 
>>>>> of `v8_inspector::V8InspectorSession`.
>>>>>
>>>>> When running my code, the TCP acceptor is set up and waiting for a 
>>>>> client. I visit `localhost:<PORT>` with Chromium (the chrome-devtool:// 
>>>>> links just won't work). Then my application executes the WebAssembly and 
>>>>> the browser says the page isn't working (ERR_EMPTY_RESPONSE).
>>>>>
>>>>> What am I missing?
>>>>> Elmi Ahmadov schrieb am Mittwoch, 19. August 2020 um 10:21:38 UTC+2:
>>>>>
>>>>>> Hi.
>>>>>>
>>>>>> I have an example project how to use V8 inspector API: 
>>>>>> https://github.com/ahmadov/v8_inspector_example. Hope this would 
>>>>>> help.
>>>>>>
>>>>>> Best regards
>>>>>>
>>>>>> On Wednesday, August 19, 2020 at 10:11:00 AM UTC+2, Immanuel Haffner 
>>>>>> wrote:
>>>>>>>
>>>>>>> Hi all,
>>>>>>>
>>>>>>> I followed this V8 documentation [1] to embed V8 into my 
>>>>>>> application. The application compiles inputs to WebAssembly modules and 
>>>>>>> executes them in embedded V8.  Now I would like to debug these 
>>>>>>> WebAssembly 
>>>>>>> modules.  Searching online brought me to ChromeDevTools and the 
>>>>>>> v8-inspector API.  I mostly followed this guide [2] to set up a 
>>>>>>> `V8InspectorSession` and implemented the `V8Inspector::Channel` 
>>>>>>> interface 
>>>>>>> by creating a TCP server, waiting for a connection, and then in 
>>>>>>> `sendResponse()` and `sendNotification()` I simply send the message 
>>>>>>> over 
>>>>>>> the TCP socket.
>>>>>>>
>>>>>>> To debug, I launch chromium and connect to localhost on the port 
>>>>>>> where the TCP server was created. Sadly, this doesn't work. The 
>>>>>>> `sendResponse()` and `sendNotification()` methods are never invoked.
>>>>>>>
>>>>>>> Can someone please point me to a tutorial or give me some guidance?
>>>>>>>
>>>>>>> Thanks,
>>>>>>> Immanuel
>>>>>>>
>>>>>>> [1] https://v8.dev/docs/embed
>>>>>>> [2] 
>>>>>>> https://hyperandroid.com/2020/02/12/v8-inspector-from-an-embedder-standpoint/
>>>>>>>
>>>>>>

-- 
-- 
v8-users mailing list
v8-users@googlegroups.com
http://groups.google.com/group/v8-users
--- 
You received this message because you are subscribed to the Google Groups 
"v8-users" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to v8-users+unsubscr...@googlegroups.com.
To view this discussion on the web visit 
https://groups.google.com/d/msgid/v8-users/7eac7bfb-e40e-4b26-8ffe-3503a6f248d9n%40googlegroups.com.

Reply via email to