{"id":112757,"date":"2026-10-06T07:00:00","date_gmt":"2026-10-06T14:00:00","guid":{"rendered":"https:\/\/devblogs.microsoft.com\/oldnewthing\/?p=112757"},"modified":"2026-10-06T20:56:22","modified_gmt":"2026-10-07T03:56:22","slug":"20261006-00","status":"publish","type":"post","link":"https:\/\/devblogs.microsoft.com\/oldnewthing\/20261006-00\/?p=112757\/","title":{"rendered":"Why does the compiler sometimes use <CODE>ud2<\/CODE> and sometimes <CODE>int 3<\/CODE> for code that shouldn&#8217;t execute?"},"content":{"rendered":"<p>There are two common ways for x86 compilers to indicate that execution should not have reached a particular point: One is the single-byte <code>int 3<\/code> breakpoint opcode. And the other is the two-byte <code>ud2<\/code> invalid instruction opcode. How do they decide which one to use?<\/p>\n<p>The two types of &#8220;bad instructions&#8221; are typically for different purposes.<\/p>\n<p>The <code>int 3<\/code> means &#8220;There is no code here. If you somehow got here, then somebody used an invalid function pointer.&#8221; It is used as padding, such as between functions. There is no way that code can reach the <code>int 3<\/code> by normal execution. You must have generated an invalid address and called it.<\/p>\n<p>The <code>ud2<\/code> is used to mark the case when execution reached something that should be unreachable. It means &#8220;You executed a code path that the standard says is undefined behavior.&#8221; For example, falling off the end of a non-<code>void<\/code> function without returning a value, or following the call to a <code>[[noreturn]]<\/code> function in case it somehow managed to return.<\/p>\n<p>Using <code>int 3<\/code> for &#8220;there is not even code here&#8221; is important because it&#8217;s a one-byte instruction. If you had used the two-byte instruction <code>ud2<\/code> instruction, then that stray function pointer might land on the <i>second<\/i> byte of the instruction, in which case it&#8217;s not <code>ud2<\/code> any more. Instead of stopping immediately, it starts executing garbage code:<\/p>\n<pre>0b 0f            or      ecx,dword ptr [edi]\r\n0b 0f            or      ecx,dword ptr [edi]\r\n0b 0f            or      ecx,dword ptr [edi]\r\n<\/pre>\n<p>Okay, so what does this mean for you?<\/p>\n<p>If you find yourself executing the <code>ud2<\/code> instruction, then look for logic flaws in your code. If you find yourself executing the <code>int 3<\/code> instruction, then look for an uninitialized function pointer variable, or a hard-coded breakpoint, or a <a title=\"Debugger breakpoints are usually implemented by patching the in-memory copy of the code\" href=\"https:\/\/devblogs.microsoft.com\/oldnewthing\/20241111-00\/?p=110503\/\"> debugger-inserted breakpoint<\/a>.<\/p>\n","protected":false},"excerpt":{"rendered":"<p>It shouldn&#8217;t execute, but for different reasons.<\/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-112757","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-oldnewthing","tag-code"],"acf":[],"blog_post_summary":"<p>It shouldn&#8217;t execute, but for different reasons.<\/p>\n","_links":{"self":[{"href":"https:\/\/devblogs.microsoft.com\/oldnewthing\/wp-json\/wp\/v2\/posts\/112757","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=112757"}],"version-history":[{"count":1,"href":"https:\/\/devblogs.microsoft.com\/oldnewthing\/wp-json\/wp\/v2\/posts\/112757\/revisions"}],"predecessor-version":[{"id":112758,"href":"https:\/\/devblogs.microsoft.com\/oldnewthing\/wp-json\/wp\/v2\/posts\/112757\/revisions\/112758"}],"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=112757"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/oldnewthing\/wp-json\/wp\/v2\/categories?post=112757"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/oldnewthing\/wp-json\/wp\/v2\/tags?post=112757"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}