logo
Contato | Sobre...        
rebarba rebarba

Rodrigo Strauss :: Blog


Debug Markup Language: Mais uma carta na manga do WinDbg

Um recurso muito interessante e escondido do novo WinDbg chama-se DML, ou Debug Markup Language. É uma linguagem makup bem simples, com alguns recursos do HTML, como links. O melhor uso disso é que seu código pode chamar OutputDebugString (ou o equivalente da sua linguagem ou framework) passando ao invés de simples strings, links que podem ser clicados no WinDbg. Esses links disparam comandos do WinDbg, cuja utilidade é limitada somente pela criatividade e necessidade do programador.

O link <exec cmd="kb">Visualizar a pilha</exec>" terá como label a frase "Visualizar a pilha" e executará o comando "kb" quando for clicado. Simples assim.

Para demonstar a utilidade esse novo recurso, fiz um programa que simula um servidor que recebe conexões de clientes. Toda vez que um "cliente" se conectar, o programa montará um log em DML que terá um link para que as informações sobre o cliente sejam visualizados. Note que para que o WinDbg identifique as mensagens como DML, é necessário colocar <?dml?> antes das mensagem.


#include <windows.h>
#include <vector>

#include <string>
#include <sstream>
#include <strsafe.h>
#include <boost/shared_ptr.hpp>
 
//
// informações do cliente conectado
//
struct ClientInfo
{
  DWORD ClientId;
  wchar_t ClientName[64];
  DWORD ConnectTime;
};
 
int APIENTRY wWinMain(HINSTANCE, HINSTANCE, LPWSTR, int)
{
  std::vector<boost::shared_ptr<ClientInfo> > ClientVector;
 

  for(DWORD a = 0 ; a < 10 ; ++a)
  {
    std::wstringstream buf;
 
    //
    // criamos um novo cliente
    //
    boost::shared_ptr<ClientInfo> pNewClient(new ClientInfo());

 
    //
    // informações do novo cliente "conectado"
    //
    pNewClient->ClientId = a;
 
    //
    // montamos o nome dele com a versão segura
    // do sprintf
    //

    StringCbPrintfW(pNewClient->ClientName, 
        sizeof(pNewClient->ClientName), 
        L"Client %d", 
        pNewClient->ClientId);
 
    pNewClient->ConnectTime = GetTickCount();
 
    ClientVector.push_back(pNewClient);
 
    //
    // monta o DML com um link que mostra nosso cliente
    // no prompt do Windbg
    //
    buf << L"<?dml?><exec cmd=\"dt ClientInfo " << std::hex << pNewClient.get() 
      << "\">" << pNewClient->ClientName << "</exec>\n";

 
    OutputDebugString(buf.str().c_str());
 
    Sleep(3000);
  }
 
  //
  // isso é só um programa de testes, lembra?
  //
  Sleep(60000);
 
  //

  // olha mamãe, sem o garbage collector :-)
  //
 
  return 0;
}

E o resultado visto no WinDbg, depois de clicar no link "Client 4":

Não esqueça que para que isso funcione você precisará da versão mais atual do WinDbg.

Em 07/08/2006 13:29, por Rodrigo Strauss


  
 
 
Comentários
Wanderley Caloni Jr | website | em 08/08/2006 | #
Awesome! =D
Antonio Augusto Meireles | em 02/11/2006 | #
Louco. Muito Bom. Certamente acherei um uso para isto.
Rodrigo Strauss | website | em 03/11/2006 | #
:-)
rebarba rebarba
  ::::