浏览器M55内核升级最后一个崩溃

最近做M55内核升级,我负责浏览器的稳定性。陆陆续续把各种崩溃都修复的差不多了,只剩下最后一个崩溃了,其崩溃堆栈如下: 在执行这行代码的时候发生了崩溃: 初步一看,这个崩溃点在Chromium原生的代码里面,所以怀疑是Chromium自己的bug。于是在https://bugs.chromium.org/p/chromium/issues/list里面搜索相关堆栈关键词,看看能不能找到类似的崩溃。很遗憾的是并没有搜到有用的信息。 然后再去https://groups.google.com/a/chromium.org/forum/#!forum/chromium-dev里面碰碰运气,仍然是一无所获。看来是指望不上Chromium社区的帮助了,只能自己动手,丰衣足食。 因为我们抓的崩溃dump只包含栈上的内存,另外浏览器Release版本做了编译器优化,导致很多栈上变量值都优化的不可见。因此崩溃dump里面包含的有用信息并不多,只能看到浏览器崩溃在哪行代码,却不能观察到浏览器崩溃时所处的状态,如Windbg里面查看到变量信息下图所示: 为此,通过Alias函数引用到栈上变量,防止它被优化,Alias函数如下图所示: 然后把自己关心的信息,都存到栈上分配的内存上,比如我想知道崩溃的时候请求的url、cookie等信息,如下图所示: 加上这些收集调试信息的代码,再灰度出去收集新的dump。通过分析新的dump果然有了一些有用的信息。可以看到浏览器崩溃的时候first_party_for_cookies对于的url都是天猫、淘宝的商品页面,而此时网络请求的url也都是https://gm.mmstat.com/tbdetail的url,如下图所示: 可以确定浏览器都是访问淘宝天猫出现的崩溃,但是我本地试了试,并不能复现问题。为了找到可以复现的崩溃场景,我在浏览器崩溃的时候,利用QQ的tencent://协议自动打开QQ跟我联系,代码如下: 继续灰度出去一版,等待崩溃的用户联系我。 我这边继续分析之前的崩溃dump,可以排除是空指针崩溃。发现cookie_store变量很有意思,其中一个dump如下: 可以看到cookie_store指向的net::CookieStore对象的虚函数表地址竟然是0xe43a00f2,已经跑到系统的地址空间里面去了,显然超出了合法的地址范围。而有的dump则是这样: 虽然虚函数表地址是正常的,但是其中虚函数指针都是错的,我猜可能是UAF(Use... Read More | Share it now!

避免编译器优化掉代码

c++代码编译成Release版本,编译器会做一些优化,生成的二进制可执行文件执行更快,体积更小。这种优化会复用栈上不同变量的空间,导致调试的时候,有些局部变量看不到了。比如如下代码: 在调试的的时候,调试器直接运行到printf(“%d”,... Read More | Share it now!

Blink/Webkit浏览器内核崩溃分析过程总结

前两天技术团队旺旺群里有同事提出一个问题:在debug模式下,Chromium浏览器打开http://product.suning.com/125073744.html页面renderer进程就立即崩溃。团队对于Blink/Webkit内核问题的分析经验不多,故把分析过程写出一个总结,希望对大家以后分析此类问题有帮助。 多进程调试 Chromium浏览器是多进程的架构。而Blink内核在renderer进程,debug模式下,VS调试不能抓到renderer进程的异常,也就无法定位问题。所以解决问题的第一步是把VS调试器附加到问题相应的renderer进程。 Chromium已有一篇文档讲述如何调试Chromium。对于浏览器子进程的调试,有一个–wait-for-debugger-children的命令行参数。给浏览器传递这个命令行参数之后,生成的子进程都会在一开始等待调试器60秒附加上去。另外这个命令行还可以指定是plugin进程还是renderer进程。因为这次调试的对象是renderer进程,故我们在VS调试器设置–wait-for-debugger-children=renderer传递给被调试的浏览器。 重现问题 用VS打开Chromium的源代码工程,并在debug模式下运行。启动浏览器之后,新建tab页,在地址栏里输入会导致renderer进程崩溃的网址http://product.suning.com/125073744.html。这时候就是生成对应的renderer进程。这个renderer进程在60秒等待我们把调试器附加上去。 我们找到新建renderer进程的PID,然后用VS的debug->Attach... Read More | Share it now!

visual studio的Function Evaluation调试功能

今天公司技术群里老大提及GDB调试器有个牛逼的功能,在断点的情况下执行程序里的函数。如下代码: 在GDB中直接输入a.print或者pa->print()就执行a对象的print方法,有时候这样对于调试非常方便。然后有其他同事说vs也有类似功能,叫做Immediate... Read More | Share it now!

visual stdio调试中的数据类型可视化Debug Visualizers

前言 c++可以灵活自定义非常复杂的数据结构,比如标准库中的vector,map,还有很多是用户自定义的数据。通常调试器只能解释显示一些基本的数据变量,比如int,float,能够漂亮的显示标准库的那些类就算非常不错了,比如string。对于一些用户自定义的类型,往往调试器显示出来的变量值没有什么用,有时候就想能够自己自定义的方式友好的显示调试变量值。 之前vs是通过autoexp.dat的方式支持用户自定义显示变量值,如这篇博客所介绍的:Customize... Read More | Share it now!