Como depurar Thunks simples

Traduções deste artigo Traduções deste artigo
ID do artigo: 133722 - Exibir os produtos aos quais esse artigo se aplica.
Expandir tudo | Recolher tudo

Neste artigo

Sumário

Depuração simples thunks gerados pelo compilador conversão pode ser difícil porque o mecanismo de conversão é complexo e ferramentas de depuração capazes de rastreamento por meio de thunks são difíceis de usar. Este artigo apresenta uma estratégia geral para depuração thunks simples, várias técnicas de depuração específicas e um guia de solução de problemas que explica como corrigir muitos problemas comuns de conversão (thunking).

Mais Informações

Limitações no que pode fazer um DLL de destino

Antes de começar a depuração thunks, tenha em mente que há algumas limitações em que um destino DLL pode fazer dentro de uma conversão. Isso ocorre porque um aplicativo baseado em Win16 chamar uma DLL baseados em Win32 não é um processo baseado em Win32; da mesma forma, um aplicativo baseado em Win32 chamar uma DLL Win16 com não é um processo baseado em Win16. Limitações específicas comuns incluem:

  • Não é possível criar threads dentro de uma conversão de um aplicativo Win16 baseado em uma DLL baseados em Win32.
  • O código dentro de DLLs baseados em Win32 chamado pelo thunks deve exigir espaço de pilha pouco porque os processos com base em Win16 chamados tem muito menores pilhas de aplicativos baseados em Win32.
  • DLLs com base em Win16 que contêm rotinas de serviço de interrupção (ISRs) não devem thunk às DLLs baseados em Win32 ao manipular interrupções.
  • Aplicativos baseados em Win32 não devem passar ponteiros para dados localizados na pilha como parâmetros de thunks ou DLLs com base em Win16 que alternar pilhas de chamada.

Por que depuração Thunks simples pode ser difícil

Depuração thunks simples é difícil parcialmente porque o mecanismo de conversão simples é uma parte complexa de kernel do Windows. Seus radicais de complexidade do fato de que ele deve transformar chamadas de função no código compilado de 32 bits em chamadas compatível com código de 16 bits e vice-versa. Como códigos de 32 bits usa diferentes tipos de dados e CPU registrar conjuntos de códigos de 16 bits, o mecanismo de conversão simples deve converter os parâmetros da função, alternar pilhas e converter valores de retorno. Ela é otimizada para velocidade, mas deve permitir que código Win32 preemptiva chamar código não-preemptiva do Win16. O compilador de conversão faz thunks simples criar muito mais fácil que criá-las manualmente, mas não é à prova de falhas.

Depuração thunks simples é difícil não apenas porque o mecanismo propriamente dito é complexo, mas também pois as ferramentas de depuração necessárias são mais difíceis de serem mestre. Nível de aplicativo depuradores, como o depurador do Microsoft Visual C++ e o WinDBG não podem rastrear por meio de thunks porque eles consistem em código de 32 bits e 16 bits e fazer com que o sistema solicitar ou liberar o Win16Mutex. Para rastrear por meio de uma conversão, você precisará usar um depurador de nível de sistema, como WDEB386.EXE. As principais desvantagens usar WDEB386.EXE são que você precisa saber linguagem de assembly Intel x 86, saber como microprocessadores Intel x 86 funcionam e lembre-se muitos comandos do depurador.

A melhor estratégia para usar

A melhor estratégia para depuração thunks é dividir e conquistar porque é relativamente fácil e elimina a maioria dos problemas antes de precisar rastrear código de linguagem assembly em um depurador de nível de sistema. Thunks simples são compostos de uma DLL baseados em Win32 e uma DLL com base em Win16, portanto, é possível testar cada um deles em isolamento antes de testá-las juntas. Crie um aplicativo Win16 para testar a DLL do Win16 e crie um aplicativo baseado em Win32 para testar a DLL baseados em Win32. Isso permite que você use uma grande variedade de ferramentas de depuração para verificar se cada lado funciona corretamente.

Lista de verificação preliminar - antes da compilação com o compilador Thunk

