{"id":3627,"date":"2016-02-05T07:19:41","date_gmt":"2016-02-05T06:19:41","guid":{"rendered":"https:\/\/glandium.org\/blog\/?p=3627"},"modified":"2019-09-03T15:21:16","modified_gmt":"2019-09-03T06:21:16","slug":"going-beyond-ns_processnextevent","status":"publish","type":"post","link":"https:\/\/glandium.org\/blog\/?p=3627","title":{"rendered":"Going beyond NS_ProcessNextEvent"},"content":{"rendered":"<p>If you've been debugging Gecko, you've probably hit the frustration of having the code you're inspecting being called asynchronously, and your stack trace rooting through <code>NS_ProcessNextEvent<\/code>, which means you don't know at first glance how your code ended up being called in the first place.<\/p>\n<p>Events running from the Gecko event loop are all <code>nsRunnable<\/code> instances. So at some level close to <code>NS_ProcessNextEvent<\/code>, in your backtrace, you will see <code>Class::Run<\/code>. If you're lucky, you can find where the <code>nsRunnable<\/code> was created. But that requires the stars to be perfectly aligned. In many cases, they're not.<\/p>\n<p>There comes your savior: <a href=\"http:\/\/rr-project.org\">rr<\/a>. If you don't know it, <a href=\"http:\/\/rr-project.org\">check it out<\/a>. The downside is that you must first <code>rr record<\/code> a Firefox session doing what you're debugging. Then, <code>rr replay<\/code> will give you a debugger with the capabilities of a time machine.<\/p>\n<p>Note, I'm kind of jinxed, I don't do much C++ debugging these days, so every time I use <code>rr replay<\/code>, I end up hitting a new error. Tip #1: try again with rr's current master. Tip #2: <a href=\"http:\/\/robert.ocallahan.org\/\">roc<\/a> is very helpful. But my takeaway is that it's well worth the trouble. It is a game changer for debugging.<\/p>\n<p>Anyways, once you're in <code>rr replay<\/code> and have hit your crasher or whatever execution path you're interested in, and you want to go beyond that <code>NS_ProcessNextEvent<\/code>, here is what you can do:<\/p>\n<blockquote>\n<pre>(rr) break <a href=\"https:\/\/dxr.mozilla.org\/mozilla-central\/rev\/584870f1cbc5d060a57e147ce249f736956e2b62\/xpcom\/threads\/nsEventQueue.cpp#60\">nsEventQueue.cpp:60<\/a>\r\n(rr) reverse-continue\r\n<\/pre>\n<\/blockquote>\n<p>(Adjust the line number to match wherever the <a href=\"https:\/\/dxr.mozilla.org\/mozilla-central\/rev\/584870f1cbc5d060a57e147ce249f736956e2b62\/xpcom\/threads\/nsEventQueue.cpp#60\"><code>*aResult = mHead->mEvents[mOffsetHead++];<\/code><\/a> line is in your tree).<\/p>\n<blockquote>\n<pre>(rr) disable\r\n(rr) watch -l mHead->mEvents[mOffsetHead]\r\n(rr) reverse-continue\r\n(rr) disable\r\n<\/pre>\n<\/blockquote>\n<p>And there you are, you just found where the exact event that triggered the executed code you were looking at was put on the event queue. (assuming there isn't a nested event loop processed during the first <code>reverse-continue<\/code>)<\/p>\n<p>Rinse and repeat.<\/p>\n","protected":false},"excerpt":{"rendered":"<p>If you&#8217;ve been debugging Gecko, you&#8217;ve probably hit the frustration of having the code you&#8217;re inspecting being called asynchronously, and your stack trace rooting through NS_ProcessNextEvent, which means you don&#8217;t know at first glance how your code ended up being called in the first place. Events running from the Gecko event loop are all nsRunnable [&hellip;]<\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"closed","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[25],"tags":[23],"class_list":["post-3627","post","type-post","status-publish","format-standard","hentry","category-planet-mozilla","tag-en"],"_links":{"self":[{"href":"https:\/\/glandium.org\/blog\/index.php?rest_route=\/wp\/v2\/posts\/3627","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/glandium.org\/blog\/index.php?rest_route=\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/glandium.org\/blog\/index.php?rest_route=\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/glandium.org\/blog\/index.php?rest_route=\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/glandium.org\/blog\/index.php?rest_route=%2Fwp%2Fv2%2Fcomments&post=3627"}],"version-history":[{"count":3,"href":"https:\/\/glandium.org\/blog\/index.php?rest_route=\/wp\/v2\/posts\/3627\/revisions"}],"predecessor-version":[{"id":3630,"href":"https:\/\/glandium.org\/blog\/index.php?rest_route=\/wp\/v2\/posts\/3627\/revisions\/3630"}],"wp:attachment":[{"href":"https:\/\/glandium.org\/blog\/index.php?rest_route=%2Fwp%2Fv2%2Fmedia&parent=3627"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/glandium.org\/blog\/index.php?rest_route=%2Fwp%2Fv2%2Fcategories&post=3627"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/glandium.org\/blog\/index.php?rest_route=%2Fwp%2Fv2%2Ftags&post=3627"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}