{"id":94135,"date":"2016-08-22T07:00:00","date_gmt":"2016-08-22T21:00:00","guid":{"rendered":"https:\/\/blogs.msdn.microsoft.com\/oldnewthing\/?p=94135"},"modified":"2019-03-13T11:05:50","modified_gmt":"2019-03-13T18:05:50","slug":"20160822-00","status":"publish","type":"post","link":"https:\/\/devblogs.microsoft.com\/oldnewthing\/20160822-00\/?p=94135","title":{"rendered":"Adventures in application compatibility: The bogus memory calculation"},"content":{"rendered":"<p>One of my colleagues shared with me one of his application compatibility stories. <\/p>\n<p>There was a program that would fail on some computers but not others, and it wasn&#8217;t clear why. The problem was traced to the size of an internal cache. Now, <code>Global&shy;Memory&shy;Status<\/code> officially returns unsigned values, but if the calling application <a HREF=\"https:\/\/devblogs.microsoft.com\/oldnewthing\/\">is not marked <code>\/LARGE&shy;ADDRESS&shy;AWARE<\/code><\/a>, then <a HREF=\"https:\/\/msdn.microsoft.com\/en-us\/library\/windows\/desktop\/aa366586(v=vs.85).aspx\"><code>Global&shy;Memory&shy;Status<\/code> reports a maximum<\/a> of 2<a HREF=\"https:\/\/blogs.msdn.microsoft.com\/oldnewthing\/20090611-00\/?p=17933\">GB<\/a> &minus; 1 bytes of memory, for compatibility purposes. <\/p>\n<p>You&#8217;d think that this would be enough to keep old programs happy, but apparently not. This particular program wasn&#8217;t content with the values that it got from <code>Global&shy;Memory&shy;Status<\/code>. Instead, it took the <code>dwTotalPhys<\/code> and added it to the <code>dwTotalPageFile<\/code>, and treated the result as a signed value. This means that on systems with more than 2GB of memory, the addition will produce a total of <code>0xFFFFFFFE<\/code>, which is a negative value when interpreted as a signed result, which in turn causes the program to crash. <\/p>\n<p>My colleague fixed the program by patching out the instructions that added <code>dwTotalPhys<\/code> to <code>dwTotalPageFile<\/code>, and had the program operate solely on <code>dwTotalPhys<\/code>, which is probably what it should have been operating on in the first place. <\/p>\n<p>You see, even though the field in <a HREF=\"https:\/\/msdn.microsoft.com\/en-us\/library\/windows\/desktop\/aa366772(v=vs.85).aspx\">the <code>MEMORY&shy;STATUS<\/code> structure<\/a> is named <code>dwTotalPageFile<\/code>, it doesn&#8217;t actually give you the size of the page file. The documentation of <code>dwTotalPageFile<\/code> says <\/p>\n<blockquote CLASS=\"q\"><p>The current size of the committed memory limit, in bytes. This is physical memory plus the size of the page file, minus a small overhead. <\/p><\/blockquote>\n<p>Yes, this is a case of <a HREF=\"http:\/\/martinfowler.com\/bliki\/TwoHardThings.html\">bad naming<\/a>. (You can come up with your own theories how we ended up with the bad name.) <\/p>\n<p>By adding <code>dwTotalPhys<\/code> and <code>dwTotalPageFile<\/code>, the code was double-counting the physical memory. <\/p>\n<p>The conclusion my colleague drew from this exercise was that there are still programmers out there who are working hard to skip the documentation, come up with bad ideas, and <a HREF=\"http:\/\/www.quotationspage.com\/quote\/781.html\">implement them poorly<\/a>. <\/p>\n<p>I admire the program&#8217;s dedication to getting everything wrong despite the operating system&#8217;s efforts to save them from themselves. <\/p>\n","protected":false},"excerpt":{"rendered":"<p>Let&#8217;s add some numbers together, shall we?<\/p>\n","protected":false},"author":1069,"featured_media":111744,"comment_status":"open","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"_acf_changed":false,"footnotes":""},"categories":[1],"tags":[2],"class_list":["post-94135","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-oldnewthing","tag-history"],"acf":[],"blog_post_summary":"<p>Let&#8217;s add some numbers together, shall we?<\/p>\n","_links":{"self":[{"href":"https:\/\/devblogs.microsoft.com\/oldnewthing\/wp-json\/wp\/v2\/posts\/94135","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/devblogs.microsoft.com\/oldnewthing\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/devblogs.microsoft.com\/oldnewthing\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/oldnewthing\/wp-json\/wp\/v2\/users\/1069"}],"replies":[{"embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/oldnewthing\/wp-json\/wp\/v2\/comments?post=94135"}],"version-history":[{"count":0,"href":"https:\/\/devblogs.microsoft.com\/oldnewthing\/wp-json\/wp\/v2\/posts\/94135\/revisions"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/oldnewthing\/wp-json\/wp\/v2\/media\/111744"}],"wp:attachment":[{"href":"https:\/\/devblogs.microsoft.com\/oldnewthing\/wp-json\/wp\/v2\/media?parent=94135"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/oldnewthing\/wp-json\/wp\/v2\/categories?post=94135"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/oldnewthing\/wp-json\/wp\/v2\/tags?post=94135"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}