Como depurar Thunks plano

Traduções de Artigos Traduções de Artigos
Artigo: 133722 - Ver produtos para os quais este artigo se aplica.
Expandir tudo | Reduzir tudo

Nesta página

Sumário

Depuração simples thunks gerados pelo compilador thunk pode ser difícil porque o mecanismo de thunk é complexo e ferramentas de depuração capazes de rastreio através de thunks são difíceis de utilizar. Este artigo apresenta uma estratégia global para depuração thunks simples, várias técnicas de depuração específicas e uma guia de resolução de problemas que explica como resolver muitos problemas thunking comuns.

Mais Informação

Limitações em que um destino DLL pode fazer

Antes de começar a depurar thunks, tenha em mente que existem algumas limitações que um destino DLL fazer dentro de um thunk. Esta é uma vez que uma aplicação baseada no Win16 chamar uma DLL baseadas no Win32 não é um processo baseado no Win32; do mesmo modo, uma aplicação baseada no Win32 chamar uma DLL baseada em Win16 não é um processo baseado em Win16. Limitações específicas comuns incluem:

  • Não pode criar threads dentro de um thunk a partir de uma aplicação baseada no Win16 para uma DLL baseadas em Win32.
  • O código dentro de DLLs baseadas no Win32 chamado pelo thunks deverão requerer espaço na pilha pouco porque os processos baseados em Win16 chamados tem pilhas muito mais pequenas do que as aplicações baseadas em Win32.
  • Dll Win16 baseadas em com rotinas de serviço de interrupção (ISRs) não tem thunk para as DLLs baseadas no Win32 ao processar interrupções.
  • Aplicações baseadas no Win32 não tem de passar os ponteiros para dados localizados na pilha como parâmetros de thunks ou chamada de dll com Win16 mudar as pilhas.

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

Depuração thunks simples é difícil parcialmente porque o mecanismo de thunk simples é uma parte complexa do kernel do Windows. Caules a complexidade de facto tem transformar chamadas de função num código compilado de 32 bits para chamadas compatível com o código de 16 bits e vice-versa. Porque o código de 32 bits utiliza diferentes tipos de dados e da CPU registar conjuntos do código de 16 bits, o mecanismo simples thunk tem converter parâmetros de função, mude pilhas e converter valores de retorno. É optimizado para a velocidade, mas tem de permitir preemptive Win32 chamar não preemptive código Win16. O compilador thunk facilita thunks simples criar muito do que criar manualmente, mas não é infalível.

Depuração thunks simples é difícil não só porque o mecanismo propriamente dito é complexo, mas também uma vez que as ferramentas de depuração necessárias são mais difíceis de dominar. Nível da aplicação depuradores, tais como o depurador do Microsoft Visual C++ e WinDBG não é possível rastrear a thunks uma vez que consistem em código de 32 bits e 16 bits e fazer com que o sistema pedir ou libertar o Win16Mutex. Para rastrear através de um thunk, terá de utilizar um depurador de nível do sistema como, por exemplo, WDEB386.EXE. Desvantagens principais utilizar WDEB386.EXE são que é necessário conhecer linguagem de assemblagem Intel x 86, sabe como funcionam os microprocessadores Intel x 86, lembre- se muitos comandos o depurador.

A estratégia de procedimentos para utilizar

A melhor estratégia para depuração thunks é divida e Conquiste porque é relativamente fácil e elimina a maior parte dos problemas antes de que pretende pesquisar a código de linguagem assembly um depurador de nível do sistema. Thunks simples são compostos por uma DLL baseadas no Win32 e DLL Win16 com, por isso, é possível testar cada um no isolamento antes de testá-las em conjunto. Criar uma aplicação baseada no Win16 para testar a DLL de Win16 e criar uma aplicação baseada no Win32 para testar a DLL baseadas em Win32. Se o fizer, permite utilizar uma grande variedade de ferramentas de depuração para verificar se cada lado funciona correctamente.

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

