{"id":90881,"date":"2015-07-17T07:00:00","date_gmt":"2015-07-17T21:00:00","guid":{"rendered":"https:\/\/blogs.msdn.microsoft.com\/oldnewthing\/20150717-00\/?p=90881\/"},"modified":"2023-08-04T09:22:36","modified_gmt":"2023-08-04T16:22:36","slug":"20150717-00","status":"publish","type":"post","link":"https:\/\/devblogs.microsoft.com\/oldnewthing\/20150717-00\/?p=90881","title":{"rendered":"What did the Ignore button do in Windows 3.1 when an application encountered a general protection fault?"},"content":{"rendered":"<p>In Windows 3.0, when an application encountered a general protection fault, you got an error message that looked like this:<\/p>\n<table style=\"border: solid 1px black; font-family: System, sans-serif; font-weight: bold; width: 40em; background-color: white;\" border=\"0\">\n<tbody>\n<tr>\n<td style=\"padding: 1em 0px 2em 0px; background-color: white; color: black;\" align=\"center\" nowrap=\"nowrap\">Application error<\/td>\n<\/tr>\n<tr>\n<td style=\"padding-bottom: 2em; background-color: white; color: black;\" align=\"center\" nowrap=\"nowrap\">CONTOSO caused a General Protection Fault in<br \/>\nmodule CONTOSO.EXE at 0002:2403<\/td>\n<\/tr>\n<tr>\n<td style=\"padding-bottom: 1em; background-color: white; color: black;\" align=\"center\" nowrap=\"nowrap\">\n<div style=\"width: 10em; padding: 2px; background: #C0C0C0; border: 2px outset #C0C0C0;\">\n<div style=\"border: 1px dotted black; padding: .5em;\"><u>C<\/u>lose<\/div>\n<\/div>\n<\/td>\n<\/tr>\n<\/tbody>\n<\/table>\n<p>In Windows 3.1, under the right conditions, you would get a second option:<\/p>\n<table style=\"border: solid 1px black; font-family: System, sans-serif; font-weight: bold; width: 40em; background-color: white;\" border=\"0\">\n<tbody>\n<tr>\n<td style=\"padding: 1em 0px 2em 0px; background-color: white; color: black;\" align=\"center\" nowrap=\"nowrap\">CONTOSO<\/td>\n<\/tr>\n<tr>\n<td style=\"padding-bottom: 2em; background-color: white; color: black;\" align=\"center\" nowrap=\"nowrap\">An error has occurred in your application.<br \/>\nIf you choose Ignore, you should save your work in a new file.<br \/>\nIf you choose Close, your application will terminate.<\/td>\n<\/tr>\n<tr>\n<td style=\"padding-bottom: 1em; background-color: white; color: black;\" align=\"center\" nowrap=\"nowrap\">\n<div style=\"width: 10em; padding: 2px; display: inline-block; background: #C0C0C0; margin-right: 5em; border: 2px outset #C0C0C0;\">\n<div style=\"border: 1px dotted black; padding: .5em;\"><u>C<\/u>lose<\/div>\n<\/div>\n<div style=\"width: 10em; padding: 2px; display: inline-block; background: #C0C0C0; border: 2px outset #C0C0C0;\">\n<div style=\"border: 1px none black; padding: .5em;\"><u>I<\/u>gnore<\/div>\n<\/div>\n<\/td>\n<\/tr>\n<\/tbody>\n<\/table>\n<p>Okay, we know what Close does. But what does Ignore do? And under what conditions will it appear?<\/p>\n<p>Roughly speaking, the Ignore option becomes available if<\/p>\n<ul>\n<li>The fault is a general protection fault,<\/li>\n<li>The faulting instruction is not in the kernel or the window manager,<\/li>\n<li>The faulting instruction is one of the following, possibly with one or more prefix bytes:\n<ul>\n<li>Memory operations: <code>op r, m<\/code>; <code>op m, r<\/code>; or <code>op m<\/code>.<\/li>\n<li>String memory operations: <code>movs<\/code>, <code>stos<\/code>, etc.<\/li>\n<li>Selector load: <code>lds<\/code>, <code>les<\/code>, <code>pop ds<\/code>, <code>pop es<\/code>.<\/li>\n<\/ul>\n<\/li>\n<\/ul>\n<p>If the conditions are met, then the Ignore option became available. If you chose to Ignore, then the kernel did the following:<\/p>\n<ul>\n<li>If the faulting instruction is a selector load instruction, the destination selector register is set to zero.<\/li>\n<li>If the faulting instruction is a pop instruction, the stack pointer is incremented by two.<\/li>\n<li>The instruction pointer is advanced over the faulting instruction.<\/li>\n<li>Execution is resumed.<\/li>\n<\/ul>\n<p>In other words, the kernel did the assembly language equivalent of <code>ON ERROR RESUME NEXT<\/code>.<\/p>\n<p>Now, your reaction to this might be, &#8220;How could this possibly work? You are just randomly ignoring instructions!&#8221; But the strange thing is, <i>this idea was so crazy it actually worked<\/i>, or at least worked a lot of the time. You might have to hit Ignore a dozen times, but there&#8217;s a good chance that eventually the bad values in the registers will get overwritten by good values (and it probably won&#8217;t take long because the 8086 has so few registers), and the program will continue seemingly-normally.<\/p>\n<p>Totally crazy.<\/p>\n<p><b>Exercise<\/b>: Why didn&#8217;t the code have to know how to ignore jump instructions and conditional jump instructions?<\/p>\n<p><b>Bonus trivia<\/b>: The developer who implemented this crazy feature was Don Corbitt, <a href=\"http:\/\/blogs.msdn.com\/b\/oldnewthing\/archive\/2005\/11\/14\/492483.aspx\"> the same developer who wrote Dr. Watson<\/a>.<\/p>\n","protected":false},"excerpt":{"rendered":"<p>Muddling through.<\/p>\n","protected":false},"author":1069,"featured_media":111744,"comment_status":"closed","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"_acf_changed":false,"footnotes":""},"categories":[1],"tags":[2],"class_list":["post-90881","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-oldnewthing","tag-history"],"acf":[],"blog_post_summary":"<p>Muddling through.<\/p>\n","_links":{"self":[{"href":"https:\/\/devblogs.microsoft.com\/oldnewthing\/wp-json\/wp\/v2\/posts\/90881","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=90881"}],"version-history":[{"count":0,"href":"https:\/\/devblogs.microsoft.com\/oldnewthing\/wp-json\/wp\/v2\/posts\/90881\/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=90881"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/oldnewthing\/wp-json\/wp\/v2\/categories?post=90881"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/oldnewthing\/wp-json\/wp\/v2\/tags?post=90881"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}