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.