{"id":2349,"date":"2015-05-16T08:15:37","date_gmt":"2015-05-16T07:15:37","guid":{"rendered":"http:\/\/roboblog.fatal-fury.de\/?p=2349"},"modified":"2015-05-16T08:15:37","modified_gmt":"2015-05-16T07:15:37","slug":"integer-overflow-debugger-trap","status":"publish","type":"post","link":"http:\/\/roboblog.fatal-fury.de\/?p=2349","title":{"rendered":"integer overflow debugger trap"},"content":{"rendered":"<p>Benutzt man 16bit Integer statt 32bit um Speicher zu sparen und seine cache misses zu optimieren, l\u00e4uft man Gefahr den Zahlenbereich von -32768 bis +32767 zu verlassen. So wie es f\u00fcr Floatingpoint Zahlen \u00dcberpr\u00fcfungen auf over\/underflow etc gibt, die ein Signal werfen bzw den Compiler anspringen lassen, so gibt es das auch f\u00fcr Integer. Ist wohl nur nicht so bekannt.<\/p>\n<p>F\u00fcr den GNU Compiler gibt es die Option -ftrapv [1]<\/p>\n<blockquote><p>This option generates traps for signed overflow on addition, subtraction, multiplication operations.<\/p><\/blockquote>\n<p>Leider wird nicht erw\u00e4hnt, dass das Programm nun furchtbar langsamer l\u00e4uft. Weiterhin scheinen sich noch im Geheimen Fehler zu verbergen die ich nicht ganz verstehe. [2]<\/p>\n<blockquote><p>When -ftrapv is in effect, libcalls are \"necessary\" so that the results of an operation can be propagated without making the call to the libgcc functions dead.<\/p><\/blockquote>\n<p>Im Prinzip funktioniert das \u00dcberpr\u00fcfen auf Overflows aber ohne gro\u00dfe Einb\u00fc\u00dfen wie dieser Artikel zeigt [3]<\/p>\n<blockquote><p>How much overhead should we expect from enabling integer overflow checks? Using a compiler flag or built-in intrinsics, <strong>we should be able to do the check with a conditional branch that branches based on the overflow flag<\/strong> that add and sub set. <strong>Assuming that branch is always correctly predicted<\/strong> (which should be the case for most code), the costs of the branch are the cost of executing that correctly predicted not-taken branch, the pollution the branch causes in the branch history table, and the cost of decoding the branch.<br \/>\n...<br \/>\n<strong> result in 3% penalty<\/strong>.<br \/>\n...<br \/>\nJohn Regehr, who\u2019s done serious analysis on integer overflow checks estimates that <strong>the penalty should be about 5%<\/strong>, which is in the same ballpark as our napkin sketch estimate.<\/p><\/blockquote>\n<p>Der Artikel \"Catching Integer Overflows in C\" [4] gibt eine sch\u00f6ne \u00dcbersicht \u00fcber die Techniken der Overflow detections und jener FAQ Eintrag \"comp.lang.c FAQ list \u00b7 Question 20.6b\" [5] gibt eine Beispiel Implementierung. Mit dieser Einschr\u00e4nkung:<\/p>\n<blockquote><p>(Note: these functions all share one bug: they may fail if invoked on the largest negative integer, INT_MI<\/p><\/blockquote>\n<pre><code>#include < stdio.h >\r\n#include < limits.h >\r\n\r\nint chkadd(int a, int b) {\r\n\tif(b < 0)\r\n\t\treturn chksub(a, -b);\r\n\tif(INT_MAX - b < a) {\r\n\t\tfputs(\"int overflow\\n\", stderr);\r\n\t\treturn INT_MAX;\r\n\t}\r\n\treturn a + b;\r\n}\r\n\r\nint chksub(int a, int b) {\r\n\tif(b < 0)\r\n\t\treturn chkadd(a, -b);\r\n\tif(INT_MIN + b > a) {\r\n\t\tfputs(\"int underflow\\n\", stderr);\r\n\t\treturn INT_MIN;\r\n\t}\r\n\treturn a - b;\r\n}\r\n\r\nint chkmul(int a, int b) {\r\n\tint sign = 1;\r\n\tif(a == 0 || b == 0) return 0;\r\n\tif(a < 0) { a = -a; sign = -sign; }\r\n\tif(b < 0) { b = -b; sign = -sign; }\r\n\tif(INT_MAX \/ b < a) {\r\n\t\tfputs(\"int overflow\\n\", stderr);\r\n\t\treturn (sign > 0) ? INT_MAX : INT_MIN;\r\n\t}\r\n\treturn sign * a * b;\r\n}\r\n<\/code><\/pre>\n<p>Nun m\u00f6chte man nicht f\u00fcr das komplette Programm die \u00dcberpr\u00fcfung einschalten, sondern z.B. nur f\u00fcr 16bit Integer. Vielleicht implementiere ich einen eigenen Type mit \u00fcberladenen Funktionen daf\u00fcr. Irgendwann..<\/p>\n<p>[1] <a href=\"https:\/\/gcc.gnu.org\/onlinedocs\/gcc\/Code-Gen-Options.html\">https:\/\/gcc.gnu.org\/onlinedocs\/gcc\/Code-Gen-Options.html<\/a><br \/>\n[2] <a href=\"https:\/\/gcc.gnu.org\/bugzilla\/show_bug.cgi?id=35412\">https:\/\/gcc.gnu.org\/bugzilla\/show_bug.cgi?id=35412<\/a><br \/>\n[3] <a href=\"http:\/\/danluu.com\/integer-overflow\/\">http:\/\/danluu.com\/integer-overflow\/<\/a><br \/>\n[4] <a href=\"http:\/\/www.fefe.de\/intof.html\">http:\/\/www.fefe.de\/intof.html<\/a><br \/>\n[5] <a href=\"http:\/\/c-faq.com\/misc\/intovf.html\">http:\/\/c-faq.com\/misc\/intovf.html<\/a><\/p>\n","protected":false},"excerpt":{"rendered":"<p>Benutzt man 16bit Integer statt 32bit um Speicher zu sparen und seine cache misses zu optimieren, l\u00e4uft man Gefahr den Zahlenbereich von -32768 bis +32767 zu verlassen. So wie es f\u00fcr Floatingpoint Zahlen \u00dcberpr\u00fcfungen auf over\/underflow etc gibt, die ein Signal werfen bzw den Compiler anspringen lassen, so gibt es das auch f\u00fcr Integer. Ist [&hellip;]<\/p>\n","protected":false},"author":2,"featured_media":0,"comment_status":"closed","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[4],"tags":[14,17],"class_list":["post-2349","post","type-post","status-publish","format-standard","hentry","category-allgemein","tag-c","tag-cpp"],"_links":{"self":[{"href":"http:\/\/roboblog.fatal-fury.de\/index.php?rest_route=\/wp\/v2\/posts\/2349","targetHints":{"allow":["GET"]}}],"collection":[{"href":"http:\/\/roboblog.fatal-fury.de\/index.php?rest_route=\/wp\/v2\/posts"}],"about":[{"href":"http:\/\/roboblog.fatal-fury.de\/index.php?rest_route=\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"http:\/\/roboblog.fatal-fury.de\/index.php?rest_route=\/wp\/v2\/users\/2"}],"replies":[{"embeddable":true,"href":"http:\/\/roboblog.fatal-fury.de\/index.php?rest_route=%2Fwp%2Fv2%2Fcomments&post=2349"}],"version-history":[{"count":4,"href":"http:\/\/roboblog.fatal-fury.de\/index.php?rest_route=\/wp\/v2\/posts\/2349\/revisions"}],"predecessor-version":[{"id":2353,"href":"http:\/\/roboblog.fatal-fury.de\/index.php?rest_route=\/wp\/v2\/posts\/2349\/revisions\/2353"}],"wp:attachment":[{"href":"http:\/\/roboblog.fatal-fury.de\/index.php?rest_route=%2Fwp%2Fv2%2Fmedia&parent=2349"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"http:\/\/roboblog.fatal-fury.de\/index.php?rest_route=%2Fwp%2Fv2%2Fcategories&post=2349"},{"taxonomy":"post_tag","embeddable":true,"href":"http:\/\/roboblog.fatal-fury.de\/index.php?rest_route=%2Fwp%2Fv2%2Ftags&post=2349"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}