Turns out the Wasm code not showing up is a known CDT bug. After updating and restarting chromium I see the Wasm code in the CDT debugger and can set breakpoints. Brilliant!!!
Thanks again very much for your great help. I really appreciate it. Am Freitag, 11. September 2020 10:20:55 UTC+2 schrieb Immanuel Haffner: > > Hi Elmi, > > I found the biggest problem yet: I need to create a `v8::Script` and > invoke `run()` so that it appears in the CDT debugger. To do so, I create a > temporary JS file with (roughly) the code you provided and the Wasm binary > code inside the JS in form of a Uint8Array. I can now see the JS code that > instantiates the module and invokes `run()`. > > [image: cdt_debugging.png] > However, when I set a breakpoint at `run()` and then step inside, I don't > see any code. I see the scope and heap. But I'd really like to see the Wasm > (in Wast form). > > I think I did a bad job explaining what I'm after. I am receiving a > program in some graph form. To execute the program, I directly compile it > to Wasm via Binaryen. Then I want to execute it in embedded V8. Because my > graph to Wasm compiler is WIP, I need a debugger to investigate some bugs. > But there is more to that. I patched V8 such that I can replace the memory > of a Wasm instance. This allows the embedder (C++ code) and Wasm module to > operate on the same memory. No more need to copy data back and forth. > Basically, the embedder instantiates a Wasm module through the V8 API. > Then, with my patched in function, the embedder provides a pointer to a > memory location as well as the size in bytes and this region is then used > as the module instance's linear memory. > > I will also have to see how I can "patch" the module instance's memory in > the approach I now use for debugging. Since it's a JS script, the patching > of the instance's memory does not happen anymore. Maybe I can somehow hook > the `WebAssembly.Instance` constructor or provide a JS function that calls > back into the embedder to perform the patching? We will see... > > Thanks a lot! > Kind regards > > Am Donnerstag, 10. September 2020 17:45:16 UTC+2 schrieb Elmi Ahmadov: >> >> Do you need to execute `Run()` on JS side or C++ side and in which side >> do you need the result of `Run()`? You can add a global method in JS side >> to fetch WASM binary from memory and you can execute on JS side as follows: >> >> // in js >> const wasmBinary = getWASMFromMemory(); // -> this will be a new global >> method to transfer WASM binary to JS side which you need to implement in V8 >> C++ side. >> const module = await WebAssembly.compile(wamBinary); >> const instance = await WebAssembly.instantiate(module, importsObject); >> instance.exports.Run(); >> >> Maybe I got wrong idea what you want. >> >> On Thursday, September 10, 2020 at 11:00:46 AM UTC+2, Immanuel Haffner >> wrote: >>> >>> Thanks a lot for providing the example. You are creating a `v8::Script` >>> instance of the code that fetches and executes the WebAssembly stored in a >>> wasm file. In my setting, I cannot do that. I have only the in-memory >>> binary representation of the compiled Wasm. I don't see how to create a >>> `v8::Script` for that such that I could invoke `Run()`. Maybe this is why I >>> can't see the Wasm in CDT... >>> >>> Am Mittwoch, 9. September 2020 22:21:06 UTC+2 schrieb Elmi Ahmadov: >>>> >>>> Hi Immanuel, >>>> >>>> Unfortunately, I've never worked with WebAssembly until today :) and I >>>> conducted a simple experiment and I improved my example to support >>>> WebAssembly (but very naively), you can see my changes here: >>>> https://github.com/ahmadov/v8_inspector_example/tree/wasm >>>> >>>> I have successfully established a debugger session: >>>> >>>> [image: Screenshot from 2020-09-09 21-47-45.png] >>>> and I can also see the compiled WASM code in CDT (you can see in the >>>> left side under `wasm`): >>>> >>>> [image: Screenshot from 2020-09-09 21-42-31.png] >>>> >>>> Also, I can set a breakpoint in the WASM code! >>>> >>>> [image: Screenshot from 2020-09-09 21-46-09.png] >>>> >>>> I used this `emcc` tool ( >>>> https://emscripten.org/docs/tools_reference/emcc.html) to compile C >>>> source code to WASM binary file. >>>> I added a simple C source code in `example` folder and I compiled the >>>> source code via this following command: >>>> >>>> emcc --no-entry -Os -s add.c -o add.wasm >>>> >>>> I also tried to compile the WASM code with *`-g`* flag which should >>>> include source-map to the original C source file, I saw the file name >>>> *add.c* in CDT but I didn't see the content. >>>> >>>> If you want to see the result yourself, first compile *add.c* to >>>> generate *add.wasm* then run it. Hope this will help. >>>> >>>> Best regards. >>>> >>>> On Wednesday, September 9, 2020 at 3:56:57 PM UTC+2, Immanuel Haffner >>>> wrote: >>>>> >>>>> I think I am close! The embedded V8 is connected to CDT. However, I >>>>> can't see the executed Wasm code. I use Binaryen to generate Wasm code >>>>> and >>>>> write its binary representation into a byte array. Then I create a new >>>>> `ArrayBuffer` from that byte array and pass it to the >>>>> `WebAssembly.Module` >>>>> constructor to create a Wasm module object. Last, I call >>>>> `WebAssembly.Instance(module, imports)` to instantiate the just created >>>>> Wasm module with the given imports. Then I call one of the exported >>>>> functions of the module instance. This is the point where I want to >>>>> start >>>>> debugging! However, calling into the function directly executes it >>>>> entirely. (Setting break points didn't help.) I also tried making the >>>>> function globally accessible so I could call it from the JS shell, but no >>>>> success in doing so. >>>>> >>>>> I saw from your example that you implemented `V8InspectorListener` to >>>>> provide the source map to CDT. How can I provide the source of my Wasm >>>>> code >>>>> to CDT? There is no source file and no source map. There is only the >>>>> in-memory representation of Binaryen and the binary format in the byte >>>>> array. I could, however, emit the textual representation of the Wasm >>>>> code. >>>>> No clue how to provide that to CDT, though. >>>>> >>>>> Please help :) >>>>> >>>>> Am Dienstag, 8. September 2020 10:30:26 UTC+2 schrieb Immanuel Haffner: >>>>>> >>>>>> I somehow thought that the WebSocket connections needs to be in a >>>>>> separate thread, so the communication with CDT can happen concurrently. >>>>>> After reinspecting your code I found that this is not the case. (I don't >>>>>> know why I had that idea.) The threading was causing my quite some >>>>>> headache. The execution of my Wasm would proceed without waiting for the >>>>>> inspector. Anyways, now I'm having problems how to debug my Wasm code. >>>>>> >>>>>> Without the inspector, I'd execute my Wasm code as follows: >>>>>> /* Invoke the exported function `run` of the module. */ >>>>>> args_t args { v8::Int32::New(isolate_, wasm_context.id), }; >>>>>> const uint32_t head_of_heap = >>>>>> run->Call(context, context->Global(), 1, >>>>>> args).ToLocalChecked().As<v8::Int32>()->Value(); >>>>>> >>>>>> However, with the inspector, I don't know how to "schedule" the call >>>>>> to `run` for debugging. Do I have to invoke this function from the CDT >>>>>> console? I tried to register `run` in `Global` to call it, but I'm >>>>>> failing >>>>>> to do so. Further, I cannot see the source of the Wasm module in CDT. >>>>>> Any >>>>>> clues? >>>>>> >>>>>> Regards >>>>>> >>>>>> >>>>>> Am Montag, 7. September 2020 14:40:02 UTC+2 schrieb Immanuel Haffner: >>>>>>> >>>>>>> Hi Elmi, >>>>>>> >>>>>>> sorry for being quiet for two weeks. I was on vacation. I will >>>>>>> investigate your latest remarks regarding string conversion and the >>>>>>> message >>>>>>> loop. I will reply here. Would you be available for a call? Via >>>>>>> Discord, >>>>>>> Zoom, or the like... >>>>>>> >>>>>>> Regards >>>>>>> >>>>>>> Am Mittwoch, 26. August 2020 21:58:31 UTC+2 schrieb Elmi Ahmadov: >>>>>>>> >>>>>>>> Hi Immanuel, >>>>>>>> >>>>>>>> Do you have any progress? Did you solve "Connection is closed" >>>>>>>> issue? >>>>>>>> >>>>>>>> On Friday, August 21, 2020 at 4:55:19 PM UTC+2, Elmi Ahmadov wrote: >>>>>>>>> >>>>>>>>> There could a few things that influence cut off messages, could >>>>>>>>> you please post how do you convert V8 `StringBuffer` message to a >>>>>>>>> string >>>>>>>>> format that Boost can send to CDT. >>>>>>>>> >>>>>>>>> you have to implement `runMessageLoopOnPause` and >>>>>>>>> `schedulePauseOnNextStatement` methods to stop the execution. >>>>>>>>> If you don't implement your waiting logic in >>>>>>>>> `runMessageLoopOnPause` it will just execute without waiting a user >>>>>>>>> action >>>>>>>>> (I changed my example to see how it behaves). >>>>>>>>> >>>>>>>>> If you have an example WebAssembly source code maybe you can use >>>>>>>>> my example to see how it works. >>>>>>>>> Analyzing the WebSocket messages really helps. I remember that I >>>>>>>>> spend almost one or two weeks to understand how it works. >>>>>>>>> >>>>>>>>> On Friday, August 21, 2020 at 11:56:30 AM UTC+2, Immanuel Haffner >>>>>>>>> wrote: >>>>>>>>>> >>>>>>>>>> Hi Elmi, >>>>>>>>>> >>>>>>>>>> I am using boost web sockets now, just like you do ;) So cut off >>>>>>>>>> messages are not the fault of sockpp. In the "Console" tab of CDT i >>>>>>>>>> see an >>>>>>>>>> error >>>>>>>>>> >>>>>>>>>> Connection is closed, can't dispatch pending call >>>>>>>>>> >>>>>>>>>> I suspect that V8 simply finished execution, in which case I stop >>>>>>>>>> the WebSocket server and dispose of the inspector. >>>>>>>>>> >>>>>>>>>> To be precise, I want to debug a function of a WebAssembly >>>>>>>>>> module, called "run". This is how I invoke the function through the >>>>>>>>>> V8 API: >>>>>>>>>> /* Get the exports of the created WebAssembly instance. */ >>>>>>>>>> auto exports = instance->Get(context, >>>>>>>>>> V8STR("exports")).ToLocalChecked().As<v8::Object>(); >>>>>>>>>> auto run = exports->Get(context, >>>>>>>>>> V8STR("run")).ToLocalChecked().As<v8::Function>(); >>>>>>>>>> >>>>>>>>>> /* Invoke the exported function `run` of the module. */ >>>>>>>>>> args_t args { v8::Int32::New(isolate_, wasm_context.id), }; >>>>>>>>>> const uint32_t head_of_heap = run->Call(context, >>>>>>>>>> context->Global(), 1, >>>>>>>>>> args).ToLocalChecked().As<v8::Int32>()->Value(); >>>>>>>>>> >>>>>>>>>> Now how can I break/pause on entry to that function and inspect >>>>>>>>>> it in CDT? I tried invoking >>>>>>>>>> v8_inspector_session->schedulePauseOnNextStatement(...); >>>>>>>>>> But that did not help... >>>>>>>>>> >>>>>>>>>> I am confused and lost :/ >>>>>>>>>> Your help is very appreciated Elmi >>>>>>>>>> >>>>>>>>>> Am Freitag, 21. August 2020 11:06:31 UTC+2 schrieb Elmi Ahmadov: >>>>>>>>>>> >>>>>>>>>>> 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/62c1fd4b-573c-43da-8e47-96ee47412e55o%40googlegroups.com.