Depois de você ter verificado que cada lado funciona corretamente, é hora de colocar os dois juntos para testar a conversão propriamente dito. Antes de compilar a conversão intermediária com o compilador de conversão, verifique uma verificação preliminar dos seguintes itens:
  1. No script conversão, verifique se cada função tem o número correto e os tipos de parâmetros. Verifique também se que os tipos de parâmetro são suportados pelo compilador conversão. Se eles não estiverem, você precisará alterar o parâmetro, de alguma forma, para passar os dados com um tipo com suporte.
  2. Se você passar qualquer estruturas como parâmetros, verifique se que você usar a mesma estrutura de remessa no DLL baseados em Win32, com base em Win16 DLL e script de conversão. Definir estrutura remessa na linha de comando do compilador C/C ++ e na linha de comando do compilador de conversão. Observe que a opção de remessa do compilador de conversão é para o lado de 16 bits, maiúsculas e minúsculas para o lado de 32 bits.
  3. Certifique-se que as funções que você está conversão para são exportadas corretamente e usam PASCAL chamar convenção se elas estiverem 16 bits ou _stdcall se elas estiverem 32 bits. O compilador de conversão não oferece suporte a _cdecl e __fastcall convenções de chamada.
  4. Certifique-se de que sua DLL baseados em Win32 chama ThunkConnect32() toda vez que sua função DllMain() é chamada. Da mesma forma, certifique-se que a DLL do Win16 tem uma função de DllEntryPoint() exportada, separada do seu LibMain(), que chama ThunkConnect16() e retorna VERDADEIRO se ThunkConnect16() for bem-sucedido.

    Observação : você realmente chamar XXX_ThunkConnect16() e XXX_ThunkConnect32() onde XXX é o símbolo definir com opção de -t do compilador de conversão. O código gerado pelo compilador conversão usa esses símbolos para gerar tabelas que chamam ThunkConnect16() e ThunkConnect32.
  5. Verifique se o valor especificado na opção de -t de linha de comando do compilador de conversão é o mesmo para o Win32 e DLLs de conversão de Win16. O valor também deve corresponder ao prefixo das chamadas ThunkConnect no suas DLLs de Win16 e Win32 (consulte a observação na etapa 4).
  6. Verifique se a DLL do Win16 tem DLLEntryPoint exportada com a palavra-chave RESIDENTNAME em seu arquivo de definição (.def) módulo. Sem a palavra-chave RESIDENTNAME, a chamada ThunkConnect32/ThunkConnect16 falhará e as DLLs não serão carregado.
  7. Verifique se a DLL de 16 bits tem XXX_ThunkData16 exportadas com a palavra-chave RESIDENTNAME em seu arquivo de definição (.def) módulo.
  8. Verifique no makefile do sua com base em Win16 DLL que o compilador de recurso é marcando a DLL como 4.0. Se ele estiver marcado menor 4.0, não é possível carregar e a conversão falhará.
  9. Se sua função de conversão de 32 bits para 16 bits retorna um ponteiro, certifique-se que o tipo base é o mesmo tamanho nos dois lados 16 e 32 bits da conversão. Se o tamanho do tipo base é diferente, o compilador de conversão emite uma mensagem de erro dizendo, "Não é possível retornar ponteiros para tipos não idênticos." Uma maneira de contornar esse problema é retornar um ponteiro para um tipo de dados diferentes, mas compatível. Por exemplo, uma conversão não pode retornar um ponteiro para um int porque um int é de dois bytes no lado 16 bits, mas quatro bytes no lado de 32 bits. Altere tipo de retorno da conversão de um ponteiro para um inteiro para um ponteiro para um longo no script conversão e o código-fonte das DLLs baseados em Win32 em Win16 e.

    Se você escrever uma conversão de 16 bits para 32 bits que retorna um ponteiro, o compilador de conversão emite uma mensagem de erro informando, "tipos ponteiro não podem ser retornados." O compilador de conversão não permite thunks de 16 bits para 32 bits retornar tipos ponteiro porque depois que a conversão foi retornado da função de 32 bits, o ponteiro não irá apontar para dados no espaço de endereço de processo baseados em Win32 correto. Isso ocorre porque os espaços de endereço de todos os processos baseados em Win32 usam os mesmos endereços intervalo e são preemptively comutação de contexto.
  10. Se o vinculador relata um erro "não resolvidos externo" e o símbolo é um nome de função que está escrito consistentemente em todo o código fonte, arquivos de definição de módulo e o script de conversão, certifique-se de que todas as ocorrências do seu protótipo são consistentes. No lado do Win32, a função de conversão deve ser declarada com o tipo de __stdcall; no lado do Win16, a função deve ser declarada com o tipo de PASCAL. Projetos do C++, não deixe de declarar e definir ambos os lados da função de conversão com o especificador de ligação extern "C" juntamente com o __stdcall ou o tipo de PASCAL.

