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/44f04d05-40c2-4f09-ba91-f05139cccb4cn%40googlegroups.com.