{"id":4792,"date":"2022-11-26T18:55:48","date_gmt":"2022-11-27T01:55:48","guid":{"rendered":"http:\/\/www.contrapositivediary.com\/?p=4792"},"modified":"2022-11-28T15:50:34","modified_gmt":"2022-11-28T22:50:34","slug":"a-libc-mystery-solved","status":"publish","type":"post","link":"https:\/\/www.contrapositivediary.com\/?p=4792","title":{"rendered":"A libc Mystery&#8230;Solved"},"content":{"rendered":"<p>We have solved the mystery described in yesterday&#8217;s entry&#8230;<\/p>\n<p>&#8230;mostly. I&#8217;ve found down the years that inside any big mystery are likely one or more smaller mysteries. And so it is. I would have figured this problem out a <em>whole<\/em> lot sooner if the symptoms had been consistent.<\/p>\n<p>They weren&#8217;t. And those symptoms made me nuts for several days. Eventually I decided to yell for help.<\/p>\n<p>I got a lot of <em>very<\/em> good help. If you haven&#8217;t read yesterday&#8217;s entry (and if you&#8217;re actually interested in assembly language programming) go read it now. I won&#8217;t repeat all the details here.<\/p>\n<p>In short: I wrote a small demo program for my new book, <em>x64 Assembly Language Step By Step<\/em>. It didn&#8217;t work. Several of my readers took the code I posted in yesterday&#8217;s entry, built the executable, and&#8230;it worked.<\/p>\n<p>That&#8217;s what made me nuts. I ran the damned thing on three different Linux instances, and the problem manifested on all three of them. But a couple of my friends ran the executable and had no trouble at all. It worked perfectly.<\/p>\n<p>WTF?<\/p>\n<p>That&#8217;s actually the small mystery inside the big mystery. The big mystery we figured out fairly quickly. Bruce, a new Contra commenter, built the executable and it failed. He changed one line in the program, and it worked. I tried his fix. It worked. Mystery solved.<\/p>\n<p>But&#8230;why? Bruce cleared register RDI to null (i.e., 0) before calling the libc time function. I had cleared RAX, as part of an earlier test to try and pin down the symptoms. I intended to remove that line from the program. But it gave Bruce an idea: clear RDI instead. He did. It worked. I tried it, and&#8230;victory! Clearing RDI to 0 completely eliminated the problem, and I spent another hour trying various things to crash the executable. No luck. It was a consistent fix, in that once I cleared RDI to 0, nothing else would make the executable malfunction.<\/p>\n<p>I think it started to dawn on several of us at once. Supposedly, the time function doesn&#8217;t take any parameters. Or so I supposed, based on my reading. But that was wrong. The Linux time function takes one (understated) parameter: The parameter can either be 0, or it can be an address. If it&#8217;s an address, time will put the current time_t timestamp value at that address. If it&#8217;s 0, time will return the time_t value in RAX.<\/p>\n<p>In stepping through the demo program&#8217;s execution in a debugger, I noticed that after a call to the puts function, register RDI would contain a memory address. It wasn&#8217;t always the same, and it wasn&#8217;t generally useful, So un-useful, in fact, that the garbage addresses being left in RDI would cause either a hang or a segmentation fault. In the x64 calling convention, the first parameter is always passed to a function in RDI. I didn&#8217;t think of time as having any parameters at all, but clearing RDI to 0 before calling time guaranteed that time would place the time_t value safely in register RAX&#8230;instead of crashing.<\/p>\n<p>So the big mystery was solved. I spent an hour and a half trying to get the program to crash. As long as RDI was 0 when time was called, it did not crash. Halleluia! The big mystery was solved.<\/p>\n<p>The small mystery remained: Why did some of my readers built the executable and have it work perfectly, while the exact same program on my Linux machines went belly-up? That remains an open service ticket. I&#8217;m mildly curious, but as long as I know that RDI has to be either 0 (preferably) or the address of a suitable buffer to hold the time_t value, all will be well.<\/p>\n<p>Let me wrap up by abundantly thanking everyone who took part in the bug hunt:<\/p>\n<ul>\n<li>My friend and SFF collaborator Jim Strickland<\/li>\n<li>Linux expert Bill Buhler<\/li>\n<li>New commenter Bruce<\/li>\n<li>Long-time reader Jason Bucata<\/li>\n<li>X64 programming expert Jonathan O&#8217;Neal<\/li>\n<li>Contra regular Keith<\/li>\n<\/ul>\n<p>You guys were brilliant. I will cite you all on the Acknowlegements page in the book, when it comes up (with some luck) next summer.<\/p>\n<p>Again, thanks. In a weird but satifying way, it was fun. Now I have to get back to work.<\/p>\n","protected":false},"excerpt":{"rendered":"<p>We have solved the mystery described in yesterday&#8217;s entry&#8230; &#8230;mostly. I&#8217;ve found down the years that inside any big mystery are likely one or more smaller mysteries. And so it is. I would have figured this problem out a whole lot sooner if the symptoms had been consistent. They weren&#8217;t. And those symptoms made me [&hellip;]<\/p>\n","protected":false},"author":2,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[1],"tags":[],"class_list":["post-4792","post","type-post","status-publish","format-standard","hentry","category-noneoftheabove"],"_links":{"self":[{"href":"https:\/\/www.contrapositivediary.com\/index.php?rest_route=\/wp\/v2\/posts\/4792","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/www.contrapositivediary.com\/index.php?rest_route=\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/www.contrapositivediary.com\/index.php?rest_route=\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/www.contrapositivediary.com\/index.php?rest_route=\/wp\/v2\/users\/2"}],"replies":[{"embeddable":true,"href":"https:\/\/www.contrapositivediary.com\/index.php?rest_route=%2Fwp%2Fv2%2Fcomments&post=4792"}],"version-history":[{"count":3,"href":"https:\/\/www.contrapositivediary.com\/index.php?rest_route=\/wp\/v2\/posts\/4792\/revisions"}],"predecessor-version":[{"id":4795,"href":"https:\/\/www.contrapositivediary.com\/index.php?rest_route=\/wp\/v2\/posts\/4792\/revisions\/4795"}],"wp:attachment":[{"href":"https:\/\/www.contrapositivediary.com\/index.php?rest_route=%2Fwp%2Fv2%2Fmedia&parent=4792"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.contrapositivediary.com\/index.php?rest_route=%2Fwp%2Fv2%2Fcategories&post=4792"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.contrapositivediary.com\/index.php?rest_route=%2Fwp%2Fv2%2Ftags&post=4792"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}