Depois de ter verificado que cada lado funciona correctamente, é altura de colocar as duas em conjunto para testar o thunk propriamente dito. Antes de compilar thunk com o compilador thunk, efectue uma verificação preliminar dos seguintes itens:
  1. No script thunk, certifique-se que cada função tem o número correcto e tipos de parâmetros. Certifique-se de que os tipos de parâmetro são suportados pelo compilador thunk também de. Se não, terá de alterar o parâmetro de alguma forma para transmitir os dados com um tipo suportado.
  2. Se passar estruturas como parâmetros, certifique-se que utiliza a mesma estrutura de remessa na DLL baseadas no Win32, baseado em Win16 DLL e thunk script. Definir estrutura de embalagem na linha de comandos do compilador C/C ++ e na linha de comandos thunk compilador. Note que embalagem parâmetro o compilador thunk é 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 está a thunking para são exportadas correctamente e utilizam PASCAL chamar convenção se estiverem 16-bit ou _stdcall se estiverem 32 bits. O compilador thunk não suporta o _cdecl e __fastcall convenções de chamada.
  4. Certifique-se de que a DLL baseadas no Win32 chama ThunkConnect32() sempre que denomina-se a função DllMain(). Do mesmo modo, certifique-se que a DLL de Win16 tem uma função de DllEntryPoint() exportada, separada do respectivo LibMain() que chama ThunkConnect16() e devolve VERDADEIRO se ThunkConnect16() com êxito.

    Nota : É realmente chamar XXX_ThunkConnect16() e XXX_ThunkConnect32() onde XXX é o símbolo que definir com -t parâmetro o compilador thunk. O código gerado pelo compilador thunk utiliza estes símbolos para criar tabelas chamar ThunkConnect16() e ThunkConnect32.
  5. Certifique-se que o valor especificado no parâmetro -t do compilador thunk linha de comandos está o mesmo para o Win32 e Win16 thunk dll. O valor também tem de corresponder para o prefixo de chamadas de ThunkConnect in as DLL baseado em Win16 e baseadas em Win32 (consulte a nota no passo 4).
  6. Verifique se a DLL Win16 baseadas em tem DLLEntryPoint exportada com a palavra-chave RESIDENTNAME no respectivo ficheiro de definição (.def) do módulo. Sem a palavra-chave RESIDENTNAME chamada ThunkConnect32/ThunkConnect16 falhará e as DLL não serão carregado.
  7. Verifique se a DLL de 16 bits tem XXX_ThunkData16 exportadas com a palavra-chave RESIDENTNAME no respectivo ficheiro de definição (.def) do módulo.
  8. Verifique na makefile a DLL de Win16 baseadas em que o compilador de recurso está a marcar a DLL como 4.0. Se estiver marcado menos 4.0, não é possível carregar e a thunk falhará.
  9. Se a função de 32 bits para 16 bits thunk devolve um ponteiro, certifique-se de que o tipo base é o mesmo tamanho nos dois lados 16-bit e 32 bits do thunk. Se o tamanho do tipo base for diferente, em seguida, o compilador thunk emite uma mensagem de erro indicar, "Não é possível regressar ponteiros para tipos não idênticos." Uma forma de contornar este problema é para repor um ponteiro de um tipo de dados diferentes, mas compatível. Por exemplo, um thunk não é possível devolver um ponteiro para um inteiro porque um int é dois bytes no lado 16 bits, mas quatro bytes do lado de 32 bits. Altere tipo de retorno do thunk de um ponteiro para um inteiro para um ponteiro para uma longa no script thunk e o código das DLLs baseado em Win16 e baseadas em Win32.

    Se escrever um thunk de 16 bits para 32 bits que devolve um ponteiro, o compilador thunk emite uma mensagem de erro a indicar, "não podem ser devolvidos tipos de ponteiro." O compilador thunk não permite thunks 16-bit para 32 bits para tipos de ponteiro de retorno porque depois do thunk devolveu da função de 32 bits, o ponteiro vai não apontam para dados no espaço de endereço correcta processo baseado no Win32. Isto acontece porque os espaços de endereço de todos os processos baseadas no Win32 utilizam os mesmos intervalo de endereços e são preemptively mudou de contexto.
  10. Se o linker comunica um erro "não resolvidos externa" e o símbolo é um nome de função que está escrito consistente ao longo de todo o código fonte, ficheiros de definição do módulo e o script thunk, certifique-se de que todas as ocorrências do respectivo protótipo são consistentes. No lado do Win32, a função thunk deve ser declarada com o tipo de __stdcall; no lado Win16, a função deve ser declarada com o tipo de PASCAL. Nos projectos do C++, não se esqueça declarar e definir ambos os lados da função thunk com o especificador de ligação de "C" externo juntamente com o __stdcall ou o tipo PASCAL.

Guia trouble-Shooting - depois de compilar com o compilador Thunk

Depois de verificar os preliminaries, criar a dll thunk e tentar executá-los. Se são executadas, continue com mais testes para garantir que está a rock sólida. Se não executar, utilize o guia de resolução de problemas seguinte para determinar e corrigir a causa do problema.

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

  1. Versões de depuração do sistema dll. As versões de depuração do Kernel32.dll e KRNL386.exe contêm muitas mensagens de diagnóstico para indicar o thunk não foi inicializado. Para executar as versões de depuração da DLL de sistema, utilize o ícone "Mudar para depurar DLLs" no menu ' Iniciar ' em Ferramentas do Win32 SDK. Utilizar "Mudar para a depuração não dll" para voltar para a versão de revenda.
  2. Verifique se a DLL de Win16 tem uma chamada para ThunkConnect16() e DLL baseadas no Win32 tem uma chamada correspondente para ThunkConnect32(). Se um destes estiver em falta, em seguida, o outro falhará e não será possível carregar a dll thunk.
  3. Coloque pontos de interrupção na DllMain() a DLL Win32 e o DLL Win16 DllEntryPoint() e LibMain() funções para ver as DLL não são carregados.