Guia trouble-shooting - após a compilação com o compilador Thunk

Depois de verificar os preliminares, criar sua conversão DLLs e tente executá-los. Se eles são executados, continue com testes adicionais para Verifique se eles estiver desloque sólida. Se eles não funcionarem, use o guia de solução de problemas a seguir para determinar e corrigir a causa do problema.

ThunkConnect16() no Win16 ou ThunkConnect32() no lado Win32 falhar:

  1. Executar as versões de depuração do sistema DLLs. As versões de depuração do Kernel32.dll e KRNL386.exe contêm muitas mensagens de diagnóstico saber por que a conversão não foi inicializado. Para executar as versões de depuração do sistema DLLs, use o ícone "Alternar para depurar DLLs" no Menu Iniciar em ferramentas do Win32 SDK. Use "Switch a depuração não DLLs" para voltar para a versão comercial.
  2. Verifique se a DLL do Win16 tem uma chamada para ThunkConnect16() e DLL baseados em Win32 tem uma chamada correspondente para ThunkConnect32(). Se um deles estiver ausente, em seguida, o outro falhará e conversão DLLs falhará carregar.
  3. Coloque pontos de interrupção em DllMain() do sua DLL Win32, e em sua DLL Win16 DllEntryPoint() e LibMain() funções para ver quais DLLs não estão carregando.
Se as chamadas ThunkConnect16() e ThunkConnect32() estão funcionando corretamente, mas ainda não a conversão, é hora para simplificar sua conversão. Você realmente pode atacar isso de duas maneiras. Primeiro, inicie removendo parâmetros da conversão, uma a uma e recompilá-lo. Ou, em segundo lugar, crie uma conversão simples que funciona e compilá-lo até ele falhar, seguindo estas etapas:
  1. Crie uma conversão simples e executá-lo apenas para ter certeza que você possui o mecanismo de conversão configurado corretamente. Uma boa opção para uma conversão simples é uma função com nenhum valor de retorno e sem parâmetros. Se mesmo a conversão simples não funciona, execute por meio da lista de verificação preliminar acima para certificar se que você tem as coisas configuradas corretamente. Em seguida, continue com a etapa 2.
  2. Verifique se o destino DLL e quaisquer DLLs depende podem ser encontrados e carregados. Se um estiver faltando ou o carregador não é possível localizá-lo, a conversão não funcionará.
  3. Certifique-se a DLL não está fazendo algo que não é possível no contexto de uma conversão de destino.
