Hi Immanuel, Seems the messages that come from V8 instance are cut off, maybe because of sockpp. They are also not complete, there should be a response for each request but in your case there are only 3 responses.
The logic to wait the V8 instance should be done in `runMessageLoopOnPause` method. In my example, I'm calling a Boost method to get a new message from CDT. So, until there is a new message the V8 instance would wait. On Friday, August 21, 2020 at 10:10:15 AM UTC+2, Immanuel Haffner wrote: > > Here is what the network messages in CDT look like: > > [image: cdt_network.png] > > I guess the execution doesn't wait for CDT. My WebAssembly function is > executed right away and the connection is closed. > How do I make my `v8::Isolate` instance wait for commands from CDT? > > Am Donnerstag, 20. August 2020 22:04:15 UTC+2 schrieb Elmi Ahmadov: >> >> Seems you've managed to make a communication between CDT and your server. >> I also checked `sockpp` which does not support websocket protocol out of >> box. Probably, you should implement all required parts yourself. >> >> I'm using Google Groups old UI which allows me to add image to the post, >> it's next to the `Link`: >> >> [image: Screenshot from 2020-08-20 21-58-22.png] >> >> >> But I also couldn't find it in the new UI, if you're using the new UI you >> can switch back to the old UI, click settings (gear icon) at the top of the >> page and click "Return to classic Google Groups", then you can attach an >> image. >> >> On Thursday, August 20, 2020 at 1:54:43 PM UTC+2, Immanuel Haffner wrote: >>> >>> 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/f46610d5-411b-4ae2-88eb-4f4413ed189do%40googlegroups.com.