{"id":106038,"date":"2021-12-16T07:00:00","date_gmt":"2021-12-16T15:00:00","guid":{"rendered":"https:\/\/devblogs.microsoft.com\/oldnewthing\/?p=106038"},"modified":"2021-12-16T06:23:29","modified_gmt":"2021-12-16T14:23:29","slug":"20211216-00","status":"publish","type":"post","link":"https:\/\/devblogs.microsoft.com\/oldnewthing\/20211216-00\/?p=106038","title":{"rendered":"Why does the precise point at which I get a stack overflow exception change from run to run?"},"content":{"rendered":"<p>Consider this program:<\/p>\n<pre>#include &lt;stdio.h&gt;\r\n\r\nint maxdepth = 0;\r\n\r\nint f()\r\n{\r\n  ++maxdepth;\r\n  return f();\r\n}\r\n\r\nint main()\r\n{\r\n  __try {\r\n    f();\r\n  } __except (GetExceptionCode() == STATUS_STACK_OVERFLOW ?\r\n              EXCEPTION_EXECUTE_HANDLER :\r\n              EXCEPTION_CONTINUE_SEARCH) {\r\n    printf(\"Overflow at %u\\n\", maxdepth);\r\n  }\r\n}\r\n<\/pre>\n<p>Make sure to compile this program with optimizations disabled to ensure that the recursive call occupies stack and doesn&#8217;t get tail-call-optimized.<\/p>\n<p>When I run this program multiple times, the results are inconsistent.<\/p>\n<pre>Overflow at 4882\r\nOverflow at 4877\r\nOverflow at 4879\r\nOverflow at 4884\r\nOverflow at 4877\r\nOverflow at 4883\r\nOverflow at 4882\r\nOverflow at 4881\r\nOverflow at 4879\r\nOverflow at 4882\r\n<\/pre>\n<p>This program is completely deterministic. Why does the overflow happen at different stack depths? In other words, why does the size of the stack vary?<\/p>\n<p>The variation in the stack size is thanks to Address Space Layout Randomization, or ASLR. The system places the initial stack pointer at a random location in the last page of the stack, thereby randomizing the low-order bits and reducing stack predictability.<\/p>\n<p>It also has a secondary benefit of reducing collisions in caches that are indexed by virtual address. For example, the internal tables used by <code>Wait\u00adOn\u00adAddress<\/code> use the address of a stack-allocated object as a key in a hash table to keep track of all the threads that are waiting on an address. Randomizing the initial stack location means that if you have multiple threads running the same code, their stack-allocated objects won&#8217;t have similar addresses.<\/p>\n<p>Today, we looked at where the stack starts. Next time, we&#8217;ll look at where the stack ends.<\/p>\n","protected":false},"excerpt":{"rendered":"<p>The system is trying to introduce some unpredictability.<\/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":[25],"class_list":["post-106038","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-oldnewthing","tag-code"],"acf":[],"blog_post_summary":"<p>The system is trying to introduce some unpredictability.<\/p>\n","_links":{"self":[{"href":"https:\/\/devblogs.microsoft.com\/oldnewthing\/wp-json\/wp\/v2\/posts\/106038","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=106038"}],"version-history":[{"count":0,"href":"https:\/\/devblogs.microsoft.com\/oldnewthing\/wp-json\/wp\/v2\/posts\/106038\/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=106038"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/oldnewthing\/wp-json\/wp\/v2\/categories?post=106038"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/oldnewthing\/wp-json\/wp\/v2\/tags?post=106038"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}