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
[email protected]
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 [email protected].
To view this discussion on the web visit
https://groups.google.com/d/msgid/v8-users/44f04d05-40c2-4f09-ba91-f05139cccb4cn%40googlegroups.com.