工作经验大厂生活精选好文
最近在研究WebAssembly,也写了几篇全面介绍的文章:
高级前端进阶:我是如何把C/C++代码跑在浏览器上的?[1]快11KStar的WebAssembly,你应该这样学[2]本文是学习WebAssembly系列的第三篇文章,也是想探究一下Chrome开发者工具对WebAssembly的调试支持度如何,通过这个探究的过程,我们会了解到Chrome调试工具各种方面的使用方法以及作用,发掘你可能不知道的一些知识点。
所以本文既可以当做学习使用ChromeDevtools调试工具的一篇比较全面的文章,也可以当做是介绍现阶段我们如何在浏览器中对WebAssembly相关的代码进行调试,帮助你成为一个合格的调试工程师:)。
WebAssembly的原始调试方式Chrome开发者工具目前已经支持WebAssembly的调试,虽然存在一些限制,但是针对WebAssembly的文本格式的文件能进行单个指令的分析以及查看原始的堆栈追踪,具体见如下图:
上述的方法对于一些无其他依赖函数的WebAssembly模块来说可以很好的运行,因为这些模块只涉及到很小的调试范围。但是对于复杂的应用来说,如C/C++编写的复杂应用,一个模块依赖其他很多模块,且源代码与编译后的WebAssembly的文本格式的映射有较大的区别时,上述的调试方式就不太直观了,只能靠猜的方式才能理解其中的代码运行方式,且大多数人很难以看懂复杂的汇编代码。
更加直观的调试方式现代的JavaScript项目在开发时通常也会存在编译的过程,使用ES6进行开发,编译到ES5及以下的版本进行运行,这个时候如果需要调试代码,就涉及到SourceMap的概念,sourcemap用于映射编译后的对应代码在源代码中的位置,sourcemap使得客户端的代码更具可读性、更方便调试,但是又不会对性能造成很大的影响。
而C/C++到WebAssembly代码的编译器Emscripten则支持在编译时,为代码注入相关的调试信息,生成对应的sourcemap,然后安装Chrome团队编写的C/C++DevtoolsSupport[3]浏览器扩展,就可以使用Chrome开发者工具调试C/C++代码了。
这里的原理其实就是,Emscripten在编译时,会生成一种DWARF格式的调试文件,这是一种被大多数编译器使用的通用调试文件格式,而C/C++DevtoolsSupport[4]则会解析DWARF文件,为ChromeDevtools在调试时提供sourcemap相关的信息,使得开发者可以在89+版本以上的ChromeDevtools上调试C/C++代码。
调试简单的C应用因为DWARF格式的调试文件可以提供处理变量名、格式化类型打印消化、在源代码中执行表达式等等,现在就让我们实际来编写一个简单的C程序,然后编译到WebAssembly并在浏览器中运行,查看实际的调试效果吧。
首先让我们进入到之前创建的WebAssembly目录下,激活emcc相关的命令,然后查看激活效果:
cdemsdksourceemsdk_env.shemcc--version#emcc(Emscriptengcc/clang-likereplacement)1.39.18(a3beeb0d6cbddeda77)
接着在WebAssembly创建一个temp文件夹,然后创建temp.c文件,填充如下内容并保存:
#includestdlib.hvoidassert_less(intx,inty){if(x=y){abort();}}intmain(){assert_less(10,20);assert_less(30,20);}
上述代码在执行asset_less时,如果遇到x=y的情况会抛出异常,终止程序执行。
在终端切换目录到temp目录下执行emcc命令进行编译:
emcc-gtemp.c-otemp.html
上述命令在普通的编译形式上,加入了-g参数,告诉Emscripten在编译时为代码注入DWARF调试信息。
现在可以开启一个HTTP服务器,可以使用npxserve.,然后访问localhost:/temp.html查看运行效果。
需要确保已经安装了Chrome扩展: