<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>Martin&#039;s Blog &#187; CRT</title>
	<atom:link href="http://blog.m-ri.de/index.php/category/programmieren/crt/feed/" rel="self" type="application/rss+xml" />
	<link>http://blog.m-ri.de</link>
	<description>Gesammeltes aus dem Leben eines &#34;normalen&#34; Programmierers... :-)</description>
	<lastBuildDate>Sat, 04 Feb 2012 12:07:16 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.3.1</generator>
		<item>
		<title>Für was ist der Makro %(PreprocessorDefinitions) gut ?</title>
		<link>http://blog.m-ri.de/index.php/2011/10/16/fur-was-ist-der-makro-preprocessordefinitions-gut/</link>
		<comments>http://blog.m-ri.de/index.php/2011/10/16/fur-was-ist-der-makro-preprocessordefinitions-gut/#comments</comments>
		<pubDate>Sun, 16 Oct 2011 17:54:35 +0000</pubDate>
		<dc:creator>Martin Richter</dc:creator>
				<category><![CDATA[ATL]]></category>
		<category><![CDATA[CRT]]></category>
		<category><![CDATA[IDE]]></category>
		<category><![CDATA[MFC]]></category>
		<category><![CDATA[Programmieren]]></category>
		<category><![CDATA[VS 2008]]></category>
		<category><![CDATA[VS 2010]]></category>
		<category><![CDATA[C++]]></category>
		<category><![CDATA[Compiler]]></category>
		<category><![CDATA[VS-2008]]></category>
		<category><![CDATA[VS-2010]]></category>

		<guid isPermaLink="false">http://blog.m-ri.de/?p=903</guid>
		<description><![CDATA[In den C++ Compilereinstellungen finden sich ein vorgegebener Makro %(PreprocessorDefinitions) in den C++ Präprozessor Definitionen. Die Verwendung dieses Makros ist nicht ganz offensichtlich. Dieser Makro sollten in jedem Fall nicht entfernt werden, denn Sie dienen der Übernahme einiger Einstellungen aus der General-Seite für die C++ Projekte. Zum Beispiel werden die Einstellungen für Unicode und MBCS über [...]]]></description>
			<content:encoded><![CDATA[<p>In den C++ Compilereinstellungen finden sich ein vorgegebener Makro <em>%(PreprocessorDefinitions)</em> in den C++ Präprozessor Definitionen. Die Verwendung dieses Makros ist nicht ganz offensichtlich.</p>
<p>Dieser Makro sollten in jedem Fall nicht entfernt werden, denn Sie dienen der Übernahme einiger Einstellungen aus der <em>General</em>-Seite für die C++ Projekte. Zum Beispiel werden die Einstellungen für Unicode und MBCS über den Makro <em>%(PreprocessorDefinitions)</em> in die allgemeinen Compiler-Einstellungen übernommen (die entsprechenden Defines sind <em>_UNICODE; UNICODE; _MBCS </em>).<br />
Erzeugt man eine DLL wird zusätzlich <em>_WINDLL</em> gesetzt.<br />
Setzt man ATL Optionen in der General Seite wird auch über die <em>%(PreprocessorDefinitions) _ATLDLL</em> bzw. <em>_ATL_STATIC_REGISTRY</em> gesetzt oder zurückgesetzt.<br />
Gleiches gilt, wenn die <em>MFC</em> als shared DLL verwendet wird. In diesem Fall wird der Define <em>_AFXDLL</em> zusätzlich gesetzt.</p>
<p>Löscht man also <em>%(PreprocessorDefinitions)</em> dann werden alle diese Einstellungen nicht mehr  korrekt übernommen.</p>
<p>Anmerkung:<br />
Bei dem Linker Makro <em>%(AdditionalDependencies) </em>habe ich eine ähnliche Verwendung vermutet, konnte aber keine direkte Beziehung zur Seite General herstellen.</p>
<p>Obwohl es auch hier Einflüsse auf die Linkereinstellungen gibt bei Änderungen in den <em>General</em>-Einstellungen. Werden allerdings die MFC als zusätzliche Bibliothek ausgewählt werden die Standard-LIBs aus dem SDK komplett entfernt. Hier gibt die MFC Bibliothek selbst vor in welchen zusätzlichen Libs, des SDK gesucht werden soll über #pragma comment(lib,..).</p>
<hr /><small>Copyright &copy; 2010 Martin Richter<br />Dieser Feed ist nur für den persönlichen, nicht gewerblichen Gebrauch bestimmt. Eine Verwendung dieses Feeds bzw. der hier veröffentlichten Beiträge auf anderen Webseiten bedarf der ausdrücklichen Genehmigung des Autors.<br />(Digital Fingerprint: bdafe67664ea5aacaab71f8c0a581adf)</small>]]></content:encoded>
			<wfw:commentRss>http://blog.m-ri.de/index.php/2011/10/16/fur-was-ist-der-makro-preprocessordefinitions-gut/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Änderungen in den VC-Libraries des Sicherheitsupdates vom 09.08.2011</title>
		<link>http://blog.m-ri.de/index.php/2011/08/12/anderungen-in-den-vc-libraries-des-sicherheitsupdates-vom-09-08-2011/</link>
		<comments>http://blog.m-ri.de/index.php/2011/08/12/anderungen-in-den-vc-libraries-des-sicherheitsupdates-vom-09-08-2011/#comments</comments>
		<pubDate>Fri, 12 Aug 2011 18:49:30 +0000</pubDate>
		<dc:creator>Martin Richter</dc:creator>
				<category><![CDATA[C++]]></category>
		<category><![CDATA[CRT]]></category>
		<category><![CDATA[Programmieren]]></category>
		<category><![CDATA[VS 2010]]></category>
		<category><![CDATA[MFC]]></category>
		<category><![CDATA[SP1]]></category>
		<category><![CDATA[VS-2010]]></category>

		<guid isPermaLink="false">http://blog.m-ri.de/?p=887</guid>
		<description><![CDATA[Eigentlich kann man es kein Sicherheitsupdate nennen. Ich sehe  eigentlich nur eine sicherheitsrelevante Änderung in: atltransactionmanager.h (ATL) Hier wird das Laden der ktmw32.dll jetzt mit einer neuen Funktion AtlLoadSystemLibraryUsingFullPath durchgeführt, die in atlcore.h hinzugefügt wird. Diese Funktion lädt eine DLL nur aus dem Windows-System Verzeichnis. Damit wird Binary-Planting verhindert, aber dies betrifft eigentlich nur Windows [...]]]></description>
			<content:encoded><![CDATA[<p>Eigentlich kann man es kein Sicherheitsupdate nennen. Ich sehe  eigentlich nur eine sicherheitsrelevante Änderung in:</p>
<ul>
<li><strong>atltransactionmanager.h (ATL)</strong><br />
Hier wird das Laden der ktmw32.dll jetzt mit einer neuen Funktion <em>AtlLoadSystemLibraryUsingFullPath</em> durchgeführt, die in <strong><em>atlcore.h</em></strong> hinzugefügt wird. Diese Funktion lädt eine DLL nur aus dem Windows-System Verzeichnis. Damit wird Binary-Planting verhindert, aber dies betrifft eigentlich nur <del><em>Windows Vista / 7 / 2008</em></del> <span style="text-decoration: underline;">Windows 2003 und Windows XP</span> <em>(Nachtrag am 18.08. siehe dazu Kommentar von Stefan Kuhr)</em> und diejenigen die den <em>Kernel Transaction Manager</em> mit der <em>ATL</em> nutzen.</li>
</ul>
<p>Bugfixes habe ich folgende gefunden:</p>
<ul>
<li><strong>afxtoolbarimages.cpp (MFC)</strong><br />
In <em>CPngImage::LoadFromBuffer</em> wurde bei der Verwendung dieser Funktion in Speicherblock eines Streams nicht freigegeben (falsche Nutzung von <em>CreateStreamOnHGlobal</em>).</li>
<li><strong>dbcore (MFC / ODBC)</strong><br />
In <em>CRecordset::BuildUpdateSQL</em> in der ODBC Implementierung, wird bei Abfrage eines Cursornamens ein Puffer von 18 Zeichen Länge verwendet (<em>MAX_CURSOR_NAME</em>). Ist der Cursorname länger so wurde eine Exception geworfen. Jetzt wird erkannt, dass der Buffer zu klein ist und es wird ein dynamischer Buffer mit ausreichender Größe alloziert und der Name dann abgefragt.</li>
<li> <strong>xutility (STL und auch CRT)</strong><br />
In der Basisklasse der Iteratoren wurde eine Änderung gemacht. Scheinbar hat die Zuweisung eines &#8220;leeren/nicht initialisierten&#8221; Iterators bisher einen Iterator gar nicht verändert. Der alte Iterator wurde nicht aufgelöst durch <em>_Orphan_me</em>. Dies bringt dann Probleme mit sich wenn der <em>_ITERATOR_DEBUG_LEVEL</em> mit 2 genutzt wird.<br />
Da dieser STL Code auch komplett in der CRT verwendet wird, hat dies auch Einfluß auf die CRT.<br />
Auf die Release Version aber hat diese Code-Änderung jedoch keinen Einfluss, soweit ich das erkennen kann.</li>
</ul>
<p>Es gibt noch einige andere Dateien, die geändert wurde, aber hier haben sich nur unwichtige Kommentare geändert.</p>
<p>Fazit: Alles in allem ein Sicherheitspatch, der eher Bugfixes enthält, aber selbst die sind nicht sonderlich weitreichend. Und der Nutzerbereich, der mit der <em>ATL</em> den <em>Kernel Transaction Manager</em> nutzt, wird wohl eher klein sein&#8230;</p>
<p>PS: Die Dateien dieses Sicherheitspatches haben die Version 10.0.40219.325.<br />
Die Dateien aus dem VS-2010 SP1 haben die Versionsnummer 10.0.30319.1.</p>
<p><strong>Nachtrag 01.12.2011, MSDN Links:</strong><br />
Sicherheits Bullentin:   <a href="http://www.microsoft.com/technet/security/bulletin/MS11-025.mspx">MS11-025</a><br />
Knowledge Base-Artikel (KB-Artikel):  <a href="http://support.microsoft.com/?kbid=2565057">KB2565057</a></p>
<hr /><small>Copyright &copy; 2010 Martin Richter<br />Dieser Feed ist nur für den persönlichen, nicht gewerblichen Gebrauch bestimmt. Eine Verwendung dieses Feeds bzw. der hier veröffentlichten Beiträge auf anderen Webseiten bedarf der ausdrücklichen Genehmigung des Autors.<br />(Digital Fingerprint: bdafe67664ea5aacaab71f8c0a581adf)</small>]]></content:encoded>
			<wfw:commentRss>http://blog.m-ri.de/index.php/2011/08/12/anderungen-in-den-vc-libraries-des-sicherheitsupdates-vom-09-08-2011/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>Feature Request: Always ask the developer before applying a service pack or a security fix to Visual Studio that need changed C++ runtime DLLs ATL/MFC/CRT</title>
		<link>http://blog.m-ri.de/index.php/2011/04/20/feature-request-always-ask-the-developer-before-applying-a-service-pack-or-a-security-fix-to-visual-studio-that-need-changed-c-runtime-dlls-atlmfccrt/</link>
		<comments>http://blog.m-ri.de/index.php/2011/04/20/feature-request-always-ask-the-developer-before-applying-a-service-pack-or-a-security-fix-to-visual-studio-that-need-changed-c-runtime-dlls-atlmfccrt/#comments</comments>
		<pubDate>Wed, 20 Apr 2011 15:55:54 +0000</pubDate>
		<dc:creator>Martin Richter</dc:creator>
				<category><![CDATA[C++]]></category>
		<category><![CDATA[CRT]]></category>
		<category><![CDATA[Programmieren]]></category>
		<category><![CDATA[VS 2008]]></category>
		<category><![CDATA[VS 2010]]></category>
		<category><![CDATA[Feature Request]]></category>
		<category><![CDATA[Qualitätssicherung]]></category>
		<category><![CDATA[VS-2005]]></category>
		<category><![CDATA[VS-2008]]></category>
		<category><![CDATA[VS-2010]]></category>

		<guid isPermaLink="false">http://blog.m-ri.de/?p=832</guid>
		<description><![CDATA[I know this is a German blog, but for reaching a wider range of developer this article is written in English In the past security patches to Visual Studio were automatically installed on the machines of developers. This might have a great impact of to the shipment of the software that is created with this [...]]]></description>
			<content:encoded><![CDATA[<p>I know this is a German blog, but for reaching a wider range of developer this article is written in English <img src='http://blog.m-ri.de/wp-includes/images/smilies/icon_smile.gif' alt=':-)' class='wp-smiley' /> </p>
<p>In the past security patches to <em>Visual Studio </em>were automatically installed on the machines of developers. This might have a great impact of to the shipment of the software that is created with this new pachted Visual-Studio version and it might cause incompatibilities with previous created modules.</p>
<p>And we all suffered under the problems that came with this patches and I don&#8217;t want to know how much time and money was wasted here.</p>
<p>Also I am aware of the risk that is caused when security fixes are not applied. But the last decision must be allowed to a developer if a fix is applied or not.</p>
<p>To avoid this I have a feature request that such security fixes to Visual Studio (any Version: <em>VS-2005</em>, <em>VS-2008</em>, <em>VS-2010</em>) is only applied to the developers machine if he is asked to do this!</p>
<p>Please use your vote and your words to comment this feature request <img src='http://blog.m-ri.de/wp-includes/images/smilies/icon_exclaim.gif' alt=':!:' class='wp-smiley' /><br />
Here is the link:</p>
<p><strong><a href="https://connect.microsoft.com/VisualStudio/feedback/details/662511/always-ask-the-developer-before-applying-a-security-fix-or-service-pack-to-visual-studio-that-need-changed-the-c-runtime-dlls-atl-mfc-crt">Always ask the developer before applying a security fix or service pack to Visual Studio that need changed the C++ runtime DLLs ATL/MFC/CRT</a></strong></p>
<hr /><small>Copyright &copy; 2010 Martin Richter<br />Dieser Feed ist nur für den persönlichen, nicht gewerblichen Gebrauch bestimmt. Eine Verwendung dieses Feeds bzw. der hier veröffentlichten Beiträge auf anderen Webseiten bedarf der ausdrücklichen Genehmigung des Autors.<br />(Digital Fingerprint: bdafe67664ea5aacaab71f8c0a581adf)</small>]]></content:encoded>
			<wfw:commentRss>http://blog.m-ri.de/index.php/2011/04/20/feature-request-always-ask-the-developer-before-applying-a-service-pack-or-a-security-fix-to-visual-studio-that-need-changed-c-runtime-dlls-atlmfccrt/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>BUG: VC-2010 ftell liefert negative Werte wenn eine UTF-8 Datei mit ccs=UNICODE geöffnet wird, die nicht mit fseek funktionieren</title>
		<link>http://blog.m-ri.de/index.php/2010/12/27/bug-vc-2010-ftell-liefert-negative-werte-wenn-eine-utf-8-datei-mit-ccsunicode-geoeffnet-wird-die-nicht-mit-fseek-funktionieren/</link>
		<comments>http://blog.m-ri.de/index.php/2010/12/27/bug-vc-2010-ftell-liefert-negative-werte-wenn-eine-utf-8-datei-mit-ccsunicode-geoeffnet-wird-die-nicht-mit-fseek-funktionieren/#comments</comments>
		<pubDate>Mon, 27 Dec 2010 08:33:16 +0000</pubDate>
		<dc:creator>Martin Richter</dc:creator>
				<category><![CDATA[C++]]></category>
		<category><![CDATA[CRT]]></category>
		<category><![CDATA[MFC]]></category>
		<category><![CDATA[Programmieren]]></category>
		<category><![CDATA[VS 2008]]></category>
		<category><![CDATA[VS 2010]]></category>
		<category><![CDATA[Bug]]></category>
		<category><![CDATA[VS-2010]]></category>

		<guid isPermaLink="false">http://blog.m-ri.de/?p=667</guid>
		<description><![CDATA[In VS-2005 hielt die Unicode und UTF-8 Unterstützung Einzug in die CRT und damit auch in die MFC. Jochen und ich haben dazu gebloggt. Leider ist die Implementierung nicht fehlerfrei. Wenn man eine UTF-8 Datei mit ccs=UNICODE öffnet dann liefert ftell zum Teil auch negative Werte. Das ftell nicht die exakte Position in der Datei [...]]]></description>
			<content:encoded><![CDATA[<p lang="cpp">In <em>VS-2005</em> hielt die Unicode und <em>UTF-8</em> Unterstützung Einzug in die <em>CRT </em>und damit auch in die <em>MFC</em>. Jochen und ich haben dazu <a href="http://blog.m-ri.de/index.php/2007/07/03/vc-2005-features-der-crt-fuer-unicode-unterstuetzung/">gebloggt</a>.</p>
<p lang="cpp">Leider ist die Implementierung nicht fehlerfrei. Wenn man eine <em>UTF-8</em> Datei mit <em>ccs=UNICODE</em> öffnet dann liefert <em>ftell</em> zum Teil auch negative Werte. Das ftell nicht die exakte Position in der Datei liefert ist dokumentiert, nur sollte es mit dem Wert zumindest möglich sein wieder fseek aufzurufen um an eine alte Dateiposition zurück zu gelangen.<br />
Das ist mit der jetzigen Implementierung nicht möglich.</p>
<p lang="cpp">Ein Sample dazu ist schnell gebaut:</p>

<div class="wp_syntax"><div class="code"><pre class="cpp" style="font-family:monospace;"><span style="color: #0000ff;">int</span> _tmain<span style="color: #008000;">&#40;</span><span style="color: #008000;">&#41;</span>
<span style="color: #008000;">&#123;</span>
  <span style="color: #0000ff;">FILE</span> <span style="color: #000040;">*</span>file <span style="color: #000080;">=</span> <span style="color: #0000ff;">NULL</span><span style="color: #008080;">;</span>
  <span style="color: #0000ff;">if</span> <span style="color: #008000;">&#40;</span>_tfopen_s<span style="color: #008000;">&#40;</span><span style="color: #000040;">&amp;</span>file,_T<span style="color: #008000;">&#40;</span><span style="color: #FF0000;">&quot;Test.txt&quot;</span><span style="color: #008000;">&#41;</span>,_T<span style="color: #008000;">&#40;</span><span style="color: #FF0000;">&quot;rt&quot;</span><span style="color: #008000;">&#41;</span> _T<span style="color: #008000;">&#40;</span><span style="color: #FF0000;">&quot;, ccs=UNICODE&quot;</span><span style="color: #008000;">&#41;</span><span style="color: #008000;">&#41;</span><span style="color: #008000;">&#41;</span>
    <span style="color: #0000ff;">return</span> <span style="color: #000040;">-</span><span style="color: #0000dd;">1</span><span style="color: #008080;">;</span>
&nbsp;
  TCHAR szBuffer<span style="color: #008000;">&#91;</span>_MAX_PATH<span style="color: #008000;">&#93;</span><span style="color: #008080;">;</span>
  <span style="color: #0000ff;">while</span> <span style="color: #008000;">&#40;</span>_fgetts<span style="color: #008000;">&#40;</span>szBuffer,_countof<span style="color: #008000;">&#40;</span>szBuffer<span style="color: #008000;">&#41;</span>,file<span style="color: #008000;">&#41;</span><span style="color: #008000;">&#41;</span>
  <span style="color: #008000;">&#123;</span>
    <span style="color: #0000ff;">int</span> iPos <span style="color: #000080;">=</span> <span style="color: #0000ff;">static_cast</span><span style="color: #008000;">&#40;</span><span style="color: #0000dd;">ftell</span><span style="color: #008000;">&#40;</span>file<span style="color: #008000;">&#41;</span><span style="color: #008000;">&#41;</span><span style="color: #008080;">;</span>
    _tprintf<span style="color: #008000;">&#40;</span>_T<span style="color: #008000;">&#40;</span><span style="color: #FF0000;">&quot;%d<span style="color: #000099; font-weight: bold;">\n</span>&quot;</span><span style="color: #008000;">&#41;</span>,iPos<span style="color: #008000;">&#41;</span><span style="color: #008080;">;</span>
    _ASSERTE<span style="color: #008000;">&#40;</span><span style="color: #0000dd;">fseek</span><span style="color: #008000;">&#40;</span>file,iPos,<span style="color: #0000ff;">SEEK_SET</span><span style="color: #008000;">&#41;</span><span style="color: #000080;">==</span><span style="color: #0000dd;">0</span><span style="color: #008000;">&#41;</span><span style="color: #008080;">;</span>
  <span style="color: #008000;">&#125;</span>
&nbsp;
  <span style="color: #0000dd;">fclose</span><span style="color: #008000;">&#40;</span>file<span style="color: #008000;">&#41;</span><span style="color: #008080;">;</span>
  <span style="color: #0000ff;">return</span> <span style="color: #0000dd;">0</span><span style="color: #008080;">;</span>
<span style="color: #008000;">&#125;</span></pre></div></div>

<p><a href="http://blog.m-ri.de/wp-content/uploads/2010/12/TestFtell.zip">Ein entsprechendes Sample kann man hier herunterladen</a>.</p>
<p>Der Fehler betrifft natürlich auch die MFC mit <em>CStdioFile </em>und <em>GetPosition</em>!</p>
<p>Hintergrund:<br />
Ich kam auf den Fehler, weil wir ein Programm benutzen, dass sich bestimmte Dateipositionen merkte um einen Datenimport bei einer bestimmten Bedingung, ab einer definierten Stelle, neu aufnehmen zu können. Bisher hatten wir hier nur pure ASCII Dateien erlaubt, jetzt wollten wir auch UTF-8 Dateien unterstützen.<br />
Sicher man kann auch alles im Speicher zwischenhalten, aber wenn es eine simple Dateiposition ist das Ganze so weitaus Ressourcen schonender.</p>
<p>Soweit ich das übersehen kann, betrifft der Fehler alle VS-Versionen ab VS-2005. Ein entsprechende Bug wurde von mir schon vor längerer Zeit auf Connect geöffnet. Getan hat sich bisher noch nichts:<br />
<a href="https://connect.microsoft.com/VisualStudio/feedback/details/591030/ftell-returns-negative-value-for-utf-8-files-opened-with-textmode-and-ccs">https://connect.microsoft.com/VisualStudio/feedback/details/591030/ftell-returns-negative-value-for-utf-8-files-opened-with-textmode-and-ccs</a></p>
<hr /><small>Copyright &copy; 2010 Martin Richter<br />Dieser Feed ist nur für den persönlichen, nicht gewerblichen Gebrauch bestimmt. Eine Verwendung dieses Feeds bzw. der hier veröffentlichten Beiträge auf anderen Webseiten bedarf der ausdrücklichen Genehmigung des Autors.<br />(Digital Fingerprint: bdafe67664ea5aacaab71f8c0a581adf)</small>]]></content:encoded>
			<wfw:commentRss>http://blog.m-ri.de/index.php/2010/12/27/bug-vc-2010-ftell-liefert-negative-werte-wenn-eine-utf-8-datei-mit-ccsunicode-geoeffnet-wird-die-nicht-mit-fseek-funktionieren/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>VS-Tipps &amp; Tricks: Direkter Break in den Debugger bei einem ASSERT</title>
		<link>http://blog.m-ri.de/index.php/2009/08/30/vs-tipps-tricks-direkter-break-in-den-debugger-bei-einem-assert/</link>
		<comments>http://blog.m-ri.de/index.php/2009/08/30/vs-tipps-tricks-direkter-break-in-den-debugger-bei-einem-assert/#comments</comments>
		<pubDate>Sun, 30 Aug 2009 14:10:31 +0000</pubDate>
		<dc:creator>Martin Richter</dc:creator>
				<category><![CDATA[C++]]></category>
		<category><![CDATA[CRT]]></category>
		<category><![CDATA[Debugging]]></category>
		<category><![CDATA[MFC]]></category>
		<category><![CDATA[Programmieren]]></category>
		<category><![CDATA[VS 2008]]></category>
		<category><![CDATA[VS 2010]]></category>
		<category><![CDATA[VS-Tipps&Tricks]]></category>
		<category><![CDATA[Debuggen]]></category>
		<category><![CDATA[Qualitätssicherung]]></category>
		<category><![CDATA[Tipps&Tricks]]></category>

		<guid isPermaLink="false">http://blog.m-ri.de/?p=509</guid>
		<description><![CDATA[ASSERTs in der MFC und in der CRT sind tolle Hilfsmittel, aber nicht selten verfälschen sie auch das Problem alleine dadurch, dass ein Fenster aufpoppt, wenn der ASSERT zuschlägt. Hat man nun einen Code, der in einem Tooltipp etwas Böses macht, dann wird der Tooltipp selbst aber schon wieder durch das erscheinen der ASSERT Meldung [...]]]></description>
			<content:encoded><![CDATA[<p><em>ASSERTs</em> in der <em>MFC </em>und in der <em>CRT </em>sind tolle Hilfsmittel, aber nicht selten verfälschen sie auch das Problem alleine dadurch, dass ein Fenster aufpoppt, wenn der <em>ASSERT </em>zuschlägt. Hat man nun einen Code, der in einem Tooltipp etwas Böses macht, dann wird der Tooltipp selbst aber schon wieder durch das erscheinen der <em>ASSERT </em>Meldung zerstört. Oder es wird ein neuer ASSERT ausgelöst. Der Callstack wird dadurch oft schwer zu lesen.<br />
Besonders 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ümliche Seiteneffekte weiter auslösen können, dito. Probleme in WM_PAINT Handlern, denn auch die lösen evtl. schon wieder Aktionen aus, die Variablen verändern.</p>
<p>Nett ist am ASSERT-Dialog natürlich die Möglichkeit Ignorieren zu sagen und das Programm weiter laufen zu lassen. Ganz besonders wenn man Debug Versionen im Testfeld mit Anwendern testet.</p>
<p>Dennoch bin ich bei Debug-Versionen dazu übergegangen <em>ASSERTs</em> direkt  crashen zu lassen, bzw. direkt einen Debug-Break auszulösen. 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üs etc.).</p>
<p>Der Code um das zu erreichen ist relativ simpel. Man 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ätte. Nämlich bei einem <em>ASSERT</em> oder <em>ERROR</em> keinen Dialog sondern einen Break (<em>INT3</em>).</p>

<div class="wp_syntax"><div class="code"><pre class="cpp" style="font-family:monospace;"><span style="color: #339900;">#ifdef _DEBUG</span>
<span style="color: #0000ff;">int</span> __cdecl DebugReportHook<span style="color: #008000;">&#40;</span><span style="color: #0000ff;">int</span> nReportType, <span style="color: #0000ff;">char</span><span style="color: #000040;">*</span> , <span style="color: #0000ff;">int</span><span style="color: #000040;">*</span> pnRet<span style="color: #008000;">&#41;</span>
<span style="color: #008000;">&#123;</span>
  <span style="color: #666666;">// Stop if no debugger is loaded and do not assert, cause a crash</span>
  <span style="color: #666666;">// - returning TRUE indicates that we handled the problem, so no other hook</span>
  <span style="color: #666666;">//   needs to perform any action</span>
  <span style="color: #666666;">// - setting the target of *pnRet to TRUE indicates that the CRT should</span>
  <span style="color: #666666;">//   execute an INT3 and should crash or break into the debugger.</span>
  <span style="color: #0000ff;">return</span> <span style="color: #000040;">*</span>pnRet <span style="color: #000080;">=</span> nReportType<span style="color: #000080;">==</span>_CRT_ASSERT <span style="color: #000040;">||</span>
                  nReportType<span style="color: #000080;">==</span>_CRT_ERROR <span style="color: #008080;">?</span>
                            TRUE <span style="color: #008080;">:</span> FALSE<span style="color: #008080;">;</span>
<span style="color: #008000;">&#125;</span>
<span style="color: #339900;">#endif</span>
&nbsp;
<span style="color: #0000ff;">void</span> SetBreakOnAssert<span style="color: #008000;">&#40;</span>BOOL bBreakOnAssert<span style="color: #ff0000; font-style: italic;">/* =FALSE */</span><span style="color: #008000;">&#41;</span>
<span style="color: #008000;">&#123;</span>  
<span style="color: #666666;">// Need to disable the ASSERT handler?</span>
<span style="color: #339900;">#ifdef _DEBUG  </span>
  <span style="color: #0000ff;">if</span> <span style="color: #008000;">&#40;</span>bBreakOnAssert<span style="color: #008000;">&#41;</span>   
    _CrtSetReportHook2<span style="color: #008000;">&#40;</span>_CRT_RPTHOOK_INSTALL, DebugReportHook<span style="color: #008000;">&#41;</span><span style="color: #008080;">;</span> 
  <span style="color: #0000ff;">else</span>   
    _CrtSetReportHook2<span style="color: #008000;">&#40;</span>_CRT_RPTHOOK_REMOVE, DebugReportHook<span style="color: #008000;">&#41;</span><span style="color: #008080;">;</span>
<span style="color: #339900;">#else</span>
  UNUSED_ALWAYS<span style="color: #008000;">&#40;</span>bBreakOnAssert<span style="color: #008000;">&#41;</span><span style="color: #008080;">;</span>
<span style="color: #339900;">#endif</span>
<span style="color: #008000;">&#125;</span></pre></div></div>

<p>Durch diese kleine Funktion <em>SetBreakOnAssert</em> kann man dieses Verhalten nun einfach ein- und ausschalten. Nähere Details stehen im Kommentar der Hook-Funktion.</p>
<hr /><small>Copyright &copy; 2010 Martin Richter<br />Dieser Feed ist nur für den persönlichen, nicht gewerblichen Gebrauch bestimmt. Eine Verwendung dieses Feeds bzw. der hier veröffentlichten Beiträge auf anderen Webseiten bedarf der ausdrücklichen Genehmigung des Autors.<br />(Digital Fingerprint: bdafe67664ea5aacaab71f8c0a581adf)</small>]]></content:encoded>
			<wfw:commentRss>http://blog.m-ri.de/index.php/2009/08/30/vs-tipps-tricks-direkter-break-in-den-debugger-bei-einem-assert/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>Tipps &amp; Tricks: Wie man einen permanenten ASSERT direkt mit einem Kommentar versieht</title>
		<link>http://blog.m-ri.de/index.php/2009/06/07/wie-man-einen-permanenten-assert-direkt-mit-einem-kommentar-versieht/</link>
		<comments>http://blog.m-ri.de/index.php/2009/06/07/wie-man-einen-permanenten-assert-direkt-mit-einem-kommentar-versieht/#comments</comments>
		<pubDate>Sun, 07 Jun 2009 10:08:04 +0000</pubDate>
		<dc:creator>Martin Richter</dc:creator>
				<category><![CDATA[C++]]></category>
		<category><![CDATA[CRT]]></category>
		<category><![CDATA[Debugging]]></category>
		<category><![CDATA[MFC]]></category>
		<category><![CDATA[Programmieren]]></category>
		<category><![CDATA[Debuggen]]></category>
		<category><![CDATA[Qualitätssicherung]]></category>
		<category><![CDATA[Tipps&Tricks]]></category>

		<guid isPermaLink="false">http://blog.m-ri.de/?p=461</guid>
		<description><![CDATA[Ich verwende gerne ASSERT&#8217;s in meinem Code. Sie sind ein wirksames Mittel Zustände abzufragen und bereist in der Testphase unzulässige Konstellationen oder Funktionsaufrufe zu entdecken. Nun gibt es ja auch if, else oder switch Blöcke an denen das Programm normalerweise nicht vorbei kommen sollte. So eine Stelle versieht man dann schon mal mit einem _ASSERT&#40; FALSE &#41;; [...]]]></description>
			<content:encoded><![CDATA[<p>Ich verwende gerne ASSERT&#8217;s in meinem Code.<br />
Sie sind ein wirksames Mittel Zustände abzufragen und bereist in der Testphase unzulässige Konstellationen oder Funktionsaufrufe zu entdecken.</p>
<p>Nun gibt es ja auch <em>if</em>, <em>else <em></em></em>oder <em><em>switch </em></em>Blöcke an denen das Programm normalerweise nicht vorbei kommen sollte. So eine Stelle versieht man dann schon mal mit einem</p>

<div class="wp_syntax"><div class="code"><pre class="cpp" style="font-family:monospace;">_ASSERT<span style="color: #008000;">&#40;</span> FALSE <span style="color: #008000;">&#41;</span><span style="color: #008080;">;</span>
<span style="color: #666666;">// oder wer die MFC benutzt eben ASSERT,</span>
<span style="color: #666666;">// obwohl dies auch nur ein Synonym für den CRT _ASSERT makro ist</span>
ASSERT<span style="color: #008000;">&#40;</span>FALSE<span style="color: #008000;">&#41;</span><span style="color: #008080;">;</span></pre></div></div>

<p>Jetzt müsste man noch einen Kommentar davor setzen, damit klar wird was hier schief läuft. Man kann das Ganze aber auch einfach kombinieren und noch einen Zusatznutzen erreichen indem man den etwas unbekannteren Makro <em>_ASSERTE </em>verwendet:</p>

<div class="wp_syntax"><div class="code"><pre class="cpp" style="font-family:monospace;">_ASSERTE<span style="color: #008000;">&#40;</span> <span style="color: #000040;">!</span><span style="color: #FF0000;">&quot;MyFuncFooHandler: This is not allowed in my special Foo Handler&quot;</span> <span style="color: #008000;">&#41;</span><span style="color: #008080;">;</span></pre></div></div>

<p>Die Negation macht aus dem Zeiger auf den konstanten String <em>FALSE</em>, und damit schlägt der <em>ASSERT </em>an.<br />
Wenn man jetzt wie hier gezeigt noch den _<em>ASSERTE </em>Makro verwendet, dann wird diese Expression, also der Text, sofort mit anzeigt. Man sieht dann sofort was das Problem ist sobald der <em>ASSERT </em>Dialog angezeigt wird.</p>
<hr /><small>Copyright &copy; 2010 Martin Richter<br />Dieser Feed ist nur für den persönlichen, nicht gewerblichen Gebrauch bestimmt. Eine Verwendung dieses Feeds bzw. der hier veröffentlichten Beiträge auf anderen Webseiten bedarf der ausdrücklichen Genehmigung des Autors.<br />(Digital Fingerprint: bdafe67664ea5aacaab71f8c0a581adf)</small>]]></content:encoded>
			<wfw:commentRss>http://blog.m-ri.de/index.php/2009/06/07/wie-man-einen-permanenten-assert-direkt-mit-einem-kommentar-versieht/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>VS Tipps &amp; Tricks: Heap Bugs finden (Teil 4)</title>
		<link>http://blog.m-ri.de/index.php/2008/11/27/vs-tipps-tricks-heap-bugs-finden-teil-4/</link>
		<comments>http://blog.m-ri.de/index.php/2008/11/27/vs-tipps-tricks-heap-bugs-finden-teil-4/#comments</comments>
		<pubDate>Thu, 27 Nov 2008 18:20:38 +0000</pubDate>
		<dc:creator>Martin Richter</dc:creator>
				<category><![CDATA[C++]]></category>
		<category><![CDATA[CRT]]></category>
		<category><![CDATA[Debugging]]></category>
		<category><![CDATA[Programmieren]]></category>
		<category><![CDATA[Windows API]]></category>
		<category><![CDATA[Debuggen]]></category>
		<category><![CDATA[MFC]]></category>
		<category><![CDATA[Qualitätssicherung]]></category>
		<category><![CDATA[VS-Tipps&Tricks]]></category>
		<category><![CDATA[WinAPI]]></category>

		<guid isPermaLink="false">http://blog.m-ri.de/?p=366</guid>
		<description><![CDATA[In meine ersten Artikeln über Heap-Bugs habe ich bereits erwähnt, dass die CRT aber auch Windows selbst Speicher unter bestimmten Umständen vorbelegt bzw. beim Freigeben des Speichers mit einem festen Wert löscht. Für einen Entwickler ist es gut zu wissen welche Werte durch wen gesetzt werden. Zudem erleichtert einem dieses Wissen auch das Debuggen und [...]]]></description>
			<content:encoded><![CDATA[<p>In meine ersten Artikeln über Heap-Bugs habe ich bereits erwähnt, dass die CRT aber auch Windows selbst Speicher unter bestimmten Umständen vorbelegt bzw. beim Freigeben des Speichers mit einem festen Wert löscht.</p>
<p>Für einen Entwickler ist es gut zu wissen welche Werte durch wen gesetzt werden. Zudem erleichtert einem dieses Wissen auch das Debuggen und die Identifikation von Problemen im Zusammenhang mit dem Heap, deshalb habe ich hier mal diese Magic-Bytes, die von Microsoft verwendet werden hier zusammengetragen.</p>
<p>Würde man im Debugger zum Beispiel eine Variable mit dem Wert <strong>0xCCCCCCCC </strong>entdecken, dann ist davon auszugehen, dass man diese Variable auf dem Stack nicht initialisiert hat.</p>
<ul>
<li><strong>0xABABABAB</strong><br />
Wird von <em>HeapAlloc </em>als Wert für die Guard Bytes (&#8220;no man&#8217;s land&#8221;) vor und hinter Speicherblöcken verwendet.</li>
<li><strong>0xBAADF00D</strong><br />
Wird von <em>LocalAlloc(LMEM_FIXED) </em>verwendet um nicht nicht initialisierten Speicher im Heap zu kennzeichnen.</li>
<li><strong>0xCCCCCCCC</strong><br />
Wird von der Debug-CRT verwendet um nicht initialisierten Stack zu kennzeichnen.</li>
<li><strong>0xCDCDCDCD</strong><br />
Wird von der Debug-CRT verwendet um nicht initialisierten Speicher im Heap zu kennzeichnen.</li>
<li><strong>0xDDDDDDDD</strong><br />
Wird von der Debug-CRT verwendet um freigegebenen Speicher im Heap zu kennzeichnen.</li>
<li><strong>0xFDFDFDFD</strong><br />
Wird von vom Debug-Heap verwendet für Guard Bytes (&#8220;no man&#8217;s land&#8221;), vor und hinter Speicherblöcken.</li>
<li><strong>0xFEEEFEEE</strong><br />
Wird von <em>HeapFree() </em>verwendet um freigegebenen Speicher zu kennzeichnen.</li>
</ul>
<p>Siehe auch: <a href="http://en.wikipedia.org/wiki/Magic_number_(programming">http://en.wikipedia.org/wiki/Magic_number_(programming</a>)</p>
<hr /><small>Copyright &copy; 2010 Martin Richter<br />Dieser Feed ist nur für den persönlichen, nicht gewerblichen Gebrauch bestimmt. Eine Verwendung dieses Feeds bzw. der hier veröffentlichten Beiträge auf anderen Webseiten bedarf der ausdrücklichen Genehmigung des Autors.<br />(Digital Fingerprint: bdafe67664ea5aacaab71f8c0a581adf)</small>]]></content:encoded>
			<wfw:commentRss>http://blog.m-ri.de/index.php/2008/11/27/vs-tipps-tricks-heap-bugs-finden-teil-4/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>WinMain mit argc und argv</title>
		<link>http://blog.m-ri.de/index.php/2008/11/09/winmain-mit-argc-und-argv/</link>
		<comments>http://blog.m-ri.de/index.php/2008/11/09/winmain-mit-argc-und-argv/#comments</comments>
		<pubDate>Sun, 09 Nov 2008 18:42:09 +0000</pubDate>
		<dc:creator>Martin Richter</dc:creator>
				<category><![CDATA[C++]]></category>
		<category><![CDATA[CRT]]></category>
		<category><![CDATA[Programmieren]]></category>
		<category><![CDATA[Sonstiges]]></category>
		<category><![CDATA[Windows API]]></category>
		<category><![CDATA[WinAPI]]></category>

		<guid isPermaLink="false">http://blog.m-ri.de/?p=359</guid>
		<description><![CDATA[Mit WinMain / wWinMain / _tWinMain bekommt man einen Zeiger auf Befehlszeile frei Haus mitgeliefert als lpCmdLine. Es ist nicht schwer Code u schreiben um diese Zeile zu interpretieren. Die MFC stellt dazu eine eigene Klasse mit dem Namen CCommandLineInfo. Manchmal wäre es aber auch einfach nur schön wie bei einem simplen C/C++-Konsolenprogramm argc und [...]]]></description>
			<content:encoded><![CDATA[<p>Mit <em>WinMain / wWinMain / _tWinMain </em>bekommt man einen Zeiger auf Befehlszeile frei Haus mitgeliefert als <em>lpCmdLine</em>. Es ist nicht schwer Code u schreiben um diese Zeile zu interpretieren. Die MFC stellt dazu eine eigene Klasse mit dem Namen <a href="http://msdn.microsoft.com/en-us/library/zaydx040(VS.80).aspx">CCommandLineInfo</a>. Manchmal wäre es aber auch einfach nur schön wie bei einem simplen C/C++-Konsolenprogramm <em>argc </em>und <em>argv </em>zur Verfügung zu haben, die an <em>main / wmain / _tmain </em>übergeben werden. Leider werden die aber an die Startfunktion nicht übergeben. (Diese Frage taucht auch nicht selten in den Communities auf).</p>
<p>Versteckt in der <em>CRT </em>gibt es <em>argc </em>und <em>argv </em>aber immer, egal ob Konsolen- oder UI-Programm. Der Startup-Code der <em>CRT </em>initialisiert diese Werte immer und sie stehen als globale Variablen unter den Namen <em>__argc </em>und <em>__argv </em>bzw. <em>__argvw </em>zur Verfügung. Man muss nur einen <em>#include </em>aud <em>stdlib.h </em>machen und schon stehen diese Werte zur Verfügung.<br />
Ist das Programm ein Unicode Programm ist der Array <em>__argvw </em>initialisiert und <em>__argv </em>ist NULL. Ist das Programm ein MBCS Programm dann ist <em>__argv </em>gefüllt und <em>__argvw </em>ist NULL. Entsprechend ist <em>__targv</em> in <em>tchar.h </em>definiert. (Geändert nach Kommentar von Marcus Humann am 10.09.08)</p>
<p>Mit <em>__argc / __argv / __argvw</em> <em>/ __targv </em>kann man nun ganz leicht die Befehlszeile frei verarbeiten, wie man es gewohnt ist, auch wenn man ein Windows-GUI Programm erstellt, oder die MFC benutzt.</p>
<p>Das ist zwar nicht dokumentiert, aber seit VC6 bis zur aktuellen Version VC-20008 hat sich nichts geändert.</p>
<hr /><small>Copyright &copy; 2010 Martin Richter<br />Dieser Feed ist nur für den persönlichen, nicht gewerblichen Gebrauch bestimmt. Eine Verwendung dieses Feeds bzw. der hier veröffentlichten Beiträge auf anderen Webseiten bedarf der ausdrücklichen Genehmigung des Autors.<br />(Digital Fingerprint: bdafe67664ea5aacaab71f8c0a581adf)</small>]]></content:encoded>
			<wfw:commentRss>http://blog.m-ri.de/index.php/2008/11/09/winmain-mit-argc-und-argv/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>VS Tipps &amp; Tricks: Heap Bugs finden (Teil 3)</title>
		<link>http://blog.m-ri.de/index.php/2008/11/04/vs-tipps-tricks-heap-bugs-finden-teil-3/</link>
		<comments>http://blog.m-ri.de/index.php/2008/11/04/vs-tipps-tricks-heap-bugs-finden-teil-3/#comments</comments>
		<pubDate>Tue, 04 Nov 2008 19:30:59 +0000</pubDate>
		<dc:creator>Martin Richter</dc:creator>
				<category><![CDATA[ATL]]></category>
		<category><![CDATA[C++]]></category>
		<category><![CDATA[CRT]]></category>
		<category><![CDATA[Debugging]]></category>
		<category><![CDATA[MFC]]></category>
		<category><![CDATA[Programmieren]]></category>
		<category><![CDATA[VS-Tipps&Tricks]]></category>
		<category><![CDATA[Windows API]]></category>
		<category><![CDATA[Debuggen]]></category>
		<category><![CDATA[Qualitätssicherung]]></category>
		<category><![CDATA[WinAPI]]></category>

		<guid isPermaLink="false">http://blog.m-ri.de/?p=357</guid>
		<description><![CDATA[Mancher Bug macht einem nicht den Gefallen und lässt sich in der Debug-Version finden. Ursache ist oft genug eine Variable, die in der Debug-Version initialisiert (0xCC) wird aber in der Release-Version zu einem Crash führt, wenn zufällige Daten auf dem Stack für undefiniertes Verhalten sorgen. Also macht man sich an das debuggen der Release Version [...]]]></description>
			<content:encoded><![CDATA[<p>Mancher Bug macht einem nicht den Gefallen und lässt sich in der Debug-Version finden. Ursache ist oft genug eine Variable, die in der Debug-Version initialisiert (0xCC) wird aber in der Release-Version zu einem Crash führt, wenn zufällige Daten auf dem Stack für undefiniertes Verhalten sorgen.</p>
<p>Also macht man sich an das debuggen der Release Version und kann keinen Fehler finden.<br />
Kaum startet man das Programm ohne Debugger dann kracht es wieder. Warum?</p>
<p>Manch einer könnte jetzt denken: Der Debugger verändert das Memory Layout! Das tut er schon, aber entscheidend für ein anderes Verhalten ist der Debug Heap!<br />
Die wenigsten Entwickler wissen überhaupt, dass es ihn gibt. Ich meine hier nicht die Debug Funktionen, die die CRT zur Verfügung stellt, denn mein Thema heute ist ja das Debuggen eines Release-Programms, und die Debug-CRT hat ja bekanntlich in einem Release Programm nichts zu suchen!</p>
<p>Machen wir es praktisch und nehmen wieder mein kleines Crashtest-Programm:</p>

<div class="wp_syntax"><div class="code"><pre class="cpp" style="font-family:monospace;"><span style="color: #339900;">#include &lt;windows.h&gt;</span>
<span style="color: #339900;">#include &lt;tchar.h&gt;</span>
<span style="color: #339900;">#include &lt;crtdbg.h&gt;</span>
<span style="color: #0000ff;">int</span> _tmain<span style="color: #008000;">&#40;</span><span style="color: #0000ff;">int</span> argc, _TCHAR<span style="color: #000040;">*</span> argv<span style="color: #008000;">&#91;</span><span style="color: #008000;">&#93;</span><span style="color: #008000;">&#41;</span>
<span style="color: #008000;">&#123;</span>
  <span style="color: #0000ff;">char</span> <span style="color: #000040;">*</span>pCorrupt <span style="color: #000080;">=</span> <span style="color: #0000dd;">new</span> <span style="color: #0000ff;">char</span><span style="color: #008000;">&#91;</span><span style="color: #0000dd;">100</span><span style="color: #008000;">&#93;</span><span style="color: #008080;">;</span>
  ZeroMemory<span style="color: #008000;">&#40;</span>pCorrupt,<span style="color: #0000dd;">104</span><span style="color: #008000;">&#41;</span><span style="color: #008080;">;</span>
  <span style="color: #0000ff;">char</span> <span style="color: #000040;">*</span>pOther <span style="color: #000080;">=</span> <span style="color: #0000dd;">new</span> <span style="color: #0000ff;">char</span><span style="color: #008000;">&#91;</span><span style="color: #0000dd;">100</span><span style="color: #008000;">&#93;</span><span style="color: #008080;">;</span>
  ZeroMemory<span style="color: #008000;">&#40;</span>pOther,<span style="color: #0000dd;">100</span><span style="color: #008000;">&#41;</span><span style="color: #008080;">;</span>
  <span style="color: #0000dd;">delete</span> <span style="color: #008000;">&#91;</span><span style="color: #008000;">&#93;</span> pOther<span style="color: #008080;">;</span>
  <span style="color: #0000dd;">delete</span> <span style="color: #008000;">&#91;</span><span style="color: #008000;">&#93;</span> pCorrupt<span style="color: #008080;">;</span>
  <span style="color: #0000ff;">return</span> <span style="color: #0000dd;">0</span><span style="color: #008080;">;</span>
<span style="color: #008000;">&#125;</span></pre></div></div>

<p>Wenn wir dieses Programm als Release Version kompilieren und ausführen, dann erhalten wir keine Fehlermeldung <img src='http://blog.m-ri.de/wp-includes/images/smilies/icon_exclaim.gif' alt=':!:' class='wp-smiley' />  Interessant. Der Heap ist nicht soweit zerstört, dass es zu einer Zugriffsverletzung kommt. Starten wir aber unser Programm mit dem Debugger, dann wird der so genannte Debug Heap des Systems verwendet, der wie die Debug-CRT Guardbytes setzt und kontrolliert.</p>
<p>Ein weiteres Problem entsteht dadurch, dass der Debug Heap den allokierten Speicher auf feste Werte initialisiert genau wie die Debugversion der CRT. Wenn also nicht initialisierter Speicher genutzt wird, dann ist das Verhalten mit dem Debug-Heap deterministisch, ohne Debug Heap eher zufällig.</p>
<p>Das im Debugger alles etwas anders sein kann ist sogar <a href="http://msdn.microsoft.com/en-us/library/cc266414.aspx">dokumentiert</a> <img src='http://blog.m-ri.de/wp-includes/images/smilies/icon_wink.gif' alt=';)' class='wp-smiley' /> </p>
<blockquote><p>Processes that the debugger creates (also known as spawned processes) behave slightly differently than processes that the debugger does not create.<br />
Instead of using the standard heap API, processes that the debugger creates use a special debug heap. On Microsoft Windows XP and later versions of Windows, you can force a spawned process to use the standard heap instead of the debug heap by using the _NO_DEBUG_HEAP environment variable or the -hd command-line option.</p></blockquote>
<p>In diesem Text steht auch, wie man den Debug-Heap ausschalten kann, mit:</p>

<div class="wp_syntax"><div class="code"><pre class="bat" style="font-family:monospace;">SETX _NO_DEBUG_HEAP 1</pre></div></div>

<p>Diese Environment-Variable sorgt dafür, dass sich auch bei geladenem Debugger, das Programm so verhält wie ohne Debugger (hoffentlich). Führt man mein Testprogramm nun im Debugger aus, wenn die Environment-Variable <em>_NO_DEBUG_HEAP </em>auf 1 gesetzt ist, erhält man keinen Debug-Break mehr. Denn in diesem Fall gibt es keine Guardbytes, die geprüft werden.<br />
Löscht man den Eintrag <em>_NO_DEBUG_HEAP </em>wieder, dann erhält man im Debugger wieder wie erwartet einen Break.</p>
<p>Will man also wirklich realitätsnah eine Release-Version debuggen, dann kommt man um das Ausschalten des Debug-Heaps nicht herum.</p>
<p>PS: Man kann es auch etwas einfacher haben, wenn man sich nachträglich an den Prozess mit dem Debugger attached (wenn das geht). Ideal ist dieses Verfahren auch beim Remote-Debugging (dazu demnächst mehr).</p>
<hr /><small>Copyright &copy; 2010 Martin Richter<br />Dieser Feed ist nur für den persönlichen, nicht gewerblichen Gebrauch bestimmt. Eine Verwendung dieses Feeds bzw. der hier veröffentlichten Beiträge auf anderen Webseiten bedarf der ausdrücklichen Genehmigung des Autors.<br />(Digital Fingerprint: bdafe67664ea5aacaab71f8c0a581adf)</small>]]></content:encoded>
			<wfw:commentRss>http://blog.m-ri.de/index.php/2008/11/04/vs-tipps-tricks-heap-bugs-finden-teil-3/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>VS Tipps &amp; Tricks: Heap Bugs finden (Teil 2)</title>
		<link>http://blog.m-ri.de/index.php/2008/10/31/vs-tipps-tricks-heap-bugs-finden-teil-2/</link>
		<comments>http://blog.m-ri.de/index.php/2008/10/31/vs-tipps-tricks-heap-bugs-finden-teil-2/#comments</comments>
		<pubDate>Fri, 31 Oct 2008 18:42:52 +0000</pubDate>
		<dc:creator>Martin Richter</dc:creator>
				<category><![CDATA[ATL]]></category>
		<category><![CDATA[C++]]></category>
		<category><![CDATA[CRT]]></category>
		<category><![CDATA[Debugging]]></category>
		<category><![CDATA[IDE]]></category>
		<category><![CDATA[MFC]]></category>
		<category><![CDATA[Programmieren]]></category>
		<category><![CDATA[VS-Tipps&Tricks]]></category>
		<category><![CDATA[Windows API]]></category>
		<category><![CDATA[Debuggen]]></category>
		<category><![CDATA[Qualitätssicherung]]></category>
		<category><![CDATA[WinAPI]]></category>

		<guid isPermaLink="false">http://blog.m-ri.de/?p=355</guid>
		<description><![CDATA[Einige Hilfsmittel um einen Heap-Fehler zu finden habe ich in meinem letzten Beitrag ja beschrieben. Eigentlich wünscht sich der Entwickler nichts mehr, als dass ein falscher Zugriff auf den Heap, sofort einen Break im Debugger auslöst. Die Methoden, die ich bisher gezeigt habe (AfxCheckMemory, _CrtCheckMemory, _CrtSetDbgFlag) können das nicht direkt , aber zumindest helfen sie den [...]]]></description>
			<content:encoded><![CDATA[<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>
<p>Eigentlich wünscht sich der Entwickler nichts mehr, als dass ein falscher Zugriff auf den Heap, sofort einen <em>Break </em>im Debugger auslöst. Die Methoden, die ich bisher gezeigt habe (<em>AfxCheckMemory</em>, <em>_CrtCheckMemory</em>, <em>_CrtSetDbgFlag</em>) können das nicht direkt , aber zumindest helfen sie den Fehler einzukreisen.</p>
<p>Ein unverzichtbarer Helfer, der sofort solch einen <em>Break </em>auslösen kann, ist der <a href="http://msdn.microsoft.com/de-de/library/ms220948(VS.80).aspx">Application Verifier</a>, den ich bereits in einem älteren 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>
<p>Seit <em>Visual Studio 2005 </em>kann man direkt Parameter für 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 />
An den Standardeinstellungen im Projekt braucht man hier gar nichts zu ändern:<br />
<em>Conserve Memory </em>- No<br />
<em>Protection Location </em>- Je nach Testfall (man sollte mit beiden Einstellungen mal debuggen)<br />
Alle anderen Einstellungen <em>Verification Layers Settings </em>- auf Enable</p>
<p>Mit dem <em>Application Verifier </em>lässt 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ält sofort eine Access Violation, wenn man den Speicherbereich überschreitet.</p>
<p>Mein kleines Demoproramm</p>

<div class="wp_syntax"><table><tr><td class="line_numbers"><pre>1
2
3
4
5
6
7
8
9
10
11
12
13
</pre></td><td class="code"><pre class="cpp" style="font-family:monospace;"><span style="color: #339900;">#include &lt;windows.h&gt;</span>
<span style="color: #339900;">#include &lt;tchar.h&gt;</span>
<span style="color: #339900;">#include &lt;crtdbg.h&gt;</span>
<span style="color: #0000ff;">int</span> _tmain<span style="color: #008000;">&#40;</span><span style="color: #0000ff;">int</span> argc, _TCHAR<span style="color: #000040;">*</span> argv<span style="color: #008000;">&#91;</span><span style="color: #008000;">&#93;</span><span style="color: #008000;">&#41;</span>
<span style="color: #008000;">&#123;</span>
  <span style="color: #0000ff;">char</span> <span style="color: #000040;">*</span>pCorrupt <span style="color: #000080;">=</span> <span style="color: #0000dd;">new</span> <span style="color: #0000ff;">char</span><span style="color: #008000;">&#91;</span><span style="color: #0000dd;">100</span><span style="color: #008000;">&#93;</span><span style="color: #008080;">;</span>
  ZeroMemory<span style="color: #008000;">&#40;</span>pCorrupt,<span style="color: #0000dd;">106</span><span style="color: #008000;">&#41;</span><span style="color: #008080;">;</span> <span style="color: #666666;">// -- This will corrupt the heap</span>
  <span style="color: #0000ff;">char</span> <span style="color: #000040;">*</span>pOther <span style="color: #000080;">=</span> <span style="color: #0000dd;">new</span> <span style="color: #0000ff;">char</span><span style="color: #008000;">&#91;</span><span style="color: #0000dd;">100</span><span style="color: #008000;">&#93;</span><span style="color: #008080;">;</span>
  ZeroMemory<span style="color: #008000;">&#40;</span>pOther,<span style="color: #0000dd;">100</span><span style="color: #008000;">&#41;</span><span style="color: #008080;">;</span>
  <span style="color: #0000dd;">delete</span> <span style="color: #008000;">&#91;</span><span style="color: #008000;">&#93;</span> pOther<span style="color: #008080;">;</span>
  <span style="color: #0000dd;">delete</span> <span style="color: #008000;">&#91;</span><span style="color: #008000;">&#93;</span> pCorrupt<span style="color: #008080;">;</span>
  <span style="color: #0000ff;">return</span> <span style="color: #0000dd;">0</span><span style="color: #008080;">;</span>
<span style="color: #008000;">&#125;</span></pre></td></tr></table></div>

<p>crashed mit der Nutzung des <em>Application Verifiers </em>sofort und man kann im Call Stack die Zeile 7 ausmachen.<br />
Genial 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ückgreifen kann, ist der Application Verifier ein super Hilfsmittel.</p>
<p>Der Nachteil: Die Guard Pages liegen nicht exakt und direkt hinter dem allokierten Bereich, sondern auf der nächsten Page Boundary. Deshalb crashed mein Sample auch nicht wenn man den Speicher um nur 1 Byte überschreitet.</p>
<p>Aber der Application Verifier ist zum Testen ein absolutes Muss, weil auch falsche Handles erkannt werden und auch der Lock Verfification Layer für die Qualitätssicherung einfach nützlich zum entwanzen sind. (siehe auch <a href="http://msdn.microsoft.com/en-us/library/ms220936.aspx">Application Verifier Einstellungen in der MSDN</a>).</p>
<p>Hinweis <img src='http://blog.m-ri.de/wp-includes/images/smilies/icon_exclaim.gif' alt=':!:' class='wp-smiley' /> </p>
<p>Auf <em>Windows XP </em>und <em>Windows Server 2003 </em>erhält man ohne administrative Rechte die folgende Fehlermeldung:</p>
<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>
<p>Unter Windows Vista oder Windows Server 2008 erhält man die flogende Fehlermeldung wenn der Application Verifier nicht elevated gestartet wird:</p>
<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>
<p>Durch einen simplen Eintrag in der Registry lässt 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 />
<em>HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\Session Manger\ImageExecutionOptions<br />
</em>Nach einem Reboot kann man nun einfach den <em>Application Verifier </em>auch non-elevated, als normaler Benutzer nutzen.</p>
<hr /><small>Copyright &copy; 2010 Martin Richter<br />Dieser Feed ist nur für den persönlichen, nicht gewerblichen Gebrauch bestimmt. Eine Verwendung dieses Feeds bzw. der hier veröffentlichten Beiträge auf anderen Webseiten bedarf der ausdrücklichen Genehmigung des Autors.<br />(Digital Fingerprint: bdafe67664ea5aacaab71f8c0a581adf)</small>]]></content:encoded>
			<wfw:commentRss>http://blog.m-ri.de/index.php/2008/10/31/vs-tipps-tricks-heap-bugs-finden-teil-2/feed/</wfw:commentRss>
		<slash:comments>4</slash:comments>
		</item>
	</channel>
</rss>

