 Hello, my name is Ngoza Stepanyan, and I am a WebAssembly developer at Advocated Google. Today we are going to talk about the WebAssembly debugging and look at some of the improvements that MScript and Chrome DevTools have made this in this area for C++ applications. First of all, let's take a look at the basic debugging experience. For this example, let me create a C library for Calculus Fibonacci numbers. So I'm defining an expert function FIB. It accepts a single parameter, an index at which we want to get the Fibonacci number. And the body itself is a fairly straightforward implementation of the algorithm, where each next number is summed in the previous two. On the HTML side, I'm importing the JavaScript generated by MScript and initializing it, and once it's done, I'm calling the exported function with some sample index at the same time. Now we need to compile this module. So I'm invoking MCC with Fibonacci.c, the file name, and I'm passing some parameters to ensure that it generates an ES module. And I'm building it with optimizations enabled. Now when I go to Chrome, I can see the result in the console, as I would expect. And I can go to the sources panel. When I do that, on the left, I can see the generated JavaScript and WebAssembly files. And I can set a break point at my entry point. And when I do that, it will stop there. And from there, I can step into the MScript generated JavaScript. When I step in again, I can jump right away from JavaScript into the generated WebAssembly module. Now what I see here is a raw disassembly view of the WebAssembly module. And it looks quite scary, but luckily it's not something that most developers will need to deal with, as it's the most basic debugging experience that you can get without any help from Compiler. So you can see that DevTools has a helpful generative function name for us that is shown up in call stacks and disassembly. It based it on the export name so that even when you don't have any debugging information attached, you still at least get readable stack traces. We can also see that our parameter got medical less than 4.0 and we can even scroll to the scope view and see the value of 10 we passed from the JavaScript site. In this view, I can also step over the individual instructions. I can enter our main loop. I can set a break point to, say, run the loop a couple of times. And once I do that, I can see how the 4.0, our counter, gets decremented while more of one and work two look like consecutive Fibonacci numbers. And then I also have R3, which, to be honest, just have no idea what it is as it is something what to generate by the compiler. So while this works and provides at least some debugging experience, it's obviously not a great one, as it takes quite a bit of guesswork to understand what all those instructions mean and what all those variables are and how it matches to our original code. Even on such a tiny example, on larger ups, this becomes an even bigger problem. In fact, let me demonstrate a slightly more complicated example. In this one, I'm going to compile C++ application for drawing a Mandelbrot factor. You can see how this application is still fairly small. It's a single file contained 50 lines of code. But this time, I'm also using some external libraries, like SDL for graphics, as well as complex numbers from the C++ standard library. So I am initializing SDL, and after that, I am generating a palette with some random colors. I don't care what they are for the purposes of the demo. And then I'm doing a bunch of calculations on complex numbers as per Mandelbrot formulas to determine a set of colors of each pixel on the screen. Finally, once it's all over, I'm drawing everything to use the canvas. Now I'm going to compile it very similarly to the Fibonacci example, except I'm allowing it to use as much memory as it needs and passing some parameters to link it with the SDL library and generating a default HTML instead of the customer. Once it is compiled, I can open the result in Chrome and see our beautiful fractal shape with some random colors. Once again, I can open DevTools and see the generative JavaScript and WebAssembly in the sources panel, except this time, when I open the WebAssembly file, it looks a lot, lot larger and quite incomprehensible. So I can still search for the main function and I can recognize some imports and I can set a breakpoint inside of the main function and when I reload the page, it will get hit and from there, once again, I can step into the main code. But at this point, I just have no idea what all those instructions are and what all those variables mean, as it has zero resemblance with my original code. What we would want instead is to somehow debug the original C++ code we wrote and actually familiarize this and turns out we can do just that. First of all, you need to go to the link provided on the screen and install this Chrome extension. It's been developed by the Chrome DevTools team to support debugging information provided by Inscripten. Once it is installed, let's recompile the module by saving optimizations and enabling debugging via the shift link instead. I'm also adding one extra flag to specify why DevTools should be looking for sources, in this case, in the parent directory from this folder we compile to. Now let me compile it. This time, when I open DevTools, then in addition to the usual JavaScript and WebAssembly, I can see that it locates and finds my original C++ code as well. I can not only see it, but I can also set a fragment inside of it. And when I reload the page, it will stop right there instead of zero disassembly. Moreover, if I look in the scope view, then instead of some auto-generated names, I can now see the original C++ variables as well with their corresponding types. When stepping, I'm also no longer stepping through individual instructions, but rather over familiar source-level C++ expressions. For now, the only variables that are initialized are widths and height, but let me skip, for example, other palette generation. Once I do that, I can expand the palette array as well as expand the nested structures and look at the colors it generated and verify that they look OK and random enough. From there, I can step over, for example, center initialization, and I can observe the real and imaginary parts of the complex number. I can also step into the loop, and once I'm inside of it, I can see the x and y variables as well. So let me step a few more times. I have generated point. I can verify that it's generated 0, 0. Let me run it a few more times. This time, x is 3, and the point real part should be now 0. When I expand it, I can verify that. Similarly, I can step through a few more variables, and let me just skip to the part where it picks the color. At this point, we can get it from the palette. I step through that, and now I can expand the color and check which RGB values it picked for this pixel. To summarize, I believe that this provides a much more natural multi-bugging experience with source-level breakpoints, steps, and value-formatness that you can already use today for your apps. Once this is the worst-noting instead for larger apps, the debugging information can be much larger than the WebAssembly code and data itself, and it might be desirable to split it out so that it doesn't get downloaded for non-debugging sessions. For our Mandelware example, we can check the file size of the generated WebAssembly and see that it's around 670 kilobytes. Now, we can recompile it just like above, but with one extra option, dash G separate dwarf, which allows to specify a filename where M-scripten should split out and put the debug build. When we do that and check the binary size again, we can see that we got down by 25 almost 30 kilobytes. This doesn't look like much because we only have a single 50-line source file. As your application grows, situation quickly gets flipped and the debugging information can be actually taking most of the space in the binary. In fact, Google Earth is successfully using the new debugging experience combined with this option to debug WebAssembly builds of their large C++ application on the web. You can see how they can also set breakpoints in the source of, say, a click handler, and they can trigger them from the web page, step through the C++ expressions and observe the variables, just like we did in our trivial demo. All in all, these are some amazing improvements that will out-vlog even more applications and allow them to bring the experiences to even more users across the shared cross-platform web. Still, it's not the end of the journey. There are still more features that we are working on. Just to name a few, we'll be adding linear memory inspector for raw memory view, custom format for C++ types, working on improved profiling, code coverage support, and many more. Thank you for listening, and please stay tuned for the future updates.