<?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>Caloni.com.br &#187; C++</title>
	<atom:link href="http://www.caloni.com.br/blog/archives/category/c/feed" rel="self" type="application/rss+xml" />
	<link>http://www.caloni.com.br/blog</link>
	<description>C++, Windows, Programação, Depuração e Transpiração</description>
	<lastBuildDate>Wed, 11 Jan 2012 13:22:39 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.3</generator>
		<item>
		<title>RValue é o novo LValue</title>
		<link>http://www.caloni.com.br/blog/archives/rvalue-e-o-novo-lvalue</link>
		<comments>http://www.caloni.com.br/blog/archives/rvalue-e-o-novo-lvalue#comments</comments>
		<pubDate>Wed, 11 Jan 2012 12:51:05 +0000</pubDate>
		<dc:creator>Wanderley Caloni</dc:creator>
				<category><![CDATA[Blogging]]></category>
		<category><![CDATA[C++]]></category>
		<category><![CDATA[c++11]]></category>
		<category><![CDATA[discussões]]></category>
		<category><![CDATA[eventos]]></category>

		<guid isPermaLink="false">http://www.caloni.com.br/blog/?p=1244</guid>
		<description><![CDATA[
As grandes discussões filosóficas que participei durante meu estudo da linguagem C, e mais tarde de C++, muitas vezes convergiam para o significado místico daquela figura que nós da gramática da linguagem conhecemos como lvalue, ou l-value, ou left-value. Enfim, a definição de uma expressão que  [...]]]></description>
			<content:encoded><![CDATA[<p><a href="http://www.caloni.com.br/blog/wp-content/uploads/The-C-Programming-Language.jpg"><img class="aligncenter size-full wp-image-1205" title="The-C-Programming-Language" src="http://www.caloni.com.br/blog/wp-content/uploads/The-C-Programming-Language.jpg" alt="" width="255" height="346" /></a></p>
<p>As grandes discussões filosóficas que participei durante meu estudo da linguagem C, e mais tarde de C++, muitas vezes convergiam para o significado místico daquela figura que nós da gramática da linguagem conhecemos como lvalue, ou l-value, ou left-value. Enfim, a definição de uma expressão que representa um lugar na memória e, portanto, pode ocupar o lado esquerdo de uma atribuição/cópia/passagem de argumentos qualquer. Porém, os "grandes" embates daquela época hoje parecem brincadeira de criança, como a diferença sutil entre ++x e x++ ou convergência de tipos em templates.</p>
<p>Agora o buraco é mais embaixo. Agora temos referências r-value.</p>
<p>Agora o mundo mudou.</p>
<p>Foi necessário que mudasse. C++, conhecido internacionalmente como a vanguarda das linguagens, mesmo mantendo sua fama de alta performance, precisava voltar às suas origens performáticas de qualquer forma. O Criador da linguagem e seus seguidores estavam cientes: cópia de strings é uma coisa muito, muito má. Imperfect forwarding (direcionamento imperfeito?) é algo ainda pior, pois é mais sutil.</p>
<p>Todos concordam, então, que a mudança é necessária. Nem todos concordam, contudo, com o preço a ser pago. As coisas começam a ficar cada vez mais difíceis de entender, e agora, com r-values vindo à superfície, o universo de criaturas bizarras volta a mostrar as caras.</p>
<p>Desde o começo de meus estudos em C++ tenho admirado a linguagem com um certo distanciamento. Enquanto a linguagem C continua sendo o supra-sumo das linguagens de médio-nível, C++ continua sendo uma abominação cujos detalhes muitos preferem esquecer. Mas esquecer tem se tornado cada vez mais difícil frente às <del>gambiarras</del> adaptações técnicas que a linguagem vem sofrendo.</p>
<p>No caso de Rvalues, se antes existia uma discussão interminável sobre sua inclusão no novo padrão, agora existem discussões acerca do que tudo isso significa. Existe até um <a href="http://thbecker.net/articles/rvalue_references/section_01.html">ótimo guia</a> (thanks to <a href="https://twitter.com/#!/pepper_chico">pepper_chico</a>) sobre as principais mudanças de conceitos, feito para simplificar o entendimento. Mas ele mesmo é exageradamente complexo para o programador médio. É de forçar a barra, mesmo. É pedir demais.</p>
<h4>Conversemos</h4>
<p>No próximo dia 28, sábado, nos reuniremos em mais um <a href="https://msevents.microsoft.com/CUI/EventDetail.aspx?EventID=1032503387&amp;Culture=pt-BR">evento C++ organizado </a><del><a href="https://msevents.microsoft.com/CUI/EventDetail.aspx?EventID=1032503387&amp;Culture=pt-BR">pela Microsoft</a></del> <a href="https://msevents.microsoft.com/CUI/EventDetail.aspx?EventID=1032503387&amp;Culture=pt-BR">pelo Grupo C/C++ Brasil</a> e pelos agora dois MVPs do Brasil, o veterano Fabio Galuppo e o novato Rodrigo Strauss (meu amigo, mas acima de tudo muito bem-vindo ao cargo). Estou na lista de palestrantes e conversarei com vocês sobre as otimizações que o famigerado RValue deve trazer à mesa. Espero conseguir entender um pouco mais sobre essa criatura fantástica até lá.</p>
<p>Se o Cebolinha for um programador C++, deve estar se debatendo nesse momento.</p>
<h4>Linques úteis</h4>
<ul>
<li><a href="http://thbecker.net/articles/rvalue_references/section_01.html">C++ Rvalue References Explained</a></li>
<li><a href="http://www.artima.com/cppsource/rvalue.html">A Brief Introduction to Rvalue References</a></li>
<li><a href="http://cpp-next.com/archive/2009/08/want-speed-pass-by-value/">Want Speed? Pass by Value</a></li>
<li><a href="https://msevents.microsoft.com/CUI/EventDetail.aspx?EventID=1032503387&amp;Culture=pt-BR">MSDN Community: C++ Renaissance, São Paulo - SP</a>. <strong>Faça sua incrição!</strong></li>
</ul>
]]></content:encoded>
			<wfw:commentRss>http://www.caloni.com.br/blog/archives/rvalue-e-o-novo-lvalue/feed</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>Cuidado com variáveis temporárias</title>
		<link>http://www.caloni.com.br/blog/archives/cuidado-com-variaveis-temporarias</link>
		<comments>http://www.caloni.com.br/blog/archives/cuidado-com-variaveis-temporarias#comments</comments>
		<pubDate>Tue, 26 Jul 2011 02:05:14 +0000</pubDate>
		<dc:creator>Wanderley Caloni</dc:creator>
				<category><![CDATA[C++]]></category>
		<category><![CDATA[tips-and-tricks]]></category>

		<guid isPermaLink="false">http://www.caloni.com.br/blog/?p=1131</guid>
		<description><![CDATA[

Um dos problemas que a linguagem C++ possui para seus iniciantes é o de não deixar muito explícito partes do seu comportamento, principalmente as partes que lidam com ponteiros/referências e o jogo da vida dos objetos. Às  vezes a coisa fica de tal como complexa que fica até difícil explicar o  [...]]]></description>
			<content:encoded><![CDATA[

<p>Um dos problemas que a linguagem C++ possui para seus iniciantes é o de não deixar muito explícito partes do seu comportamento, principalmente as partes que lidam com ponteiros/referências e o jogo da vida dos objetos. Às  vezes a coisa fica de tal como complexa que fica até difícil explicar o porquê das coisas.</p>
<p>Por exemplo, vejamos o singelo caso de alguém que precisa formatar uma saída de erro e para isso escolheu um stringstream:</p>
<p><pre><span style="color: #006600;">#include &lt;sstream&gt;</span>
<span style="color: #006600;">#include &lt;exception&gt;</span>
<span style="color: #006600;">#include &lt;iostream&gt;</span>
&nbsp;
<span style="color: #0000ff;">using</span> <span style="color: #0000ff;">namespace</span> std;
&nbsp;
<span style="color: #0000ff;">void</span> LogError<span style="color: #000000; font-weight: bold;">&#40;</span><span style="color: #0000ff;">const</span> <span style="color: #0000ff;">char</span>* msg<span style="color: #000000; font-weight: bold;">&#41;</span>
<span style="color: #000000; font-weight: bold;">&#123;</span>
    <span style="color: #0000ff;">cerr</span> &lt;&lt; <span style="color: #666666;">"** "</span> &lt;&lt; msg &lt;&lt; endl;
<span style="color: #000000; font-weight: bold;">&#125;</span>
&nbsp;
&nbsp;
<span style="color: #0000ff;">void</span> func<span style="color: #000000; font-weight: bold;">&#40;</span><span style="color: #000000; font-weight: bold;">&#41;</span>
<span style="color: #000000; font-weight: bold;">&#123;</span>
    <span style="color: #006600;">//doSomething();</span>
    throw exception<span style="color: #000000; font-weight: bold;">&#40;</span><span style="color: #666666;">"sbrubles exception"</span><span style="color: #000000; font-weight: bold;">&#41;</span>;
<span style="color: #000000; font-weight: bold;">&#125;</span>
&nbsp;
&nbsp;
<span style="color: #0000ff;">int</span> main<span style="color: #000000; font-weight: bold;">&#40;</span><span style="color: #000000; font-weight: bold;">&#41;</span>
<span style="color: #000000; font-weight: bold;">&#123;</span>
    <span style="color: #0000ff;">try</span>
    <span style="color: #000000; font-weight: bold;">&#123;</span>
        func<span style="color: #000000; font-weight: bold;">&#40;</span><span style="color: #000000; font-weight: bold;">&#41;</span>;
    <span style="color: #000000; font-weight: bold;">&#125;</span>
    <span style="color: #0000ff;">catch</span><span style="color: #000000; font-weight: bold;">&#40;</span>exception&amp; e<span style="color: #000000; font-weight: bold;">&#41;</span>
    <span style="color: #000000; font-weight: bold;">&#123;</span>
        stringstream ss;
        ss &lt;&lt; <span style="color: #666666;">"Error calling func: "</span> &lt;&lt; e.<span style="color: #000000;">what</span><span style="color: #000000; font-weight: bold;">&#40;</span><span style="color: #000000; font-weight: bold;">&#41;</span> &lt;&lt; endl;
        <span style="color: #0000ff;">const</span> <span style="color: #0000ff;">char</span>* errorMessage = ss.<span style="color: #000000;">str</span><span style="color: #000000; font-weight: bold;">&#40;</span><span style="color: #000000; font-weight: bold;">&#41;</span>.<span style="color: #000000;">c_str</span><span style="color: #000000; font-weight: bold;">&#40;</span><span style="color: #000000; font-weight: bold;">&#41;</span>;
        LogError<span style="color: #000000; font-weight: bold;">&#40;</span>errorMessage<span style="color: #000000; font-weight: bold;">&#41;</span>;
    <span style="color: #000000; font-weight: bold;">&#125;</span>
<span style="color: #000000; font-weight: bold;">&#125;</span></pre></p>
<p>Quando chamamos func, ele lança uma exceção que é capturada no main que, por sua vez, formata uma stream e obtém sua string (através do método str) e através dessa string obtém o ponteiro da string em C puro (através do método c_str). Porém, a mensagem resultante na saída-padrão de erro não era o esperado:</p>
<p><a href="http://www.caloni.com.br/blog/wp-content/uploads/ExceptionSStreamConsoleOutput.png"><img class="aligncenter size-full wp-image-1133" title="ExceptionSStreamConsoleOutput" src="http://www.caloni.com.br/blog/wp-content/uploads/ExceptionSStreamConsoleOutput.png" alt="" width="677" height="342" /></a></p>
<p>Depurando diretamente, vemos que a stream, de fato, contém o que esperávamos. O único elemento errante é justamente o ponteiro obtido através da chamada dupla de métodos.</p>
<p><a href="http://www.caloni.com.br/blog/wp-content/uploads/ExceptionSStreamDebugWatch.png"><img class="aligncenter size-full wp-image-1134" title="ExceptionSStreamDebugWatch" src="http://www.caloni.com.br/blog/wp-content/uploads/ExceptionSStreamDebugWatch.png" alt="" width="791" height="403" /></a></p>
<p>O porquê isso ocorre só fica óbvio quando vemos <a title="Ajuda da função stringstream::str" href="http://www.cplusplus.com/reference/iostream/stringstream/str/">a ajuda</a> (ou a assinatura) da função str da classe stringstream:</p>
<blockquote>
<pre><strong><span style="color: #ff0000;">string str ( ) const;</span></strong>
<strong>void str ( const string &amp; s );</strong>

<strong>Get/set the associated string object</strong></pre>
<pre><strong>The first version <span style="text-decoration: underline; color: #ff0000;">returns a copy of the string object</span> currently associated with the string stream buffer.</strong></pre>
</blockquote>
<p>Ora, a função str retorna uma <strong>cópia</strong> do objeto string usado internamento pelo buffer de nossa string stream. Duas coisas ocorrem em qualquer cópia de um objeto retornada por uma função:</p>
<ul>
<li>A cópia do objeto original e seu desacoplamento (óbvio).</li>
<li>A construção de um objeto baseado no original e que, após o fim da expressão onde foi chamado o método, <strong>é destruído</strong>.</li>
</ul>
<p>Uma vez que a chamada a str termina, é entregue uma instância de uma string que contém a string original que está sendo usada pela string stream para a expressão da chamada, que geralmente vem seguida de uma cópia:</p>
<pre>//
// 1. str retorna uma cópia;
// 2. atribuição copia retorno para buf.
//
string buf = ss.str();</pre>
<pre></pre>
<p>A variável buf no exemplo acima será, portanto, a terceira string usada aqui até então. Ao final da expressão, a string intermediária retornada por str é automaticamente destruída, por se trata de uma cópia temporária para obedecer a sintaxe de retorno da função.</p>
<p>Agora, o que acontece se, <strong>na cópia temporária</strong>, é feita uma operação para obter seu ponteiro interno usado para armazenar sua string estilo C?</p>
<p>Obviamente ele fica inválido após o fim da expressão!</p>
<p>Vamos ver em câmera lenta:</p>
<p><a href="http://www.caloni.com.br/blog/wp-content/uploads/ExceptionSStreamDebugWatch2.png"><img class="aligncenter size-full wp-image-1135" title="ExceptionSStreamDebugWatch2" src="http://www.caloni.com.br/blog/wp-content/uploads/ExceptionSStreamDebugWatch2.png" alt="" width="798" height="391" /></a></p>
<p>Nada como assembly fresquinho para refrescar os conceitos de C++ por baixo dos panos.</p>
<h3>Update</h3>
<p>Após uma enxurrada de programadores gerenciáveis perguntarem qual seria, então, a solução ideal, segue o snipet mais explicitado:</p>
<pre>// 1. Copie a string retornada para uma variável não-temporária
string buf = message.str();

// 2. Use essa string dentro de seu escopo válido (até o final do catch, no exemplo do artigo).
const char* text = buf.c_str();</pre>
<h3>Update 2</h3>
<p>Outro leitor sugeriu fazer toda a chamada em uma única instrução, economizando em expressividade e ainda evitando a destruição da variável temporária criada ao chamar str.</p>
<pre>// 1. Matar três coelhos com uma instrução só.
LogError(ss.str().c_str());</pre>
<p>Particularmente, gosto de instruções simples que me permitam ver claramente o que está acontecendo de forma simples pelo depurador (até porque sei que o compilador irá otimizar tudo no final em versão Release, ainda mais se estiver quebrado em instruções simples). Porém, toda solução que evita o uso da variável temporária após a execução do método str é válida.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.caloni.com.br/blog/archives/cuidado-com-variaveis-temporarias/feed</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>Sem reflection</title>
		<link>http://www.caloni.com.br/blog/archives/sem-reflection</link>
		<comments>http://www.caloni.com.br/blog/archives/sem-reflection#comments</comments>
		<pubDate>Wed, 18 May 2011 02:00:47 +0000</pubDate>
		<dc:creator>Wanderley Caloni</dc:creator>
				<category><![CDATA[C++]]></category>
		<category><![CDATA[reflection]]></category>

		<guid isPermaLink="false">http://www.caloni.com.br/blog/?p=1076</guid>
		<description><![CDATA[





Em C++ não temos (ainda) a possibilidade de listarmos, por exemplo, a lista de métodos de um determinado tipo, a fim de chamá-lo pelo nome em tempo de execução. Algo assim:
class MyClass
&#123;
public:
        void Method1&#40;&#41;;
        void Method2&#40;&#41;;
        void Method3&#40;&#41;;
&#125;;
&#160;
&#160;
int main&#40;&#41;
&#123;
         [...]]]></description>
			<content:encoded><![CDATA[





<p>Em C++ não temos (ainda) a possibilidade de listarmos, por exemplo, a lista de métodos de um determinado tipo, a fim de chamá-lo pelo nome em tempo de execução. Algo assim:</p>
<p><pre>class MyClass
<span style="color: #000000; font-weight: bold;">&#123;</span>
<span style="color: #0000ff;">public</span>:
        <span style="color: #0000ff;">void</span> Method1<span style="color: #000000; font-weight: bold;">&#40;</span><span style="color: #000000; font-weight: bold;">&#41;</span>;
        <span style="color: #0000ff;">void</span> Method2<span style="color: #000000; font-weight: bold;">&#40;</span><span style="color: #000000; font-weight: bold;">&#41;</span>;
        <span style="color: #0000ff;">void</span> Method3<span style="color: #000000; font-weight: bold;">&#40;</span><span style="color: #000000; font-weight: bold;">&#41;</span>;
<span style="color: #000000; font-weight: bold;">&#125;</span>;
&nbsp;
&nbsp;
<span style="color: #0000ff;">int</span> main<span style="color: #000000; font-weight: bold;">&#40;</span><span style="color: #000000; font-weight: bold;">&#41;</span>
<span style="color: #000000; font-weight: bold;">&#123;</span>
        MyClass c;
        <span style="color: #0000ff;">if</span><span style="color: #000000; font-weight: bold;">&#40;</span> <span style="color: #0000ff;">auto</span> m = <span style="color: #0000ff;">typeid</span><span style="color: #000000; font-weight: bold;">&#40;</span>c<span style="color: #000000; font-weight: bold;">&#41;</span>.<span style="color: #000000;">methods</span>.<span style="color: #000000;">getaddresof</span><span style="color: #000000; font-weight: bold;">&#40;</span><span style="color: #666666;">"Method1"</span><span style="color: #000000; font-weight: bold;">&#41;</span> <span style="color: #000000; font-weight: bold;">&#41;</span>
                m<span style="color: #000000; font-weight: bold;">&#40;</span><span style="color: #000000; font-weight: bold;">&#41;</span>;
<span style="color: #000000; font-weight: bold;">&#125;</span></pre></p>
<p>OK, foi apenas um exemplo tosco de como seria um reflection em C++.</p>
<p>Porém, existem algumas maneiras de contornar esse problema. A solução, é claro, depende de qual problema você está tentando resolver.</p>
<p>Vamos supor, por exemplo, que você queira cadastrar funções para serem chamadas de maneira uniforme pelo prompt de comando. Vamos chamar nossa classe tratadora de CommandPrompt.</p>
<p><pre><span style="color: #0000ff;">typedef</span> <span style="color: #0000ff;">void</span> <span style="color: #000000; font-weight: bold;">&#40;</span>Method*<span style="color: #000000; font-weight: bold;">&#41;</span><span style="color: #000000; font-weight: bold;">&#40;</span>vector&lt;string&gt;&amp; args<span style="color: #000000; font-weight: bold;">&#41;</span>;
&nbsp;
class CommandPrompt
<span style="color: #000000; font-weight: bold;">&#123;</span>
<span style="color: #0000ff;">public</span>:
        <span style="color: #0000ff;">void</span> Add<span style="color: #000000; font-weight: bold;">&#40;</span>string name, Method m<span style="color: #000000; font-weight: bold;">&#41;</span>; <span style="color: #006600;">// adiciona novo m&eacute;todo</span>
        <span style="color: #0000ff;">void</span> Interact<span style="color: #000000; font-weight: bold;">&#40;</span>ostream&amp; os, istream&amp; is<span style="color: #000000; font-weight: bold;">&#41;</span>; <span style="color: #006600;">// come&ccedil;a intera&ccedil;&atilde;o com usu&aacute;rio</span>
<span style="color: #000000; font-weight: bold;">&#125;</span>;</pre></p>
<p>Internamente, para armazenar as funções de acordo com o nome dado, basta criarmos um mapeamento entre esses dois tipos e fazemos a amarração necessária para o método principal de parseamento:</p>
<p><pre><span style="color: #0000ff;">typedef</span> map&lt;string, Method&gt; MethodList; <span style="color: #006600;">// uma vari&aacute;vel desse tipo armazena todas as fun&ccedil;&otilde;es</span>
&nbsp;
<span style="color: #0000ff;">void</span> CommandPrompt::<span style="color: #000000;">Interact</span><span style="color: #000000; font-weight: bold;">&#40;</span>ostream&amp; os, istream&amp; is<span style="color: #000000; font-weight: bold;">&#41;</span>
<span style="color: #000000; font-weight: bold;">&#123;</span>
        <span style="color: #0000ff;">while</span><span style="color: #000000; font-weight: bold;">&#40;</span> is <span style="color: #000000; font-weight: bold;">&#41;</span>
        <span style="color: #000000; font-weight: bold;">&#123;</span>
                string func;
                vector&lt;string&gt; args;
&nbsp;
                <span style="color: #0000ff;">if</span><span style="color: #000000; font-weight: bold;">&#40;</span> ParseLine<span style="color: #000000; font-weight: bold;">&#40;</span>is, func, args<span style="color: #000000; font-weight: bold;">&#41;</span> <span style="color: #000000; font-weight: bold;">&#41;</span>
                <span style="color: #000000; font-weight: bold;">&#123;</span>
                        <span style="color: #006600;">// se a fun&ccedil;&atilde;o desejada est&aacute; em nossa lista,</span>
                        <span style="color: #006600;">// podemos cham&aacute;-la, mesmo sem conhecer qual &eacute;</span>
                        <span style="color: #0000ff;">if</span><span style="color: #000000; font-weight: bold;">&#40;</span> Method m = m_funcs<span style="color: #000000; font-weight: bold;">&#91;</span>func<span style="color: #000000; font-weight: bold;">&#93;</span> <span style="color: #000000; font-weight: bold;">&#41;</span>
                                m<span style="color: #000000; font-weight: bold;">&#40;</span>args<span style="color: #000000; font-weight: bold;">&#41;</span>;
                <span style="color: #000000; font-weight: bold;">&#125;</span>
        <span style="color: #000000; font-weight: bold;">&#125;</span>
<span style="color: #000000; font-weight: bold;">&#125;</span></pre></p>
<p>Essa solução não é exatamente um reflection, mas apenas parte do que o verdadeiro reflection possibilita. Existem outras funcionalidades, como traits, que a STL já consegue se virar razoavelmente bem, por exemplo.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.caloni.com.br/blog/archives/sem-reflection/feed</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>VTable</title>
		<link>http://www.caloni.com.br/blog/archives/vtable</link>
		<comments>http://www.caloni.com.br/blog/archives/vtable#comments</comments>
		<pubDate>Tue, 01 Mar 2011 23:47:38 +0000</pubDate>
		<dc:creator>Wanderley Caloni</dc:creator>
				<category><![CDATA[C++]]></category>

		<guid isPermaLink="false">http://www.caloni.com.br/blog/archives/vtable</guid>
		<description><![CDATA[

Acho que na breve história desse blogue nunca contei a história do vtable. No máximo fizemos um hookzinho nos métodos de um componente COM. Mas só.
Não encontro uma analogia simples, assim, de cabeça. Então vou contar no cru, mesmo. Talvez seja até mais divertido.
A vtable foi um mecanismo criado  [...]]]></description>
			<content:encoded><![CDATA[

<p>Acho que na breve história desse blogue nunca contei a história do vtable. No máximo fizemos um <a href="http://www.caloni.com.br/blog/archives/hook-de-com-no-windbg">hookzinho nos métodos de um componente COM</a>. Mas só.</p>
<p>Não encontro uma analogia simples, assim, de cabeça. Então vou contar no cru, mesmo. Talvez seja até mais divertido.</p>
<p>A vtable foi um mecanismo criado para implementar o polimorfismo em C++ quando falamos de ponteiros para classes base cujos métodos virtuais foram sobrescritos por uma classe derivada.</p>
<p>A coisa fica mais simples quando explicamos que em C++ você só paga pelo que usa. Se você declarar uma classe que não tenha nenhum método virtual, os objetos dessa classe não precisarão de uma vtable. No entanto, você não conseguirá sobrescrever um método dessa classe através de uma derivada:</p>
<p><pre><span style="color: #006600;">#include &lt;iostream&gt;</span>
&nbsp;
class C
<span style="color: #000000; font-weight: bold;">&#123;</span>
<span style="color: #0000ff;">public</span>:
        <span style="color: #0000ff;">void</span> method<span style="color: #000000; font-weight: bold;">&#40;</span><span style="color: #000000; font-weight: bold;">&#41;</span>
	<span style="color: #000000; font-weight: bold;">&#123;</span>
		std::<span style="color: #0000ff;">cout</span> &lt;&lt; <span style="color: #666666;">"C::method<span style="color: #666666;">\n</span>"</span>;
	<span style="color: #000000; font-weight: bold;">&#125;</span>
<span style="color: #000000; font-weight: bold;">&#125;</span>;
&nbsp;
class D : <span style="color: #0000ff;">public</span> C
<span style="color: #000000; font-weight: bold;">&#123;</span>
<span style="color: #0000ff;">public</span>:
        <span style="color: #0000ff;">void</span> method<span style="color: #000000; font-weight: bold;">&#40;</span><span style="color: #000000; font-weight: bold;">&#41;</span>
	<span style="color: #000000; font-weight: bold;">&#123;</span>
		std::<span style="color: #0000ff;">cout</span> &lt;&lt; <span style="color: #666666;">"D::method<span style="color: #666666;">\n</span>"</span>;
	<span style="color: #000000; font-weight: bold;">&#125;</span>
<span style="color: #000000; font-weight: bold;">&#125;</span>;
&nbsp;
<span style="color: #0000ff;">void</span> func<span style="color: #000000; font-weight: bold;">&#40;</span>C* c<span style="color: #000000; font-weight: bold;">&#41;</span>
<span style="color: #000000; font-weight: bold;">&#123;</span>
        c-&gt;method<span style="color: #000000; font-weight: bold;">&#40;</span><span style="color: #000000; font-weight: bold;">&#41;</span>; 
<span style="color: #000000; font-weight: bold;">&#125;</span>
&nbsp;
<span style="color: #0000ff;">int</span> main<span style="color: #000000; font-weight: bold;">&#40;</span><span style="color: #000000; font-weight: bold;">&#41;</span>
<span style="color: #000000; font-weight: bold;">&#123;</span>
        D d;
        func<span style="color: #000000; font-weight: bold;">&#40;</span>&amp;d<span style="color: #000000; font-weight: bold;">&#41;</span>; <span style="color: #006600;">// passa endere&ccedil;o de C &quot;dentro de D&quot;</span>
<span style="color: #000000; font-weight: bold;">&#125;</span>
&nbsp;</pre></p>
<pre>Saída
=====</pre>
<pre>C::method</pre>
<p>No exemplo acima, a chamada feita em func irá chamar o método da classe C, mesmo que a classe D tenha sobrescrito esse método. O programador semi-experiente deve pensar "lógico, ela não é virtual!", e está certo, assim como qualquer pessoa que decora essas formulazinhas de vestibular.</p>
<p>Para criarmos polimorfismo de verdade, precisamos declarar o método em C como virtual:</p>
<pre>class C
{
public:
        virtual void method();
};</pre>
<p>Agora sim, a chamada em func irá ser para D::method.</p>
<p>Pergunte para o programador semi-experiente em C++ por que as coisas são assim e provavelmente ele irá falar algo sobre vtable, mesmo que não saiba exatamente como ela funciona.</p>
<p>A vtable é uma tabela que guarda o endereço dos métodos virtuais de uma classe. Se uma classe derivada sobrescrever um ou mais métodos de sua classe base, ela terá uma outra vtable com os endereços dos métodos "corrigidos".</p>
<p>&nbsp;</p>
<p style="text-align: center;"><a href="http://www.caloni.com.br/blog/wp-content/uploads/vtable11.png"><img class="aligncenter size-full wp-image-1151" title="vtable1" src="http://www.caloni.com.br/blog/wp-content/uploads/vtable11.png" alt="" width="823" height="935" /></a></p>
<p>Dessa forma, algo um pouco diferente ocorre na chamada c-&gt;method() quando estamos lidando com classes polimórficas: o início de um objeto dessa classe terá um ponteiro para a vtable de sua classe. Quando um método virtual é chamado, em vez do compilador gerar uma chamada estática para o endereço do método da classe cujo tipo estamos usando, ele irá redirecionar essa chamada para uma posição na vtable para onde esse objeto aponta. No caso de um objeto do tipo D, a entrada para method em sua vtable apontará não para C::method, mas para D::method, uma função com a mesma assinatura contida na classe base C e que, portanto, a sobrescreve.</p>
<p>Façamos um pequeno teste para comprovar o que falamos. Vamos escancarar a chamada feita a partir de uma instância de D e a partir de uma instância de C. Nada que um WinDbg não resolva de braços cruzados:</p>
<pre>int main()
{
        D d;
        C c;

        func(&amp;d);
        func(&amp;c);
}</pre>
<pre>cl /Zi vtable3.cpp
windbg vtable3.exe</pre>
<p>&nbsp;</p>
<p style="text-align: center;"><a title="vtable2.png" href="http://www.caloni.com.br/blog/wp-content/uploads/vtable2.png"><img src="http://www.caloni.com.br/blog/wp-content/uploads/vtable2.png" alt="vtable2.png" /></a></p>
]]></content:encoded>
			<wfw:commentRss>http://www.caloni.com.br/blog/archives/vtable/feed</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>Reunião de programadores C++ (há 5 anos)</title>
		<link>http://www.caloni.com.br/blog/archives/reuniao-de-programadores-c-ha-5-anos</link>
		<comments>http://www.caloni.com.br/blog/archives/reuniao-de-programadores-c-ha-5-anos#comments</comments>
		<pubDate>Wed, 12 Jan 2011 19:17:25 +0000</pubDate>
		<dc:creator>Wanderley Caloni</dc:creator>
				<category><![CDATA[C++]]></category>
		<category><![CDATA[Devaneando]]></category>

		<guid isPermaLink="false">http://www.caloni.com.br/blog/archives/reuniao-de-programadores-c-ha-5-anos</guid>
		<description><![CDATA[Começo de ano, hora de fazer backup completo. Durante minha cópia anual do gmail acabei encontrando meu post-chamado para nossa primeira reunião C++. Como parte da sessão nostalgia, convido-os, novos e velhos colegas, a continuar a brincadeira de organizar uma reunião informal de pessoas que gostam  [...]]]></description>
			<content:encoded><![CDATA[<p>Começo de ano, hora de fazer backup completo. Durante minha cópia anual do gmail acabei encontrando meu post-chamado para nossa primeira reunião C++. Como parte da sessão nostalgia, convido-os, novos e velhos colegas, a continuar a brincadeira de organizar uma reunião informal de pessoas que gostam tanto de programar que criam seus próprios ponteiros.</p>
<p><em>E-mail escrito em 02/12/2005:</em></p>
<p>Um dia desses conversando com o <a href="http://www.1bit.com.br">Rodrigo Strauss</a>, falando sobre como é interessante trocar informações e experiências sobre C++, ele teve a brilhante e original idéia (ninguém nunca fez isso antes) de propor encontros razoavelmente regulares para fazermos isso. A idéia dele era mais ou menos essa:</p>
<ul>
<li>Peridiocidade dos encontros de X em X meses. Ainda não fechamos isso;</li>
<li>X pautas por reunião, votadas pelos participantes. Já temos algumas sugestões como, recursos arcanos do C++ (essa, de acordo com ele, seria minha função), ferramentas, bibliotecas, organização de código etc;</li>
<li>Troca de experiências sobre C++ em diversos sistemas operacionais. Por exemplo, nós mostraríamos para o pessoal de UNIX o Visual C++ e aprenderíamos com eles sobre emacs ou KDevelop;</li>
<li>Começar de forma muito simples, como uma mesa redonda, e se a coisa avançar, arrumar um lugar para palestras e apresentações;</li>
<li>Reuniões em bares ou restaurantes onde possamos conversar, levar acompanhantes e nos sentirmos seguros levando notebooks ou Pockets. Podemos até subir uma rede wifi e aumentar a diversão <img src='http://www.caloni.com.br/blog/wp-includes/images/smilies/icon_smile.gif' alt=':-)' class='wp-smiley' /> </li>
<li>Como eu e o Strauss somos de São Paulo (na verdade, eu sou de São Bernardo), os primeiros encontros seriam na capital;</li>
<li>Isso é uma boa desculpa para se encontrar e tomar um chopp || guaraná || cachaça.</li>
</ul>
<p>Gostaríamos que as pessoas da comunidade C++ dessem sugestões sobre essa idéia. Estamos pensando em agendar o primeiro encontro para dia 17/12/2005 (sábado) durante a tarde, em um Outback (comida australiana, Shopping Center Norte ou Eldorado, tem infra para crianças e a comida é muito boa). Como pauta do primeiro encontro eu sugiro uma apresentação dos participantes (o que será desnecessário se só eu e o Strauss aparecermos) e uma discussão sobre o presente e o futuro do mercado de trabalho C++.</p>
<p>Coloquem as sugestões nos comentários e quando a gente fechar alguma coisa eu escrevo um novo post com o que definimos. Até lá.</p>
<p><em>PS: Qualquer semelhança deste post com o conteúdo de um conhecido blog brasileiro sobre programação não é mera coincidência.</em></p>
]]></content:encoded>
			<wfw:commentRss>http://www.caloni.com.br/blog/archives/reuniao-de-programadores-c-ha-5-anos/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Pós-&#8221;II Seminário Portabilidade e Performance&#8221;</title>
		<link>http://www.caloni.com.br/blog/archives/pos-ii-seminario-portabilidade-e-performance</link>
		<comments>http://www.caloni.com.br/blog/archives/pos-ii-seminario-portabilidade-e-performance#comments</comments>
		<pubDate>Tue, 21 Dec 2010 03:44:52 +0000</pubDate>
		<dc:creator>Wanderley Caloni</dc:creator>
				<category><![CDATA[C++]]></category>

		<guid isPermaLink="false">http://www.caloni.com.br/blog/archives/pos-ii-seminario-portabilidade-e-performance</guid>
		<description><![CDATA[O nosso seminário da semana retrasada sobre portabilidade e performance teve um clima mais familiar, lembrando os antigos eventos. O tamanho menor da sala, aliado ao fato dos palestrantes não precisarem usar microfone, como foi da última vez, fez com que houvesse mais interação com o público, com  [...]]]></description>
			<content:encoded><![CDATA[<p>O nosso <a href="http://www.temporealeventos.com.br/?area=1&amp;tipo=1&amp;id=3719">seminário da semana retrasada</a> sobre portabilidade e performance teve um clima mais familiar, lembrando os antigos eventos. O tamanho menor da sala, aliado ao fato dos palestrantes não precisarem usar microfone, como foi da última vez, fez com que houvesse mais interação com o público, com destaque para minha própria palestra, onde tivemos um hiato significativo para falar sobre o desempenho da classe std::string e outros assuntos mais obscuros.</p>
<p>A ordem das palestras também ajudou muito a tecer os conteúdos individuais para algo maior e em comum, que eram os temas do seminário: se com Galuppo tivemos uma pitada do desenvolvimento concorrente, com Fernando conseguimos entender de uma maneira simples e didática como funcionam os recursos de sincronismo entre threads rodando em múltiplos cores, com uma pequena ajuda de um exemplo em C levado ao nível de assembly, onde foi possível acompanhar o que já havíamos aprendido com a palestra do Caloni.</p>
<p style="text-align: center"><img src="http://www.caloni.com.br/blog/wp-content/uploads/assemblypp.png" alt="Assembly++ - A Palestra" /></p>
<p>Pra terminar, um apanhado de boas práticas e  a experiência de quem já mexeu muito com análise e desempenho no código: Rodrigo Strauss. Além das dicas e do bom humor costumeiros, tivemos uma pequena prévia do que poderemos ter em breve com o tema "C++ com outra linguagens".</p>
<p>Deixarei disponibilizado para download minha transparência, onde infelizmente não estão embutidos o áudio nem o vídeo do momento realmente importante,que foi a interação do grupo durante a apresentação. Se você perdeu, so sorry. Até a próxima!</p>
<ul>
<li><a href="http://www.caloni.com.br/blog/wp-content/uploads/assemblypp.7z" title="Palestra Assembly++ (com fontes de exemplo)">Palestra Assembly++ (com fontes de exemplo)</a> (ministrada em 2010-12-11).</li>
<li><a href="http://www.temporealeventos.com.br/?area=101-SeminarioC-e-C++-Portabilidade-e-Performance">Saite do evento</a></li>
</ul>
]]></content:encoded>
			<wfw:commentRss>http://www.caloni.com.br/blog/archives/pos-ii-seminario-portabilidade-e-performance/feed</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>II Seminário Portabilidade e Performance</title>
		<link>http://www.caloni.com.br/blog/archives/ii-seminario-portabilidade-e-performance</link>
		<comments>http://www.caloni.com.br/blog/archives/ii-seminario-portabilidade-e-performance#comments</comments>
		<pubDate>Fri, 12 Nov 2010 13:46:26 +0000</pubDate>
		<dc:creator>Wanderley Caloni</dc:creator>
				<category><![CDATA[C++]]></category>

		<guid isPermaLink="false">http://www.caloni.com.br/blog/archives/ii-seminario-portabilidade-e-performance</guid>
		<description><![CDATA[Aqui estamos nós de novo. Mais uma vez a Tempo Real Eventos irá organizar esse evento de final de ano. E mais uma vez, junto dos meus amigos, irei palestrar sobre um item indispensável no nécessaire de todo escovador de bits: assembly gerado pelo compilador. Vamos falar brevemente sobre o  [...]]]></description>
			<content:encoded><![CDATA[<p>Aqui estamos nós de novo. Mais uma vez a <a href="http://www.temporealeventos.com.br/?area=101-SeminarioC-e-C++-Portabilidade-e-Performance" title="Seminário Portabilidade e Performance">Tempo Real Eventos</a> irá organizar esse evento de final de ano. E mais uma vez, junto dos meus amigos, irei palestrar sobre um item indispensável no nécessaire de todo escovador de bits: assembly gerado pelo compilador. Vamos falar brevemente sobre o funcionamento de um código assembly 32 bits e passar para a análise dos compiladores modernos e o que eles fazem para tornar o código ainda mais rápido do que o próprio fonte em C++.</p>
<ul>
<li>Gerando código assembly;</li>
<li>Guia ultra-rápido de assembly;</li>
<li>Recursividade sem problemas na pilha;</li>
<li>STL aumenta performance? (exemplos práticos);</li>
<li>Assembly 64 bits.</li>
</ul>
<p>Uma outra dúvida pertinente (e discutida nos bares nerds da cidade) é se usar código STL não deixaria mais lento o resultado final, já que ele é cheio das abstrações. Por mais que autoridades competentes no funcionamento da linguagem como <a href="http://software.pedro.lamarao.nom.br/" title="Blogue profissional de Pedro Lamarão">Pedro Lamarão</a> e <a href="http://www.thradams.com/blog/" title="Blogue profissional de Thiago Adams">Thiago Adams</a> digam que as otimizações do compiladores modernos na STL/Boost são diversas vezes mais eficientes que o código artesanal de um programador, sempre fica aquela pulga atrás da orelha, pulga esta que podemos matar facilmente analisando o assembly gerado. E essa confiança extra nos dará novas chances de programar coisas legais de verdade, e não ficar ensebando um código que já está na sua velocidade máxima.</p>
<p>Então é isso aí. Espero que tenhamos uma manhã e uma tarde agradáveis nesse mundo da escovação de bits.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.caloni.com.br/blog/archives/ii-seminario-portabilidade-e-performance/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Evento C++</title>
		<link>http://www.caloni.com.br/blog/archives/evento-c</link>
		<comments>http://www.caloni.com.br/blog/archives/evento-c#comments</comments>
		<pubDate>Mon, 16 Aug 2010 16:36:58 +0000</pubDate>
		<dc:creator>Wanderley Caloni</dc:creator>
				<category><![CDATA[C++]]></category>
		<category><![CDATA[Depuração]]></category>

		<guid isPermaLink="false">http://www.caloni.com.br/blog/archives/evento-c</guid>
		<description><![CDATA[Esse fim-de-semana houve o tão falado evento C++, com a presença de dezenas de pessoas, algo que eu sinceramente não esperava. O bom desse evento foi saber que existem tantas pessoas interessadas em manter contato com quem gosta e pratica essa linguagem e também em saber que o nível técnico das  [...]]]></description>
			<content:encoded><![CDATA[<p>Esse fim-de-semana houve o tão falado evento C++, com a presença de dezenas de pessoas, algo que eu sinceramente não esperava. O bom desse evento foi saber que existem tantas pessoas interessadas em manter contato com quem gosta e pratica essa linguagem e também em saber que o nível técnico das palestras estão de alto para avançado.</p>
<p>Infelizmente em nenhuma das duas palestras práticas (minha e do Fernando) houve participação interativa, e ninguém que eu saiba abriu meu pacote-surpresa com os dumps a serem analisados. De qualquer forma, minha palestra ficou bagunçada pelo excesso de conteúdo e falta de tempo, o que me fez dar boas risadas ao ouvir no twitter que <a href="http://twitter.com/nicolasgavlak/status/21201995301" title="Twitter">minha palestra foi mais um brainstorm</a>. A intenção não era essa, claro, mas meu claro despreparo para muito conteúdo gerou essa impressão. Espero que do pouco que consegui explicar alguém tenha achado utilidade.</p>
<p>E, pelo jeito, futuramente irei aplicar essa mesma metodologia brainstorm em um videocast, que ainda não decidi como irei preparar. A ideia é analisarmos alguns dumps em conjunto e, para os que acompanharem online, a interatividade de perguntas &amp; respostas.</p>
<p>Mas enquanto isso não acontece vamos dar uma olhada no que tínhamos no <a href="http://www.caloni.com.br/blog/archives/nao-e-minha-culpa">pacote-surpresa</a>.</p>
<h4>1. NotMyFaultEither.exe.mdmp - Stack Trash</h4>
<pre>0:000&gt; kv
ChildEBP RetAddr  Args to Child
0012b200 7c90df3c 7c8025db 000000e8 00000000 ntdll!KiFastSystemCallRet
0012b204 7c8025db 000000e8 00000000 0012b238 ntdll!NtWaitForSingleObject+0xc
0012b268 7c802542 000000e8 000493e0 00000000 kernel32!WaitForSingleObjectEx+0xa8
0012b27c 6998ada6 000000e8 000493e0 003a0043 kernel32!WaitForSingleObject+0x12
0012bd70 6998aff1 000000c4 00000568 000000d0 faultrep!InternalGenerateMinidumpEx+0x335
0012bd9c 6998b50a 000000c4 00000568 0012c698 faultrep!InternalGenerateMinidump+0x75
0012c678 69986652 000000c4 00000568 0012c698 faultrep!InternalGenFullAndTriageMinidumps+0x8a
0012dea0 69987d3d 0012df18 0015c300 00000000 faultrep!ReportFaultDWM+0x4e5
0012e398 699882d8 0040a1dc 0012f1e0 ffffffff faultrep!StartManifestReportImmediate+0x268
0012f404 7c8643c6 0040a1dc ffffffff 0012fc24 faultrep!ReportFault+0x55a
Unable to load image C:\Documents and Settings\Administrador\Desktop\NotMyFaultEither.exe
*** WARNING: Unable to verify timestamp for NotMyFaultEither.exe
*** ERROR: Module load completed but symbols could not be loaded for NotMyFaultEither.exe
0012f678 004018aa 0040a1dc e280eec4 1d7f113b kernel32!UnhandledExceptionFilter+0x55b
WARNING: Stack unwind information not available. Following frames may be wrong.
0012f9ac 00401357 <font color="#ff0000">dededede dededede dededede</font> NotMyFaultEither+0x18aa
0012fbe8 <font color="#ff0000">dededede dededede dededede dededede</font> NotMyFaultEither+0x1357
0012fbec <font color="#ff0000">dededede dededede dededede dededede</font> 0xdededede
0012fbf4 <font color="#ff0000">dededede dededede dededede dededede</font> 0xdededede
...</pre>
<p>Como foi visto na palestra, uma pilha nesse estado demonstra claramente alguma variável que estourou e corrompeu o resto da pilha de chamadas. Na hora de voltar para a função chamadora, o endereço usado foi o endereço reescrito por lixo, e daí temos o "crash-pattern" Stack Trash.</p>
<h4>2. NotMyFaultEither.mdmp - Dead Lock</h4>
<pre>0:000&gt; kv
ChildEBP RetAddr  Args to Child
0012f900 7c90df3c 7c8025db 0000007c 00000000 ntdll!KiFastSystemCallRet
0012f904 7c8025db <font color="#ff0000">0000007c </font>00000000 00000000 ntdll!NtWaitForSingleObject+0xc
0012f968 7c802542 0000007c ffffffff 00000000 kernel32!WaitForSingleObjectEx+0xa8
0012f97c 00401176 0000007c ffffffff 00000111 kernel32!WaitForSingleObject+0x12
WARNING: Stack unwind information not available. Following frames may be wrong.
0012f9c0 7c910202 00000002 001506e8 00150000 NotMyFaultEither+0x1176
0012f9f8 7e3746d3 01010050 00000000 00000000 ntdll!RtlpAllocateFromHeapLookaside+0x42
0012fa5c 7e382672 01010050 01100068 7e3a4716 user32!DrawStateW+0x5cd
0012fae8 7e382c75 001563ac 01010050 00000003 user32!xxxBNDrawText+0x313
0012fb20 002d0036 00000000 00000020 0012fb3c user32!xxxDrawButton+0xbb
0012fb30 7e3799d8 0000800a 0012fbc8 7e375ba2 0x2d0036
0012fb3c 7e375ba2 0000800a 002d0036 fffffffc user32!NotifyWinEvent+0xd
0012fbc8 00000000 002d0036 004011b0 dcbaabcd user32!ButtonWndProcWorker+0x79b
0:000&gt; !handle 0000007c
Handle <font color="#ff0000">0000007c</font>
  Type         	<font color="#ff0000">Thread</font>
0:000&gt; ~* kv

.  0  Id: 5e4.<font color="#008000">39c </font>Suspend: 0 Teb: 7ffdd000 Unfrozen
ChildEBP RetAddr  Args to Child
0012f900 7c90df3c 7c8025db 0000007c 00000000 ntdll!KiFastSystemCallRet
0012f904 7c8025db 0000007c 00000000 00000000 ntdll!NtWaitForSingleObject+0xc
0012f968 7c802542 0000007c ffffffff 00000000 kernel32!WaitForSingleObjectEx+0xa8
0012f97c 00401176 0000007c ffffffff 00000111 kernel32!WaitForSingleObject+0x12
WARNING: Stack unwind information not available. Following frames may be wrong.
0012f9c0 7c910202 00000002 001506e8 00150000 NotMyFaultEither+0x1176
0012f9f8 7e3746d3 01010050 00000000 00000000 ntdll!RtlpAllocateFromHeapLookaside+0x42
0012fa5c 7e382672 01010050 01100068 7e3a4716 user32!DrawStateW+0x5cd
0012fae8 7e382c75 001563ac 01010050 00000003 user32!xxxBNDrawText+0x313
0012fb20 002d0036 00000000 00000020 0012fb3c user32!xxxDrawButton+0xbb
0012fb30 7e3799d8 0000800a 0012fbc8 7e375ba2 0x2d0036
0012fb3c 7e375ba2 0000800a 002d0036 fffffffc user32!NotifyWinEvent+0xd
0012fbc8 00000000 002d0036 004011b0 dcbaabcd user32!ButtonWndProcWorker+0x79b

   1  Id: 5e4.6a4 Suspend: 0 Teb: 7ffdc000 Unfrozen
ChildEBP RetAddr  Args to Child
00b8ff10 7c90df3c 7c91b22b 00000080 00000000 ntdll!KiFastSystemCallRet
00b8ff14 7c91b22b 00000080 00000000 00000000 ntdll!NtWaitForSingleObject+0xc
00b8ff9c 7c901046 0040e940 004010e0 0040e940 ntdll!RtlpWaitForCriticalSection+0x132
00b8ffa4 004010e0 <font color="#0000ff">0040e940 </font>00000000 00000000 ntdll!RtlEnterCriticalSection+0x46
WARNING: Stack unwind information not available. Following frames may be wrong.
00b8ffec 00000000 004010c0 0012f99c 00000000 NotMyFaultEither+0x10e0
0:000&gt; !cs <font color="#0000ff">0040e940</font>
-----------------------------------------
Critical section   = 0x0040e940 (NotMyFaultEither+0xE940)
DebugInfo          = 0x00154498
<font color="#0000ff">LOCKED</font>
LockCount          = 0x1
OwningThread       = <font color="#008000">0x0000039c</font>
RecursionCount     = 0x1
LockSemaphore      = 0x80
SpinCount          = 0x00000000</pre>
<p>A thread ativa no momento do dump aguardava por outra thread. Listando todas as threads do processo temos a primeira e a segunda, que tenta entrar em um critical section. Quando vemos que aquele CS estava sendo bloqueado pela primeira thread vemos claramente se tratar de um dead lock.</p>
<h4>3. NotMyFaultEither_100808_172407.dmp - Access Violation</h4>
<pre>0:000&gt; kv
ChildEBP RetAddr  Args to Child
WARNING: Stack unwind information not available. Following frames may be wrong.
0012f9cc 7e37f916 01010052 005a0049 0012f9f4 NotMyFaultEither+0x10a3
0012fa58 7e37f991 01010052 00000043 01100076 user32!ClientFrame+0xe0
0012fa7c 7e382909 01010052 0012fa98 00000000 user32!DrawFocusRect+0x40
0012fae8 7e382c75 00156304 01010052 00000003 user32!xxxBNDrawText+0x3e9
0012fb20 001100a0 00000000 00000020 0012fb3c user32!xxxDrawButton+0xbb
0012fb30 7e3799d8 0000800a 0012fbc8 7e375ba2 0x1100a0
0012fb3c 7e375ba2 0000800a 001100a0 fffffffc user32!NotifyWinEvent+0xd
0012fbc8 00000000 001100a0 004010f0 dcbaabcd user32!ButtonWndProcWorker+0x79b
0:000&gt; <font color="#ff0000">? eax+edx</font>
Evaluate expression: 0 = <font color="#ff0000">00000000</font>
0:000&gt; u
NotMyFaultEither+0x10a3:
004010a3 66890c02        mov     word ptr [<font color="#ff0000">edx+eax</font>],cx
004010a7 83c002          add     eax,2
004010aa 6685c9          test    cx,cx</pre>
<p>O disassemble da instrução inválida tenta escrever claramente em cima do endereço zerado (edx + eax). Dessa forma fica fácil saber que esse tipo de escrita não é permitido, constituindo nosso famosíssimo AV.</p>
<h4>4. NotMyFaultEither_100808_175404.dmp - Exception not Handled</h4>
<pre>eax=00000000 ebx=00000111 ecx=7c91003d edx=00010000 esi=00330120 edi=7e374dfa
eip=7c90120e esp=0012f9a0 ebp=00000001 iopl=0         nv up ei pl zr na pe nc
cs=001b  ss=0023  ds=0023  es=0023  fs=003b  gs=0000             efl=00000246
ntdll!DbgBreakPoint:
<font color="#ff0000">7c90120e cc              int     3</font>
0:000&gt; kv
ChildEBP RetAddr  Args to Child
0012f99c 004011ec 0012fc24 004010d0 0012fbe8 <font color="#ff0000">ntdll!DbgBreakPoint</font> (FPO: [0,0,0])
WARNING: Stack unwind information not available. Following frames may be wrong.
0012f9cc 7e37f916 01010054 005a0049 0012f9f4 NotMyFaultEither+0x11ec
0012fa58 7e37f991 01010054 00000043 01100076 user32!ClientFrame+0xe0</pre>
<p>Esse foi meio de brinde. Uma exceção de breakpoint (int 3, ntdll!DbgBreakPoint) lançada sem um depurador atachado implica em derrubamento do processo, pois é uma exceção como outra qualquer. O programador deve ter esquecido um DebugBreak ou algo que o valha no código de produção, que acabou sendo executado.</p>
<h5>5. ntdll_cliente.dll - Importação de símbolos</h5>
<p><a href="http://www.caloni.com.br/blog/wp-content/uploads/vm-sony-xp-2010-08-08-17-59-22.png" title="vm-sony-xp-2010-08-08-17-59-22.png"><img src="http://www.caloni.com.br/blog/wp-content/uploads/vm-sony-xp-2010-08-08-17-59-22.png" alt="vm-sony-xp-2010-08-08-17-59-22.png" /></a><br />
Essa foi a DLL encontrada no cliente quando ocorreu o problema relatado na imagem, também em anexo. Isso foi demonstrado na palestra com a ajuda do meu script que carrega DLLs, além de um pouco de sorte. Podemos analisar esse caso com mais calma em outro artigo. Acho que já falei demais por aqui.</p>
<h4>Slides</h4>
<ul>
<li>Download dos <a href="http://www.caloni.com.br/blog/wp-content/uploads/crash-dump-analysis-slides.zip" title="crash-dump-analysis-slides.zip">slides</a> usados na palestra.</li>
</ul>
]]></content:encoded>
			<wfw:commentRss>http://www.caloni.com.br/blog/archives/evento-c/feed</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>Sétimo Encontro de Programadores C++</title>
		<link>http://www.caloni.com.br/blog/archives/setimo-encontro-de-programadores-c</link>
		<comments>http://www.caloni.com.br/blog/archives/setimo-encontro-de-programadores-c#comments</comments>
		<pubDate>Mon, 26 Jul 2010 02:44:31 +0000</pubDate>
		<dc:creator>Wanderley Caloni</dc:creator>
				<category><![CDATA[C++]]></category>
		<category><![CDATA[Depuração]]></category>
		<category><![CDATA[Devaneando]]></category>

		<guid isPermaLink="false">http://www.caloni.com.br/blog/archives/setimo-encontro-de-programadores-c</guid>
		<description><![CDATA[Mais um fim-de-semana no ócio e na vadiagem. Tenho que manter minhas qualidades de bom programador que sou: preguiçoso, impaciente e pretensioso.
Mas nem por isso deixei de terminar uma primeira versão do aplicativo que irei usar como base na minha palestra do nosso próximo encontro C++: Crash Dump  [...]]]></description>
			<content:encoded><![CDATA[<p>Mais um fim-de-semana no ócio e na vadiagem. Tenho que manter minhas <a href="http://c2.com/cgi/wiki?LazinessImpatienceHubris">qualidades de bom programador</a> que sou: preguiçoso, impaciente e pretensioso.</p>
<p>Mas nem por isso deixei de terminar uma primeira versão do aplicativo que irei usar como base na minha palestra do nosso próximo <a href="http://www.ccppbrasil.org/wiki/Grupo:Encontro_VII">encontro C++</a>: <a href="http://www.caloni.com.br/blog/wp-content/uploads/crashdumpanalysis.7z" title="CrashDumpAnalysis">Crash Dump Analysis</a>. Se alguém tiver dicas de quais os problemas mais difíceis do Universo para analisar em um dump de memória, comente a respeito e veremos o que dá pra fazer.</p>
<p style="text-align: center"><img src="http://www.caloni.com.br/blog/wp-content/uploads/crash-dump.png" alt="crash-dump.png" /></p>
<p>Enquanto isso, continuo descobrindo maravilhas do WinDbg. Essa semana fiquei brincando de colocar breakpoint em user-mode, mas depurando o kernel, como fizeram <a href="http://blogs.msdn.com/b/ntdebugging/archive/2010/07/20/debugging-services-startup-in-svchost-from-a-kernel-mode-debug-session.aspx">os rapazes do Ntdebugging</a>. A conclusão é que ele vale para todos os aplicativos abertos. Tente com o MessageBox!</p>
<pre>!process 0 0 notepad.exe
.reload /user
bp user32!MessageBoxW</pre>
<p>Mas devaneio. Talvez outra boa qualidade de um bom programador.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.caloni.com.br/blog/archives/setimo-encontro-de-programadores-c/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Const e Volatile</title>
		<link>http://www.caloni.com.br/blog/archives/const-e-volatile</link>
		<comments>http://www.caloni.com.br/blog/archives/const-e-volatile#comments</comments>
		<pubDate>Fri, 04 Jun 2010 17:26:33 +0000</pubDate>
		<dc:creator>Wanderley Caloni</dc:creator>
				<category><![CDATA[C++]]></category>

		<guid isPermaLink="false">http://www.caloni.com.br/blog/archives/const-e-volatile</guid>
		<description><![CDATA[

Padrão C (ISO/IEC 9899:1990)

6.5.3 type-qualifier
 const
 volatile
Padrão C++ (ISO/IEC 14882:1998)

cv-qualifier
 const
 volatile
Qualificadores de tipo
Chamamos de qualificador de tipo as palavrinhas mágicas const e volatile. Na prática elas definem como uma determinada variável será usada e se  [...]]]></description>
			<content:encoded><![CDATA[

<pre>Padrão C (ISO/IEC 9899:1990)

6.5.3 type-qualifier
 const
 volatile</pre>
<pre>Padrão C++ (ISO/IEC 14882:1998)

cv-qualifier
 const
 volatile</pre>
<h4>Qualificadores de tipo</h4>
<p>Chamamos de qualificador de tipo as palavrinhas mágicas <strong>const </strong>e <strong>volatile</strong>. Na prática elas definem como uma determinada variável será usada e se comportará durante a vida do programa.</p>
<h4>Const</h4>
<p>Uma variável const não pode ser alterada pelo programa durante sua execução, apenas durante sua inicialização:</p>
<pre>const float pi = 3.14; // até onde sabemos, pi não irá mudar neste Universo</pre>
<p>No exemplo acima, o valor de pi não pode mais ser alterado. Só que repare que ele foi, em determinado momento, alterado com um valor constante: na sua inicialização. Isso quer dizer que:</p>
<ul>
<li>pi é uma variável no programa representada por um local na memória <strong>endereçável </strong>pelo programa</li>
<li>pi não é um define do pré-processador que irá virar uma constante literal (3.14, por exemplo)</li>
</ul>
<pre>// eu posso endereçar uma constante,
// desde que qualifique corretamente meu ponteiro
const float* ppi = &amp; pi;</pre>
<p align="center"><img src="http://www.caloni.com.br/blog/wp-content/uploads/const-memory.png" alt="const-memory.png" height="291" width="133" /></p>
<p>Teoricamente a região da memória que contiver uma variável const pode ser qualificada pelo sistema operacional como somente-leitura, mas isso não é uma obrigação. É obrigação do compilador avisar sobre tentativas de alteração da variável no meio do programa, mas nem sempre é possível enxergar que a memória não é alterável. Dessa forma, resultados imprevisíveis podem ocorrer.</p>
<p><img src="http://www.caloni.com.br/blog/wp-content/uploads/const-gpf.png" alt="const-gpf.png" height="506" width="545" /></p>
<h4>Uso prático</h4>
<p>Eu costumo usar variáveis const no lugar de defines. Além de ganhar na tipagem as constantes não precisam ser necessariamente globais, nem acessíveis por outros módulos. Um outro uso muito comum é criar variáveis locais que você sabe que não devem ser alteráveis por ninguém, como o tamanho de matrizes primitivas.</p>
<p><pre><span style="color: #0000ff;">namespace</span> Math
<span style="color: #000000; font-weight: bold;">&#123;</span>
	<span style="color: #0000ff;">const</span> <span style="color: #0000ff;">float</span> Pi = <span style="color: #000000;">3</span>.<span style="color: #000000;">14</span>;
<span style="color: #000000; font-weight: bold;">&#125;</span>
&nbsp;
<span style="color: #006600;">//...</span>
&nbsp;
<span style="color: #0000ff;">int</span> func1<span style="color: #000000; font-weight: bold;">&#40;</span><span style="color: #0000ff;">int</span> x<span style="color: #000000; font-weight: bold;">&#41;</span>
<span style="color: #000000; font-weight: bold;">&#123;</span>
	<span style="color: #0000ff;">float</span> calc = x * Math::<span style="color: #000000;">Pi</span>;
	<span style="color: #0000ff;">return</span> calc;
<span style="color: #000000; font-weight: bold;">&#125;</span>
&nbsp;
<span style="color: #006600;">//...</span>
&nbsp;
<span style="color: #0000ff;">int</span> func2<span style="color: #000000; font-weight: bold;">&#40;</span><span style="color: #0000ff;">int</span> y<span style="color: #000000; font-weight: bold;">&#41;</span>
<span style="color: #000000; font-weight: bold;">&#123;</span>
	<span style="color: #0000ff;">const</span> <span style="color: #0000ff;">size_t</span> PathSize = MAX_PATH * <span style="color: #000000;">2</span>;
	<span style="color: #006600;">//...</span>
	<span style="color: #006600;">//...</span>
	<span style="color: #0000ff;">char</span> path<span style="color: #000000; font-weight: bold;">&#91;</span>PathSize<span style="color: #000000; font-weight: bold;">&#93;</span>;
	<span style="color: #006600;">//...</span>
<span style="color: #000000; font-weight: bold;">&#125;</span></pre></p>
<h4>Volatile</h4>
<p>O significado do volatile teoricamente muda de implementação para implementação, mas na prática é uma forma de definir uma variável que está sendo acessada por outros programas/threads/entidades espíritas que podem alterar o seu valor sem seu programa notar quando.</p>
<p style="text-align: center"><img src="http://www.caloni.com.br/blog/wp-content/uploads/volatile-girl.jpg" title="Se concentre! Não é esse tipo de volatile!" alt="Se concentre! Não é esse tipo de volatile!" height="189" width="189" /></p>
<p>O exemplo clássico da API Win32 é o <a href="http://msdn.microsoft.com/en-us/library/ms683614%28VS.85%29.aspx">InterlockedIncrement</a>, que realiza operações atômicas em valores inteiros. Para fazer isso é necessário usar um recurso interno disponível pelo processador que irá modificar a memória sem intrusão de outras threads/processadores.</p>
<p><img src="http://www.caloni.com.br/blog/wp-content/uploads/interlocked-increment.png" alt="interlocked-increment.png" /></p>
<h4>Uso prático</h4>
<p>Variáveis volatile geralmente interagem de alguma forma com o sistema em que rodam, e são representadas por ponteiros para memória retornada por esse sistema ou documentada como sendo de uso específico.</p>
<h4>Const e Volatile</h4>
<p>É possível que exista uma variável que não pode ser modificada pelo seu programa, mas é modificada pelo sistema, de forma que ela é uma mutante!</p>
<pre>/// endereça o relógio do sistema, atualizado a cada 1/100 milissegundos
const volatile int* g_systemClock = (const volatile int*) 0x7689B9D4;</pre>
<p><a href="http://fotos-videos-incriveis.blogspot.com/2009/04/tubarao-mutante.html" title="mutante.jpg"></a></p>
<p style="text-align: center"><a href="http://fotos-videos-incriveis.blogspot.com/2009/04/tubarao-mutante.html" title="mutante.jpg"><img src="http://www.caloni.com.br/blog/wp-content/uploads/mutante.jpg" alt="mutante.jpg" height="102" width="129" /> </a></p>
<p>A definição de *g_systemClock é de uma memória que não pode ser alterada; só que ela é, pelo sistema. Então a variável também é volatile. No entanto, independente de ser const ou volatile, o tipo nunca será <strong>alterado</strong>, apenas <strong>qualificado</strong>. São duas coisas diferentes na linguagem.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.caloni.com.br/blog/archives/const-e-volatile/feed</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
	</channel>
</rss>