Depois que você tem uma conversão simplificada que funciona, mas sua conversão real não funciona, execute estas etapas:
  1. Adicione parâmetros para a conversão simples, um por vez para determinar se um parâmetro está causando a falha. Se um estiver, certifique-se que o parâmetro é o tipo correto, que a função é declarada e definida com o mesmo número e tipos de parâmetros em ambas as DLLs e o compilador de conversão, e que a função é declarada como PASCAL ou _stdcall.
  2. Se sua DLL de destino for uma DLL Win16 com e ele não pode acessar seus dados globais ou estáticos, verifique se que você tiver exportado a função corretamente. Se você usar a opção /GD com o Visual C++, você deve declarar e define a função com a palavra-chave __export no código-fonte da DLL Win16 com. Apenas listar o nome da função no arquivo de definição (.def) de módulo da DLL não é suficiente porque o compilador não processa o arquivo .def, para que ele não irá gerar o prólogo e código de epilog exportadas funções requer.
  3. Se chamadas para LocalAlloc() em falhas de proteção geral (GP) seus destino com base em Win16 DLL causa, certifique-se de sua função será exportada como descrito na etapa 2.
  4. Se você receber uma falha de GP no Kernel32 logo após seu destino com base em Win16 função retorna, certifique-se a função de destino é declarada e definida como PASCAL. A convenção C de chamada não pode ser usada. Embora incomum no código C ou C++, mas provavelmente em linguagem assembly, certifique-se de que a função de destino não modificar os registros de DS, SS, BP, SI ou DI.
  5. Se você receber uma falha de GP no sua conversão de 32 bits DLL ou Kernel32 imediatamente após seu destino função retorna baseados em Win32, certifique-se que a função de destino é declarada como _stdcall e que ele não modifique os registradores de DS, ES, FS, SS, EBP, EBX, ESI ou EDI. Código C ou C++ não deve causar os registros a ser modificada, mas o código de linguagem assembly deve ser verificado cuidadosamente.
  6. Se seu Win16 baseada em função de destino retorna para um local inválido, certifique-se é declarada e definida como FAR. Isso é especialmente importante para modelo pequeno DLLs; funções em DLLs de médio e grande modelo são FAR por padrão.
  7. Se você tiver uma falha de diretiva de grupo em uma função com base em Win16 ao acessar mais de 64 K de dados de um ponteiro passado como um parâmetro (ou seja, um ponteiro thunked), você precisa alocar uma matriz de seletores lado a lado, como descrito no seguinte artigo na Base de dados de Conhecimento da Microsoft:
    132005DOCERR: AllocSelector & FreeSelector documentação incompletos
    No lado do Win16, ponteiros thunked sempre consistem de um seletor único com um limite de 64 K, o que significa que você não é possível usá-los como ponteiros enormes. Todo o intervalo original de dados que aborda o ponteiro está acessível a destino com base em Win16 DLL - mas somente se ele cria uma matriz de seletores lado a lado para fazer referência a ela, e se ele usa variáveis de ponteiro enorme para acessar os dados.
  8. Certificar-se que você usa somente um ponteiro thunked no contexto da conversão. Seletores alocados pelo compilador de conversão para uso por destinos com base em Win16 são liberados, assim que a conversão retorna.
  9. Coloque pontos de interrupção no início de suas funções de destino para verificar se que você estiver obtendo neles. Se você estiver e você tiver depurado o lado de destino independentemente da conversão e o erro é causado dentro do destino, as chances são bons o destino está fazendo algo que não pode ser feito em uma conversão ou referência de memória que não existe. Consulte as etapas 7 e 8.

Propriedades

ID do artigo: 133722 - Última revisão: segunda-feira, 11 de julho de 2005 - Revisão: 2.3
A informação contida neste artigo aplica-se a:
  • Microsoft Platform Software Development Kit-January 2000 Edition nas seguintes plataformas
    • Microsoft Windows 95
    • Microsoft Windows 98 Standard Edition
    • Microsoft Windows Millennium Edition
Palavras-chave: 
kbmt kbhowto kbkernbase kbprogramming KB133722 KbMtpt
Tradução automática
IMPORTANTE: Este artigo foi traduzido por um sistema de tradução automática (também designado por Machine Translation ou MT), não tendo sido portanto traduzido ou revisto por pessoas. A Microsoft possui artigos traduzidos por aplicações (MT) e artigos traduzidos por tradutores profissionais, com o objetivo de oferecer em português a totalidade dos artigos existentes na base de dados de suporte. No entanto, a tradução automática não é sempre perfeita, podendo conter erros de vocabulário, sintaxe ou gramática. A Microsoft não é responsável por incoerências, erros ou prejuízos ocorridos em decorrência da utilização dos artigos MT por parte dos nossos clientes. A Microsoft realiza atualizações freqüentes ao software de tradução automática (MT). Obrigado.
Clique aqui para ver a versão em Inglês deste artigo: 133722

Submeter comentários

 

Contact us for more help

Contact us for more help
Connect with Answer Desk for expert help.
Get more support from smallbusiness.support.microsoft.com