{"id":509,"date":"2009-08-30T16:10:31","date_gmt":"2009-08-30T14:10:31","guid":{"rendered":"http:\/\/blog.m-ri.de\/?p=509"},"modified":"2009-08-30T19:19:20","modified_gmt":"2009-08-30T17:19:20","slug":"vs-tipps-tricks-direkter-break-in-den-debugger-bei-einem-assert","status":"publish","type":"post","link":"http:\/\/blog.m-ri.de\/index.php\/2009\/08\/30\/vs-tipps-tricks-direkter-break-in-den-debugger-bei-einem-assert\/","title":{"rendered":"VS-Tipps &#038; Tricks: Direkter Break in den Debugger bei einem ASSERT"},"content":{"rendered":"<p><em>ASSERTs<\/em> in der <em>MFC <\/em>und in der <em>CRT <\/em>sind tolle Hilfsmittel, aber nicht selten verf\u00e4lschen sie auch das Problem alleine dadurch, dass ein Fenster aufpoppt, wenn der <em>ASSERT <\/em>zuschl\u00e4gt. Hat man nun einen Code, der in einem Tooltipp etwas B\u00f6ses macht, dann wird der Tooltipp selbst aber schon wieder durch das erscheinen der <em>ASSERT <\/em>Meldung zerst\u00f6rt. Oder es wird ein neuer ASSERT ausgel\u00f6st. Der Callstack wird dadurch oft schwer zu lesen.<br \/>\nBesonders heikel kann dies auch noch werden wenn man mehrere Threads hat. Gleichfalls problematisch ist, dass in dem Moment in dem die ASSERT Box auftaucht nun auch wieder alle Timer weiterlaufen und sehr eigent\u00fcmliche Seiteneffekte weiter ausl\u00f6sen k\u00f6nnen, dito. Probleme in WM_PAINT Handlern, denn auch die l\u00f6sen evtl. schon wieder Aktionen aus, die Variablen ver\u00e4ndern.<\/p>\n<p>Nett ist am ASSERT-Dialog nat\u00fcrlich die M\u00f6glichkeit Ignorieren zu sagen und das Programm weiter laufen zu lassen. Ganz besonders wenn man Debug Versionen im Testfeld mit Anwendern testet.<\/p>\n<p>Dennoch bin ich bei Debug-Versionen dazu \u00fcbergegangen <em>ASSERTs<\/em> direkt\u00a0 crashen zu lassen, bzw. direkt einen Debug-Break auszul\u00f6sen. Das erleichtert das Lesen des Crashdumps bzw. hilft auch beim Debuggen, weil man direkt an der Stelle steht wo es hakt und alle Fenster und Variableninhalte exakt noch so sind, wie Sie es beim Auftreten des Problems waren (Tooltips, Popups, Men\u00fcs etc.).<\/p>\n<p>Der Code um das zu erreichen ist relativ simpel.\u00a0Man verwendet dazu <a href=\"http:\/\/msdn.microsoft.com\/en-us\/library\/94a21kwy(VS.80).aspx\">_CrtSetReportHook2<\/a>. In dem Hook sagt man einfach was man gerne h\u00e4tte. N\u00e4mlich bei einem <em>ASSERT<\/em> oder <em>ERROR<\/em> keinen Dialog sondern einen Break (<em>INT3<\/em>).<\/p>\n<pre lang=\"cpp\">#ifdef _DEBUG\r\nint __cdecl DebugReportHook(int nReportType, char* , int* pnRet)\r\n{\r\n  \/\/ Stop if no debugger is loaded and do not assert, cause a crash\r\n  \/\/ - returning TRUE indicates that we handled the problem, so no other hook\r\n  \/\/   needs to perform any action\r\n  \/\/ - setting the target of *pnRet to TRUE indicates that the CRT should\r\n  \/\/   execute an INT3 and should crash or break into the debugger.\r\n  return *pnRet = nReportType==_CRT_ASSERT ||\r\n                  nReportType==_CRT_ERROR ?\r\n                            TRUE : FALSE;\r\n}\r\n#endif\r\n\r\nvoid SetBreakOnAssert(BOOL bBreakOnAssert\/* =FALSE *\/)\r\n{ \u00a0\r\n\/\/ Need to disable the ASSERT handler?\r\n#ifdef _DEBUG \u00a0\r\n  if (bBreakOnAssert) \u00a0\u00a0\r\n    _CrtSetReportHook2(_CRT_RPTHOOK_INSTALL, DebugReportHook);\u00a0\r\n  else \u00a0\u00a0\r\n    _CrtSetReportHook2(_CRT_RPTHOOK_REMOVE, DebugReportHook);\r\n#else\r\n  UNUSED_ALWAYS(bBreakOnAssert);\r\n#endif\r\n}<\/pre>\n<p>Durch diese kleine\u00a0Funktion <em>SetBreakOnAssert<\/em> kann man dieses\u00a0Verhalten nun einfach ein- und ausschalten. N\u00e4here Details stehen im Kommentar der Hook-Funktion.<\/p>\n","protected":false},"excerpt":{"rendered":"<p>ASSERTs in der MFC und in der CRT sind tolle Hilfsmittel, aber nicht selten verf\u00e4lschen sie auch das Problem alleine dadurch, dass ein Fenster aufpoppt, wenn der ASSERT zuschl\u00e4gt. Hat man nun einen Code, der in einem Tooltipp etwas B\u00f6ses macht, dann wird der Tooltipp selbst aber schon wieder durch das erscheinen der ASSERT Meldung &hellip; <a href=\"http:\/\/blog.m-ri.de\/index.php\/2009\/08\/30\/vs-tipps-tricks-direkter-break-in-den-debugger-bei-einem-assert\/\" class=\"more-link\"><span class=\"screen-reader-text\">\u201eVS-Tipps &#038; Tricks: Direkter Break in den Debugger bei einem ASSERT\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":[30,19,11,4,3,27,172,31],"tags":[360,38,352,136,42,37],"class_list":["post-509","post","type-post","status-publish","format-standard","hentry","category-c","category-crt","category-debugging","category-mfc","category-programmieren","category-vs2008","category-vs2010","category-vs-tipps-tricks","tag-crt","tag-debuggen","tag-mfc","tag-qualitaetssicherung","tag-tippstricks","tag-vs-tippstricks"],"jetpack_featured_media_url":"","jetpack_sharing_enabled":true,"_links":{"self":[{"href":"http:\/\/blog.m-ri.de\/index.php\/wp-json\/wp\/v2\/posts\/509","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=509"}],"version-history":[{"count":0,"href":"http:\/\/blog.m-ri.de\/index.php\/wp-json\/wp\/v2\/posts\/509\/revisions"}],"wp:attachment":[{"href":"http:\/\/blog.m-ri.de\/index.php\/wp-json\/wp\/v2\/media?parent=509"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"http:\/\/blog.m-ri.de\/index.php\/wp-json\/wp\/v2\/categories?post=509"},{"taxonomy":"post_tag","embeddable":true,"href":"http:\/\/blog.m-ri.de\/index.php\/wp-json\/wp\/v2\/tags?post=509"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}