{"id":355,"date":"2008-10-31T19:42:52","date_gmt":"2008-10-31T18:42:52","guid":{"rendered":"http:\/\/blog.m-ri.de\/?p=355"},"modified":"2008-11-01T08:33:23","modified_gmt":"2008-11-01T07:33:23","slug":"vs-tipps-tricks-heap-bugs-finden-teil-2","status":"publish","type":"post","link":"http:\/\/blog.m-ri.de\/index.php\/2008\/10\/31\/vs-tipps-tricks-heap-bugs-finden-teil-2\/","title":{"rendered":"VS Tipps &#038; Tricks: Heap Bugs finden (Teil 2)"},"content":{"rendered":"<p>Einige Hilfsmittel um einen Heap-Fehler zu finden habe ich in meinem <a href=\"http:\/\/blog.m-ri.de\/index.php\/2008\/10\/27\/vs-tipps-tricks-heap-bugs-finden-teil-1\/\">letzten Beitrag<\/a> ja beschrieben.<\/p>\n<p>Eigentlich w\u00fcnscht sich der Entwickler nichts mehr, als dass ein falscher Zugriff auf den Heap, sofort einen <em>Break <\/em>im Debugger ausl\u00f6st. Die Methoden, die ich bisher gezeigt habe (<em>AfxCheckMemory<\/em>, <em>_CrtCheckMemory<\/em>, <em>_CrtSetDbgFlag<\/em>)\u00a0k\u00f6nnen das nicht direkt , aber zumindest helfen sie den Fehler einzukreisen.<\/p>\n<p>Ein unverzichtbarer Helfer, der sofort solch einen <em>Break <\/em>ausl\u00f6sen kann, ist der <a href=\"http:\/\/msdn.microsoft.com\/de-de\/library\/ms220948(VS.80).aspx\">Application Verifier<\/a>, den ich bereits in einem \u00e4lteren Artikel als <a href=\"http:\/\/blog.m-ri.de\/index.php\/2007\/03\/02\/der-application-verifier-mein-neuer-freund\/\">Freund und Helfer<\/a> vorgestellt habe.<\/p>\n<p>Seit <em>Visual Studio 2005 <\/em>kann man direkt Parameter f\u00fcr den <em>Application Verifier <\/em>im Projekt einstellen und auch direkt den Debug-Prozess mit dem Application Verifier starten (<em>Umschalt+Alt+F5<\/em>).<br \/>\nAn den Standardeinstellungen im Projekt braucht man hier gar nichts zu \u00e4ndern:<br \/>\n<em>Conserve Memory <\/em>&#8211; No<br \/>\n<em>Protection Location <\/em>&#8211; Je nach Testfall (man sollte mit beiden Einstellungen mal debuggen)<br \/>\nAlle anderen Einstellungen <em>Verification Layers Settings <\/em>&#8211; auf Enable<\/p>\n<p>Mit dem <em>Application Verifier <\/em>l\u00e4sst sich der so genannte <em>Paged Heap <\/em>nutzen, der Guard Pages anlegt hinter oder vor den allokierten Speicherbereichen (siehe auch GFLAGS.EXE). Der Vorteil: Man erh\u00e4lt sofort eine Access Violation, wenn man den Speicherbereich \u00fcberschreitet.<\/p>\n<p>Mein kleines Demoproramm<\/p>\n<pre lang=\"cpp\" line=\"1\">#include &lt;windows.h&gt;\r\n#include &lt;tchar.h&gt;\r\n#include &lt;crtdbg.h&gt;\r\nint _tmain(int argc, _TCHAR* argv[])\r\n{\r\n  char *pCorrupt = new char[100];\r\n  ZeroMemory(pCorrupt,106); \/\/ -- This will corrupt the heap\r\n  char *pOther = new char[100];\r\n  ZeroMemory(pOther,100);\r\n  delete [] pOther;\r\n  delete [] pCorrupt;\r\n  return 0;\r\n}<\/pre>\n<p>crashed mit der Nutzung des <em>Application Verifiers <\/em>sofort und man kann im Call Stack die Zeile 7 ausmachen.<br \/>\nGenial ist besonders, dass der <em>Application Verifier<\/em> auch mit der Release Version sofort die Zeile 7 als Ursache identifiziert. Gerade wenn man also nicht auf die <em>Debug-CRT<\/em> zur\u00fcckgreifen kann, ist der Application Verifier ein super Hilfsmittel.<\/p>\n<p>Der Nachteil: Die Guard Pages liegen nicht exakt und direkt hinter dem allokierten Bereich, sondern auf der n\u00e4chsten Page Boundary. Deshalb crashed mein Sample auch nicht wenn man den Speicher um nur 1 Byte \u00fcberschreitet.<\/p>\n<p>Aber der Application Verifier ist zum Testen ein absolutes Muss, weil auch falsche Handles erkannt werden und auch der Lock Verfification Layer f\u00fcr die Qualit\u00e4tssicherung einfach n\u00fctzlich zum entwanzen sind. (siehe auch <a href=\"http:\/\/msdn.microsoft.com\/en-us\/library\/ms220936.aspx\">Application Verifier Einstellungen in der MSDN<\/a>).<\/p>\n<p>Hinweis \u2757<\/p>\n<p>Auf <em>Windows XP <\/em>und <em>Windows Server 2003 <\/em>erh\u00e4lt man ohne administrative Rechte die folgende Fehlermeldung:<\/p>\n<blockquote><p>Access denied. You need administrative credentials to use Application Verifier on image &lt;App_Name.exe&gt; on machine &lt;Machine_Name&gt;. Contact your system administrator for assistance<\/p><\/blockquote>\n<p>Unter Windows Vista oder Windows Server 2008 erh\u00e4lt man die flogende Fehlermeldung wenn der Application Verifier nicht elevated gestartet wird:<\/p>\n<blockquote><p>Access denied. You need administrative credentials to use Application Verifier on image &lt;App_Name.exe&gt; on machine &lt;Machine_Name&gt; or per user verifier settings should be enabled by the administrator. Please refer to documentation for more information.<\/p><\/blockquote>\n<p>Durch einen simplen Eintrag in der Registry l\u00e4sst sich aber auch als normaler Benutzer, ohne administrative Rechte, der<em> Application Verifier <\/em>nutzen, man erzeugt einen DWORD Eintrag in der Registry mit dem Wert 1<br \/>\n<em>HKEY_LOCAL_MACHINE\\SYSTEM\\CurrentControlSet\\Control\\Session Manger\\ImageExecutionOptions<br \/>\n<\/em>Nach einem Reboot kann man nun einfach den <em>Application Verifier <\/em>auch non-elevated, als normaler Benutzer nutzen.<\/p>\n","protected":false},"excerpt":{"rendered":"<p>Einige Hilfsmittel um einen Heap-Fehler zu finden habe ich in meinem letzten Beitrag ja beschrieben. Eigentlich w\u00fcnscht sich der Entwickler nichts mehr, als dass ein falscher Zugriff auf den Heap, sofort einen Break im Debugger ausl\u00f6st. Die Methoden, die ich bisher gezeigt habe (AfxCheckMemory, _CrtCheckMemory, _CrtSetDbgFlag)\u00a0k\u00f6nnen das nicht direkt , aber zumindest helfen sie den &hellip; <a href=\"http:\/\/blog.m-ri.de\/index.php\/2008\/10\/31\/vs-tipps-tricks-heap-bugs-finden-teil-2\/\" class=\"more-link\"><span class=\"screen-reader-text\">\u201eVS Tipps &#038; Tricks: Heap Bugs finden (Teil 2)\u201c <\/span>weiterlesen<\/a><\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"_jetpack_memberships_contains_paid_content":false,"footnotes":""},"categories":[25,30,19,11,20,4,3,31,2],"tags":[366,370,360,38,352,136,37,61],"class_list":["post-355","post","type-post","status-publish","format-standard","hentry","category-atl","category-c","category-crt","category-debugging","category-ide","category-mfc","category-programmieren","category-vs-tipps-tricks","category-windows-api","tag-atl","tag-c","tag-crt","tag-debuggen","tag-mfc","tag-qualitaetssicherung","tag-vs-tippstricks","tag-winapi"],"jetpack_featured_media_url":"","jetpack_sharing_enabled":true,"_links":{"self":[{"href":"http:\/\/blog.m-ri.de\/index.php\/wp-json\/wp\/v2\/posts\/355","targetHints":{"allow":["GET"]}}],"collection":[{"href":"http:\/\/blog.m-ri.de\/index.php\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"http:\/\/blog.m-ri.de\/index.php\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"http:\/\/blog.m-ri.de\/index.php\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"http:\/\/blog.m-ri.de\/index.php\/wp-json\/wp\/v2\/comments?post=355"}],"version-history":[{"count":1,"href":"http:\/\/blog.m-ri.de\/index.php\/wp-json\/wp\/v2\/posts\/355\/revisions"}],"predecessor-version":[{"id":356,"href":"http:\/\/blog.m-ri.de\/index.php\/wp-json\/wp\/v2\/posts\/355\/revisions\/356"}],"wp:attachment":[{"href":"http:\/\/blog.m-ri.de\/index.php\/wp-json\/wp\/v2\/media?parent=355"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"http:\/\/blog.m-ri.de\/index.php\/wp-json\/wp\/v2\/categories?post=355"},{"taxonomy":"post_tag","embeddable":true,"href":"http:\/\/blog.m-ri.de\/index.php\/wp-json\/wp\/v2\/tags?post=355"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}