Se as chamadas ThunkConnect16() e ThunkConnect32() estão a funcionar correctamente, mas ainda não o thunk, é necessário simplificar o thunk. Na realidade podem atacar isto de duas formas. Em primeiro lugar, comece por remover parâmetros a thunk individualmente e recompilá-lo. Ou, em segundo lugar, crie um thunk simples que funciona e constroem cima até falhar, seguindo estes passos:
  1. Crie um thunk simples e executá-la apenas para se certificar que tem o mecanismo de thunk configurado correctamente. Uma boa escolha para um thunk simples é uma função com nenhum valor de retorno e sem parâmetros. Se ainda o thunk simples não funcionar, execute a lista de verificação preliminar acima para garantir que tem coisas configuradas correctamente. Em seguida, avance para o passo 2.
  2. Certifique-se o destino DLL e qualquer dll baseia-se no podem ser encontradas e carregadas. Se um estiver em falta ou o carregador não é possível localizá-lo, o thunk não funcionará.
  3. Certifique-se a DLL não está a fazer algo que não é possível no contexto de um thunk de destino.
Quando tiver um thunk simplificada que funciona, mas o thunk real ainda não funciona, siga estes passos:
  1. Adicione parâmetros para o thunk simples um de cada vez para determinar se um parâmetro está a causar a falha. Se existir, certifique-se que o parâmetro é do tipo correcto, que a função é declarada e definida com o mesmo número e tipos de parâmetros de ambas as DLLs e de compilador thunk, e que a função é declarada como PASCAL ou _stdcall.
  2. Se a DLL de destino é uma DLL baseada em Win16 e não consegue aceder respectivos dados globais ou estáticos, certifique-se de que exportou a função correctamente. Se utilizar o parâmetro /GD com o Visual C++, tem de declarar e definir a função com a palavra-chave __export no código de origem a DLL de baseado em Win16. Listar apenas nome da função no ficheiro de definição (.def) do módulo a DLL não é suficiente porque o compilador não vai processar o ficheiro .def, para não gerar a lógica de programação e código de epilog exportados funções requerem.
  3. Se as chamadas para LocalAlloc() em falhas de protecção geral (GP) da destino DLL Win16 baseadas em causa, certifique-se a função é exportada conforme descrito no passo 2.
  4. Se obtiver um erro de política de grupo em KERNEL32 apenas depois do destino Win16 baseadas em função devolve, certifique-se a função de destino é declarada e definida como PASCAL. É possível utilizar a convenção de chamada C. Embora comuns no código C ou C++, mas o mais provável na linguagem de assemblagem, certifique-se de que a função de destino não modificar os registos de DS, II, BP, SI ou DI.
  5. Se obtiver um erro de política de grupo em thunk a 32 bits DLL ou KERNEL32 imediatamente após a função devolve baseadas no Win32 destino, certifique-se que a função de destino é declarada como _stdcall e que não modifique os registos de DS, ES, FS, II, EBP, EBX, ESI ou EDI. Código C ou C++ não deverá causar os registos sejam modificados, mas o código de linguagem assembly deve ser verificado cuidadosamente.
  6. Se o Win16 baseadas em função de destino devolve para uma localização inválida, certifique-se é declarado e definido como FAR. Isto é especialmente importante para pequeno modelo de dll; funções em DLLs de modelo médias e grandes são FAR por predefinição.
  7. Se ocorrer uma falha de política de grupo no quando acede a uma função Win16 baseadas em mais do que 64 K de dados de um apontador transmitido como um parâmetro (ou seja, um ponteiro thunked), necessita de atribuir uma matriz de selectores em mosaico, como descrito no seguinte artigo na base de dados de conhecimento da Microsoft:
    132005DOCERR: AllocSelector & FreeSelector documentação incompletos
    No lado Win16, ponteiros thunked sempre consistem num selector único com um limite de 64 K, o que significa que não é possível utilizar como ponteiros grandes. O intervalo de dados que o ponteiro resolve completo original é acessível a destino baseados em Win16 DLL - mas apenas se cria uma matriz de selectores em mosaico para referenciá-lo e se utiliza ponteiro grande variáveis para aceder aos dados.
  8. Certifique-se que apenas utiliza um ponteiro thunked no contexto do utilizador a thunk. Selectores atribuídas pelo compilador thunk para utilização por Win16 baseadas em destinos são libertados assim o thunk devolve.
  9. Colocar pontos de quebra no início das funções de destino para garantir que está a obter nas mesmas. Se estiver e ter depurado lado independentemente do thunk destino e o erro é provocado dentro de destino, hipóteses são boas que o destino é fazer algo que não pode ser desenvolvida num thunk ou fazer referência a memória que não existe. Consulte os passos 7 e 8.

Propriedades

Artigo: 133722 - Última revisão: 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 revisto ou traduzido por humanos. A Microsoft tem artigos traduzidos por aplicações (MT) e artigos traduzidos por tradutores profissionais. O objectivo é simples: oferecer em Português a totalidade dos artigos existentes na base de dados do suporte. Sabemos no entanto que a tradução automática não é sempre perfeita. Esta pode conter erros de vocabulário, sintaxe ou gramática? erros semelhantes aos que um estrangeiro realiza ao falar em Português. A Microsoft não é responsável por incoerências, erros ou estragos realizados na sequência da utilização dos artigos MT por parte dos nossos clientes. A Microsoft realiza actualizações frequentes 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