Depurando até o último segundo
Caloni, 2009-03-31 computer blogComo depurar um programa que dá pau logo no final do desligamento de uma máquina?
No cenário em que isso se passa não existem usuários logados no momento, o que significa a impossibilidade de rodar qualquer programa em uma sessão prévia e mantê-lo no ar após o logoff. A não ser que se trate de um serviço.
O nosso programa é justamente um serviço, e por isso ele continua rodando até o final, ou bem perto dele. A primeira ideia que vem à mente é instalar o Msvcmon - depurador remoto do Visual Studio - como um serviço, como aliás já foi demonstrado neste blogue.
Essa é uma boa ideia, de fato. Contudo, não podemos esquecer que a ordem de descarregamento dos serviços pode não favorecer o nosso depurador remoto e ele ir embora antes que consigamos "atachar" nosso VC no programa faltoso. Além do mais, a própria rede, que é disponibilizada com a ajuda de serviços, pode não estar no ar, mesmo que o Msvcmon esteja.
Tudo bem, vamos dizer que você é um expert em configuração de dependências de serviços e conseguiu fazer com que a rede, o Msvcmon e o programa faltoso sejam os últimos serviços - com exceção dos drivers - a serem descarregados. Bravo!
Contudo, isso não vai adiantar de muita coisa se for necessário parar a execução por um breve momento e analisar a pilha por, digamos, cinco segundos. Esse é o tempo que o sistema - que continua rodando - precisa para desligar a máquina.
Agora o problema é outro: não há tempo para análise durante a depuração, pois o sistema continua rodando. Nesse caso, teremos que ser mais radicais e parar o próprio sistema para que possamos depurar calmamente o problema. Isso implica em termos que utilizar um depurador de kernel (WinDbg), pois só ele tem poderes de congelar o sistema inteiro.
Mas, ainda assim, precisamos de um depurador de user para fazer análises mais profundas ou, pelo menos, mais simples, com a ajuda de símbolos e tudo mais. Nesse caso é necessário usar um depurador de user que redireciona o controle para o depurador de kernel. A transição user mode >> kernel mode pode ser feita com apenas algumas configurações antes do reboot.
E, após toda essa bagunça, podemos depurar, no conforto de uma VM, o bendito programa matador.
2009-03-31 Werner:
Caloni, me perdoe, mas às vezes lendo seus posts, acho que você é doido...
Não consigo entender, como alguém consegue entender o que vc entende. Mas ao mesmo tempo invejo isso.
Essa capacidade de Debug que você consegue executar está além do meu intelecto. Confesso que depois de começar a ler o seu blog, andei fazendo umas brincadeiras aqui, mas estou longe de conseguir meu primeiro "sucesso"...
Enfim, vou lendo e quem sabe uma hora entra alguma coisa na minha cabeça...
2009-04-01 Werner:
Caloni,
Você não deve considerar meu comentário como crítica. Foi apenas um pequeno desabafo, ante a minha dificuldade em entender o seu nível de debugging. Você já vive mergulhado nesse universo, que para mim é novo, de depuração de aplicativos em tempo real, coisa que eu, apesar de já ter "ouvido falar" nunca havia imaginado ser uma coisa de rotina para certos profissionais.
Acredito que esse conhecimento abre muitas portas, e torna o programador muito mais do que um simples "teclador de F9/F11", como a maioria (eu incluso), a quem o conceito de "depuração" limita-se a "prender" o código-fonte dentro do ambiente de desenvolvimento, utilizando os recursos embutidos (F9/F11/etc)...
O problema não acredito ser você, mas sim o iniciante (eu, novamente), que se depara com o "caminhão" de informações que você já vem aqui colocando, e precisa saber onde começar com o bê-a-bá.
Eu não sei mais ler Assembler, desde que me formei no curso de eletrônica (saudosos tempos em que eu programava em Assembly Z-80), há 15 anos atrás, e me admira ver que há pessoas como você, que provavelmente sabem ler o conteúdo das janelas do WinDBG como se fossem um livro aberto. E saber isso deve ser muito gratificante, eu imagino.
Para te citar dois exemplos práticos (que me fizeram lembrar de você):
Depois de começar a ler o seu blogue, me atentei para o fato de que poderia talvez buscar formas de "capturar" chamadas feitas às APIs Win32 (pois só posso imaginar que esses programas de "Setup" dos aplicativos buscam informações da versão do Sistema Operacional dentro de algum método específico que é fornecido pela API), e tentar alterar o seu valor de retorno, antes do mesmo ser lido pelo aplicativo.
Nessa brincadeira, depois de quebrar a cabeça com o SoftICE (sem entender muito o que eu estava fazendo), acabei me deparando com a ferramenta SpyStudio, que se parece bastante com um "debugger for dummies"... no momento, estou brincando com ele. Já consegui, graças a ele, localizar quais os métodos que estão nas DLLs kernel32 e user32, e que têm por função fornecer informações sobre o Sistema. Para mim, o maior problema até agora, está em localizar quais as chamadas que são feitas, para interceptar as corretas (já interceptei um só aplicativo fazendo várias chamadas para métodos diferentes, porém ao interceptar o retorno das mesmas e alterar os parâmetros corretos, ainda não consegui alcançar o meu objetivo).
Citei esses dois casos para que veja como, apesar de minha expressa dificuldade em entender seus textos avançados, eu estou dando pequenos passos.
O que você precisa compreender, se me permite dizer isso, é que não há forma de você simplificar um assunto tão complexo quanto debug em tempo real, nem a estrutura interna dos processadores atuais, a linguagem assembler, etc... aos interessados, cabe buscar fontes de informação que os coloquem na trilha certa, e o resto o tempo se encarrega.
Para mim, acho que é necessário começar com uma boa leitura. Sei que deve haver livros (não um, mas vários), que forneçam uma introdução ao assunto, e permitam dominar, com tempo, as técnicas nas quais você já é mestre. Já sei que o debugging é uma técnica multidisciplinar; não há um livro que fale sobre tudo, são muitos os assuntos a serem dominados. Mas se você puder, apreciaria muito uma "shopping list" de publicações que você considere válidas, e que me coloquem no caminho certo (assim eu posso contar com algo a mais além do "trial-and-error"...)
Um abraço e continue sempre!
(O meu nível de matemática não permite comentários??? :))
2009-04-01 Fernando Roberto:
Isso me faz lembrar de um trecho que li do Windows Driver Model, onde Walter Oney descreve que certa vez teve que depurar um driver que apresentava problemas com os eventos de gerenciamento de energia durante a transição para o Standby.
No caso dele, o driver de serial, de vídeo e de rede já tinham ido pra caminha. Nessa situaçao WinDbg e SoftIce deixaram de ser uma opção óbvia. Escrever mensagens em disco também não foi uma escolha interessante já que o File System havia desligado. Tudo que ele tinha era uma tela preta e um congelamento da máquina durante o processo de standby ou o retorno dele.
Por sorte, o teclado e a porta paralela ainda permaneciam ligados enquanto o problema era reproduzido, ele então decidiu utilizar o SoftIce e esperar o problema acontecer. Então, quando tudo parece congelado ele torce para que o SoftIce tenha manipulado algum ASSERT quando pressiona a tecla "Print Screeen". O SoftIce então manda a saída da tela para a impressora. Assim, a cada comando que ele lançava no SoftIce, ele fazia um Print Screen da tela. Muitas folhas mais tarde ele descobre o problema.
O cara é um herói. :-)
Windows Driver Model (2nd Edition) - página 434 "Debugging Power Management"
2009-04-01 Caloni:
Olá, Mr. Ferdinando.
Essa história foi de tirar lágrima das olhos!
Você me lembrou de mais um caso extremo de depuração: microcontroladores! Lembro-me do DQ (ou outro "old-timer") comentar em um dos encontros de C++ como ele fazia para "depurar" aquelas caixinhas dos infernos: usando um led. A cada passada da rotina depurada, o led era aceso e apagado. Dessa forma, era possível saber qual a parte do código que fazia com que o dispositivo travasse.
[]s
2009-04-01 Caloni:
Caro Werner,
Então o que eu temia é verdade: nada posso fazer para amenizar a longa e sinuosa estrada que leva programadores de F9/F11 para desbravadores das ciências ocultas da computação, prontos para encontrar o culpado no melhor estilo CSI que nem os experts da Polícia Federal conseguiriam fazer!
Por outro lado, sua história de tentativas e erros me deixou muito animado, pois demonstra que não estou sozinho nesse mundo de depuração hardcore. Dessa forma, espero aos poucos, conforme for acontecendo, narrar algumas aventuras em modo Debug que passo nos dias mais felizes do trabalho.
[]s
PS: Houve algum problema com o meu "Math Tester Enterprise Edition"? Espero que não, do contrário não terei como consertá-lo com meus conhecimentos matemáticos.
E por falar em matemática, saiu um artigo muito interessante (2026-03-21 link quebrado) no Coding Horror sobre a dicotomia programação/matemática.
2009-04-01 Caloni:
Olá, Werner!
Vou considerar seu comentário uma crítica. Claro! Afinal de contas, a ideia do blogue era unicamente compartilhar conhecimento com as pessoas. Se estou me expressando confusamente, então acho que o objetivo foi por água abaixo.
Espero que você não desista de suas tentativas de depuração. Mesmo que muitas coisas não deem certo nas primeiras vezes, com o tempo, experiência e cada vez mais conhecimento tudo vai ficando mais claro e lógico.
Se você puder me dizer quais os principais obstáculos para o aprendizado em técnicas de debugging ficarei muito grato, pois me dá a chance de melhorar meus artigos.
[]s
2009-04-02 Werner:
Caro Caloni,
Infelizmente (ou talvez, felizmente), se fosse assim tão simples e fácil explicar o caminho para as ciências ocultas da computação aos "não-Jedi", facilmente tais artes negras seriam banalizadas, assim como acontece hoje com muitas das tais "linguagens" de programação que estão em voga. Imagine o que aconteceria com as carreiras e os salários...
Mas enfim... de qualquer modo, eu padawan, vou tentando me manter no rumo, mesmo que a passos de formiga (e às vezes, de caranguejo - um passo à frente seguido de 3 passos atrás...). Assim é a vida.
Quanto ao "Math Tester", acredito ter se tratado de alguma questão referente a "timeout", levando em conta a proporção direta entre tamanho do texto X tempo dispendido.
Abraços!!
(Em tempo: Se você é carabão mesmo, quero vê-lo "debugar" este código-fonte...) :-)
2009-04-03 Werner:
Gostei muito do artigo no Coding Horror, que você citou. E devo dizer que concordo com o ponto de vista exposto.
Assim como o autor explica, vejo também a matemática como uma ferramenta dentre as milhares que existem, definida para solução de problemas específicos. Assim como nenhum programador precisa necessariamente ser economista para escrever um programa que auxilie no equilíbrio das contas do mês, ou técnico de futebol profissional, para criar um programa que faça a projeção das tabelas do campeonato estadual.
É claro que existem aplicações onde a matemática é a ferramenta mais indicada, e muito provavelmente lhe garantirá o sucesso na proporção direta do seu nível de conhecimento. Eu tive a oportunidade de sentir isso na carne: ano passado, trabalhei para uma companhia que me enviou ao exterior, para aprender a mexer com uma ferramenta snap-in para sistemas CAD profissionais, a qual eu desenvolveria, futuramente. Para isso, fui estudar com programadores que eram mestres e doutores em matemática e engenharia mecânica (para meu terror, pois tenho verdadeiro trauma de matemática, desde o ginásio, e graças ao fatídico "Caloni's Math Tester Enterprise Edition", o trauma aumenta exponencialmente a cada comentário meu aqui). Era tudo envolvendo séries finitas, cálculo espacial, e por aí vai. Para você ter uma idéia, um dos exercícios que me foram propostos consistia em importar um arquivo criado no aplicativo CAD (em três formatos distintos e tendo nada em comum entre si), uma peça qualquer simples, calcular suas medidas extremas em três dimensões, e finalmente, gravar um novo arquivo contendo a peça e mais a "bounding box" (trata-se de uma representação traçada em torno da peça, exatamente nas dimensões mais extremas, como se fosse uma "caixa envolvente"). Levei aproximadamente 5 dias para completar o exercício, sendo que 1/3 do tempo passei estudando e rabiscando em papel, conceitos de geometria que não havia visto mais desde a oitava série!!
Apesar de meus esforços terem gerado resultado (a meu ver) satisfatório, havia um fator bastante desagradável, a pressão imprimida pelos instrutores, que acharam o tempo dispendido por mim inaceitável (lembro-me que um deles ainda disse-me que ao bolar o exercício, tinha resolvido o mesmo em uma tarde...)
Aprendi duas lições que levarei comigo:
Primeiro, nunca trabalhe para alemães. Eu disse: NUNCA.
Segundo, se você venceu um desafio, não deixe que ninguém (especialmente um alemão metido a besta) lhe diga que você não está à altura.
(E terceira: C++ é amigo, amiiiiigo... amigoooo!!)
Abraços! :-)
2009-04-09 Alan:
O que seria o math tester enterprise edition??? Fiquei curioso agora... :D
2009-04-11 Caloni:
É simplesmente o formulário de comentários, que pede que você faça uma conta besta que nunca dá mais de 20 =)
[]s
2009-04-12 Werner:
Ufa, me causou tremendo alívio essa informação... meu buffer não comporta mais do que um small integer... :-P