{"id":42,"date":"2014-03-23T17:01:08","date_gmt":"2014-03-23T17:01:08","guid":{"rendered":"https:\/\/blogs.scummvm.org\/josejx\/?p=42"},"modified":"2022-05-21T17:04:05","modified_gmt":"2022-05-21T17:04:05","slug":"detour-fixing-a-segfault","status":"publish","type":"post","link":"https:\/\/blogs.scummvm.org\/josejx\/2014\/03\/23\/detour-fixing-a-segfault\/","title":{"rendered":"Detour: Fixing a Segfault"},"content":{"rendered":"<p>When playing with the demo version of EMI (which you can get for free <a href=\"https:\/\/downloads.scummvm.org\/frs\/demos\/grim\/emi-win-demo-en.zip\">here<\/a> from the ResidualVM project), I found that when you press F1, which usually brings you to a menu, the game pauses, but no menu appears. While this might be the intended behavior, pressing <i>Esc<\/i> now causes ResidualVM to crash. Let&#8217;s explore this crash and figure out how to fix it!<\/p>\n<p>First, we&#8217;ll need to restart ResidualVM with a debugger. Start up ResidualVM with the command:<\/p>\n<ul>\n<li>gdb .\/residualvm<\/li>\n<\/ul>\n<p>When the prompt comes up, type <i>run<\/i> to begin running ResidualVM. Start the game as usual, and then trigger the crash. When the crash occurs this time, in our window with gdb, we can see that the debugger has caught the error and stopped execution:<\/p>\n<figure id=\"attachment_44\" aria-describedby=\"caption-attachment-44\" style=\"width: 624px\" class=\"wp-caption aligncenter\"><a href=\"https:\/\/blogs.scummvm.org\/josejx\/wp-content\/uploads\/sites\/23\/2014\/03\/Crash.png\"><img loading=\"lazy\" decoding=\"async\" class=\"size-full wp-image-44\" src=\"https:\/\/blogs.scummvm.org\/josejx\/wp-content\/uploads\/sites\/23\/2014\/03\/Crash.png\" alt=\"\" width=\"624\" height=\"148\" srcset=\"https:\/\/blogs.scummvm.org\/josejx\/wp-content\/uploads\/sites\/23\/2014\/03\/Crash.png 624w, https:\/\/blogs.scummvm.org\/josejx\/wp-content\/uploads\/sites\/23\/2014\/03\/Crash-300x71.png 300w\" sizes=\"auto, (max-width: 624px) 100vw, 624px\" \/><\/a><figcaption id=\"caption-attachment-44\" class=\"wp-caption-text\">Investigating the ResidualVM Crash<\/figcaption><\/figure>\n<p>We can see that there is an error from ResidualVM itself, warning us that there was a null value in the Lua engine from the &#8216;gettable&#8217; tag method, and also the actual crash in ResidualVM which follows that.<\/p>\n<p>It&#8217;s helpful to see how we got here, and GDB let&#8217;s us do that by checking the<i> backtrace<\/i>. Type <i>bt<\/i> to see the backtace, which is a list of the function calls that brought us to this location. Typing <i>up<\/i> or <i>down<\/i> moves the current position up or down in the stack, letting us look at different variables at each call. To print out a variable&#8217;s value, use the <i>print <\/i>or <i>p<\/i> command followed by the variable name you&#8217;re interested. It&#8217;s also sometimes useful to see the code that preceded the error. Using the <i>list<\/i> or <i>l<\/i> command will print the code around the current position in the stack.<\/p>\n<figure id=\"attachment_45\" aria-describedby=\"caption-attachment-45\" style=\"width: 730px\" class=\"wp-caption aligncenter\"><a href=\"https:\/\/blogs.scummvm.org\/josejx\/wp-content\/uploads\/sites\/23\/2014\/03\/Backtrace.png\"><img loading=\"lazy\" decoding=\"async\" class=\"size-full wp-image-45\" src=\"https:\/\/blogs.scummvm.org\/josejx\/wp-content\/uploads\/sites\/23\/2014\/03\/Backtrace.png\" alt=\"\" width=\"730\" height=\"902\" srcset=\"https:\/\/blogs.scummvm.org\/josejx\/wp-content\/uploads\/sites\/23\/2014\/03\/Backtrace.png 730w, https:\/\/blogs.scummvm.org\/josejx\/wp-content\/uploads\/sites\/23\/2014\/03\/Backtrace-243x300.png 243w\" sizes=\"auto, (max-width: 730px) 100vw, 730px\" \/><\/a><figcaption id=\"caption-attachment-45\" class=\"wp-caption-text\">Finding the Error with GDB<\/figcaption><\/figure>\n<p>After some exploration, we see that we dereferenced the <i>g_registry<\/i> variable when it was null, causing the segfault.<\/p>\n<p>Now that we know what&#8217;s causing the problem, let&#8217;s look at the engine code for the registry functions and see if we can identify why this is breaking in the demo.<\/p>\n<p>In <a href=\"https:\/\/github.com\/residualvm\/residualvm\/blob\/master\/engines\/grim\/grim.cpp#L87\"><i>engines\/grim\/grim.cpp<\/i><\/a> (line 87) we see that the registry is initialized when the engine is started and the game type is &#8221;GType_GRIM&#8221;. In <a href=\"https:\/\/github.com\/residualvm\/residualvm\/blob\/master\/engines\/grim\/detection.cpp#L413\">engines\/grim\/detection.cpp<\/a> (line 413) we see that the game type for the EMI Demo is &#8221;GType_MONKEY4&#8221;. So, the registry is never created for the demo, and because of that, the <i>g_registry<\/i> variable is never set.<\/p>\n<p>The registry for Grim Fandango holds settings and values that would normally be found in the Windows registry. As of now, there are no EMI specific registry options set up and the registry is specific to Grim Fandango. Although we&#8217;ll probably need to implement something like this later on, for now, let&#8217;s fix the segfault by preventing the code from dereferencing <i>g_registry<\/i> when it&#8217;s null.<\/p>\n<p>Searching through the code, we find that the only accesses to <i>g_registry<\/i> that don&#8217;t check for a null value are in <a href=\"https:\/\/github.com\/residualvm\/residualvm\/blob\/master\/engines\/grim\/lua_v1.cpp\">engines\/grim\/lua_v1.cpp<\/a> in the functions:<\/p>\n<ul>\n<li>Lua_V1::ReadRegistryValue<\/li>\n<li>Lua_V1::WriteRegistryValue<\/li>\n<li>Lua_V1::postRestoreHandle<\/li>\n<\/ul>\n<p>Looking back at our backtrace, we see that indeed, the path that the code took went through the <i>ReadRegistryValue<\/i> function before segfaulting. Since the code in <i>postRestoreHandle <\/i>that accesses <i>g_registry<\/i> is only used in games with the &#8221;GType_GRIM&#8221; tag, we can safely ignore this instance as those games will always have the <i>g_registry<\/i> variable set. With checks added to see if <i>g_registry<\/i> is defined before performing registry actions in the functions <i>ReadRegistryValue <\/i>and <i>WriteRegistryValue<\/i>, the bug is fixed and ResidualVM no longer crashes. I also added a warning to let anyone else know that there was an attempt to access a registry that didn&#8217;t exist. To fix this bug properly, we should override these functions so that they point to the EMI_Registry instead. For now, we&#8217;ll stick with just fixing the segfault.<\/p>\n<p>So now, we have fixed the segfault, but the game is now stuck, preventing the demo from continuing further. In the next post, we&#8217;ll discuss how to fix this issue.<\/p>\n","protected":false},"excerpt":{"rendered":"<p>When playing with the demo version of EMI (which you can get for free here from the ResidualVM project), I found that when you press F1, which usually brings you to a menu, the game pauses, but no menu appears. While this might be the intended behavior, pressing Esc now causes ResidualVM to crash. Let&#8217;s [&hellip;]<\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"closed","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[1],"tags":[],"class_list":["post-42","post","type-post","status-publish","format-standard","hentry","category-uncategorized"],"_links":{"self":[{"href":"https:\/\/blogs.scummvm.org\/josejx\/wp-json\/wp\/v2\/posts\/42","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/blogs.scummvm.org\/josejx\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/blogs.scummvm.org\/josejx\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/blogs.scummvm.org\/josejx\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/blogs.scummvm.org\/josejx\/wp-json\/wp\/v2\/comments?post=42"}],"version-history":[{"count":2,"href":"https:\/\/blogs.scummvm.org\/josejx\/wp-json\/wp\/v2\/posts\/42\/revisions"}],"predecessor-version":[{"id":46,"href":"https:\/\/blogs.scummvm.org\/josejx\/wp-json\/wp\/v2\/posts\/42\/revisions\/46"}],"wp:attachment":[{"href":"https:\/\/blogs.scummvm.org\/josejx\/wp-json\/wp\/v2\/media?parent=42"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/blogs.scummvm.org\/josejx\/wp-json\/wp\/v2\/categories?post=42"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/blogs.scummvm.org\/josejx\/wp-json\/wp\/v2\/tags?post=42"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}