Comment faire pour déboguer les thunks plats

Traductions disponibles Traductions disponibles
Numéro d'article: 133722 - Voir les produits auxquels s'applique cet article
Agrandir tout | Réduire tout

Sommaire

Résumé

Débogage des thunks plats générés par le compilateur thunk peut être difficile car le mécanisme de thunk est complexe et outils de débogage capables de suivre les thunks sont difficiles à utiliser. Cet article présente une stratégie globale pour le débogage des thunks plats, plusieurs techniques de débogage spécifiques et un guide de dépannage qui explique comment résoudre de nombreux problèmes courants de mécanisme de thunk.

Plus d'informations

Limitations relatives à ce que peut faire une cible de DLL

Avant de commencer à déboguer les thunks, gardez à l'esprit qu'il existe certaines limitations sur ce qu'une cible DLL pouvez le faire à l'intérieur d'un thunk. Cela est dû au fait qu'une application Win16 appelant une DLL Win32 n'est pas un processus Win32 ; de même, une application Win32 appelant une DLL Win16 n'est pas un processus Win16. Limitations spécifiques courantes sont les suivantes :

  • Vous ne pouvez pas créer de threads à l'intérieur d'un thunk à partir d'une application Win16 en une DLL Win32.
  • Le code dans les DLL Win32 appelée par thunks doit nécessiter d'espace pile peu car les processus appelant Win16 ont beaucoup plus petites de piles que les applications Win32.
  • DLL Win16 qui contiennent des routines de service d'interruption (ISR) devez thunk pas aux DLL Win32 lors du traitement des interruptions.
  • Applications Win32 doivent passer pas des pointeurs à situé sur la pile en tant que paramètres de thunks ou appel de DLL Win16 basculer les piles de données.

Pourquoi le débogage des thunks plats peut être difficile

Il est difficile de déboguer les thunks plats en partie parce que le mécanisme de thunk plat est une partie du noyau Windows complexe. Son radicaux de complexité du fait qu'il doit transformer des appels de fonction dans le code compilé de 32 bits dans appelle compatible avec le code 16 bits et vice versa. Étant donné que code 32 bits utilise différents types de données et processeur inscrire jeux à partir de code 16 bits, le mécanisme de thunk plat doit traduire les paramètres de fonction, changer les piles et traduisez les valeurs de retour. Il est optimisé pour la vitesse, mais doit autoriser préemptif code Win32 appeler du code de Win16 non préemptif. Le compilateur thunk rend la création de thunks plats beaucoup plus facile que de les créer manuellement, mais il n'est pas infaillible.

Débogage des thunks plats difficile n'est pas uniquement car le mécanisme lui-même est complexe, mais également dans la mesure où les outils de débogage nécessaires sont plus difficiles à maîtriser. Au niveau de l'application débogueurs telles que le débogueur Microsoft Visual C++ et WinDBG ne peut pas retrouver par le biais de thunks, car ils sont constitués de code 32 bits et 16 bits et pousser le système demander ou de libérer le Win16Mutex. Effectuer le suivi par l'intermédiaire d'un thunk, vous devez utiliser un débogueur au niveau du système, tel que WDEB386.EXE. Les principaux inconvénients à l'utilisation de WDEB386.EXE sont que vous devez connaître le langage assembleur de Intel x 86, connaître le fonctionnement des microprocesseurs Intel x 86 et n'oubliez pas de nombreuses commandes du débogueur.

La stratégie de méthodes à utiliser

La meilleure stratégie pour le débogage des thunks consiste à diviser pour mieux régner car est relativement facile et élimine la plupart des problèmes que vous devez suivre le code de langue de l'assembly dans un débogueur au niveau du système. Thunks plats sont composés d'une DLL Win32 et une DLL Win16, il est possible de tester chacune d'elles de manière isolée avant de les tester ensemble. Créez une application Win16 pour tester la DLL Win16 et créer une application Win32 pour tester la DLL Win32. Cela vous permet d'utiliser une grande variété d'outils de débogage pour vérifier le bon fonctionne de chaque côté.

Liste de vérification préliminaire - avant la compilation à l'aide du compilateur de thunks

Une fois que vous avez vérifié que chaque côté fonctionne correctement, il est temps de mettre les deux ensemble pour tester le thunk lui-même. Avant de compiler le thunk avec le compilateur de thunk, effectuez une vérification préliminaire des éléments suivants :
  1. Dans votre script de thunk, assurez-vous que chaque fonction est le nombre correct et les types de paramètres. Assurez-vous également que les types de paramètres sont pris en charge par le compilateur de thunk. Si elles ne sont pas, vous devrez peut-être modifier le paramètre une certaine manière pour transmettre les données avec un type pris en charge.
  2. Si vous passez des structures en tant que paramètres, vérifiez que vous utilisez la même structure de livraison dans votre DLL Win32 DLL Win16 et script de thunk. Vous définissez la structure livraison dans la ligne de commande de votre compilateur C/C++ et dans la ligne de commande du compilateur thunk. Notez que le commutateur de livraison du compilateur thunk est en minuscules pour le côté 16 bits et de lettres majuscules pour le côté 32 bits.
  3. Assurez-vous que les fonctions que vous êtes médiateur à sont exportées correctement et utilisent le PASCAL appel convention si elles sont 16 bits ou _stdcall si elles sont 32 bits. Le compilateur thunk ne prend pas en charge les _cdecl et __fastcall conventions d'appel.
  4. Assurez-vous que votre DLL Win32 appelle ThunkConnect32() chaque fois que sa fonction DllMain() est appelée. De même, assurez-vous que la DLL Win16 dispose d'une fonction DllEntryPoint() exportée, séparée de son LibMain(), qui appelle ThunkConnect16() et renvoie VRAI si ThunkConnect16() réussit.

    Remarque : vous en fait appelez XXX_ThunkConnect16() et XXX_ThunkConnect32() où XXX est le symbole vous définissez à l'aide t - commutateur du compilateur thunk. Le code généré par le compilateur thunk utilise ces symboles pour générer des tables qui appellent ThunkConnect16() et ThunkConnect32.
  5. Assurez-vous que la valeur spécifiée dans le commutateur -t de ligne de commande du compilateur thunk est le même pour les DLL de thunk Win16 et Win32. La valeur doit également correspondre au préfixe des appels de ThunkConnect dans votre DLL Win16 et Win32 (voir la remarque dans l'étape 4).
  6. Vérifiez que la DLL Win16 DLLEntryPoint exportée avec le mot clé RESIDENTNAME dans son fichier de définition (.def) de module. Sans le mot clé RESIDENTNAME, l'appel ThunkConnect32/ThunkConnect16 échouera et les DLL ne seront pas chargé.
  7. Vérifiez que la DLL 16 bits a XXX_ThunkData16 exportées avec le mot clé RESIDENTNAME dans son fichier de définition (.def) de module.
  8. Dans votre DLL Win16 makefile, vérifiez que le compilateur de ressources est marquage de la DLL comme 4.0. Si elle est marquée inférieures à 4.0, il ne peut pas être chargée et le thunk échouera.
  9. Si votre fonction de thunk 32 bits à 16 bits renvoie un pointeur, assurez-vous que le type de base est la même taille sur les côtés 16 bits et 32 bits du thunk. Si la taille du type de base est différente, le compilateur de thunk émet un message d'erreur indiquant, «Ne peut pas renvoyer des pointeurs aux types non-identical.» La première pour contourner ce problème consiste à retourner un pointeur vers un type de données différents, mais compatible. Par exemple, un thunk ne peut pas retourner un pointeur à un int int étant deux octets sur le côté 16 bits, mais les quatre octets sur le côté 32 bits. Modifier le type de retour du thunk à partir d'un pointeur en int en un pointeur vers un type long dans le script de thunk et le code source des DLL Win16 et Win32.

    Si vous écrivez un thunk 16 bits en 32 bits qui retourne un pointeur, le compilateur thunk émet un message d'erreur indiquant, «types pointeur ne peuvent pas être retournés.» Le compilateur thunk n'autorise pas les thunks de 16 bits en 32 bits renvoyer les types pointeur car une fois que le thunk a retourné à partir de la fonction 32 bits, le pointeur ne pointera pas vers les données dans l'espace d'adressage de processus basés sur Win32 approprié. Cela est dû au fait que les espaces d'adressage de tous les processus basés sur Win32 utilisent les mêmes adresses de plage et sont preemptively commutation de contexte.
  10. Si l'éditeur de liens signale une erreur «non résolus externe» et le symbole est un nom de la fonction orthographe cohérente dans tout le code source, fichiers de définition de module et le script de thunk, assurez-vous que toutes les occurrences de son prototype sont cohérentes. Dans la partie Win32, la fonction de thunk doit être déclarée avec le type de __stdcall ; côté Win16, la fonction doit être déclarée avec le type PASCAL. Dans les projets C++, veillez à déclarer et définir les deux côtés de la fonction de thunk avec le spécificateur de liaison extern "C" parallèlement à la __stdcall ou le type PASCAL.

Guide de dépannage - après la compilation à l'aide du compilateur de thunks

Une fois que vous avez vérifié les preliminaries, générez votre DLL de thunk et essayez de les exécuter. Si leur exécution, passez à test supplémentaire pour vous assurer qu'ils vous rock unie. Si elles ne s'exécute, utilisez le guide de dépannage suivant pour déterminer et corriger la cause du problème.

ThunkConnect16() Win16 ou ThunkConnect32() dans la partie Win32 échoue :

  1. Exécutez les versions de débogage de DLL du système. Les versions de débogage de Kernel32.dll et Krnl386.exe contiennent de nombreux messages de diagnostics pour vous indiquer pourquoi le thunk n'a pas été initialisé. Pour exécuter les versions de débogage de DLL du système, utilisez l'icône «Changer de DLL à déboguer» dans le Menu Démarrer sous Outils du Kit de développement Win32 SDK. Utilisez le commutateur"aux DLL de débogage non» pour revenir à la version commerciale.
  2. Vérifiez que la DLL Win16 possède un appel à ThunkConnect16() et la DLL Win32 a un appel correspondant à ThunkConnect32(). Si une d'entre elles est manquante, puis l'autre échoue et la DLL de thunk ne parviendra pas à charger.
  3. Placez des points d'arrêt dans votre DLL Win32 DllMain() et dans votre DLL Win16 DllEntryPoint() et LibMain() fonctions pour voir quelles DLL sont n'est pas chargé.
Si vos appels ThunkConnect16() et ThunkConnect32() fonctionnent correctement, mais le thunk n'est pas toujours, il est temps pour simplifier votre thunk. Vous pouvez l'attaquer réellement de deux manières. Tout d'abord, commencez par supprimer les paramètres de thunk un par un et en recompilant il. Ou, en second lieu, créer un thunk simple qui fonctionne et générez-le jusqu'à ce que l'échec en procédant comme suit :
  1. Créer un thunk simple et exécutez-la juste pour vous assurer que vous avez le mécanisme de thunk correctement configuré. Un bon choix pour un thunk simple est une fonction avec aucune valeur de retour et sans paramètres. Si même le thunk simple ne fonctionne pas, exécuter par le biais de la liste de vérification préliminaire ci-dessus pour vous assurer que vous avez des choses correctement configurés. Puis passez à étape 2.
  2. Vérifiez que la DLL cible et toutes les DLL elle dépend peuvent être trouvés et chargés. Si elle est manquante ou si le chargeur ne trouve pas, le thunk ne fonctionnera pas.
  3. Assurez-vous que votre cible que DLL n'est pas chose qui il ne peut pas dans le contexte d'un thunk.
Une fois que vous avez un thunk simplifié qui fonctionne, mais votre thunk réel ne fonctionne toujours pas, procédez comme suit :
  1. Ajouter des paramètres vers le thunk simple une à la fois pour déterminer si un paramètre est à l'origine de l'échec. Si un est le cas, assurez-vous que le paramètre type est correct, que la fonction est déclarée et définie avec le même nombre et les types de paramètres dans les deux DLL et dans le compilateur thunk, et que la fonction est déclarée en tant que PASCAL ou _stdcall.
  2. Si votre DLL cible est une DLL Win16 et il ne peut pas accéder à ses données globales ou statiques, vérifiez que vous avez la fonction exportée correctement. Si vous utilisez le commutateur /GD avec Visual C++, vous devez déclarer et définir la fonction avec le mot clé __export dans code source de la DLL Win16. Venez répertoriant le nom de la fonction dans le fichier de définition (.def) de module de DLL est insuffisante, car le compilateur ne traite pas le fichier .def, donc il ne génère le prologue et nécessitent du code d'épilogue fonctions exportées.
  3. Si les appels à LocalAlloc() dans vos erreurs de protection générale (GP) cible DLL Win16 cause, assurez-vous que votre fonction est exportée comme décrit dans l'étape 2.
  4. Si vous obtenez une erreur GP dans Kernel32 juste après votre retours de fonction Win16 cible, assurez-vous que la fonction cible est déclarée et définie en tant que PASCAL. La convention d'appel C ne peut pas être utilisée. Bien que rare dans le code C ou C++, mais plus probablement dans un langage assembleur, assurez-vous que la fonction cible n'a pas modifier les registres DS, SS, BP, SI ou DI.
  5. Si vous obtenez une erreur GP dans votre thunk 32 bits DLL ou Kernel32 immédiatement après votre fonction retourne basés sur Win32 cible, assurez-vous que la fonction cible est déclarée comme _stdcall et qu'il n'a pas de modifier les registres DS, ES, FS, SS, EBP, EBX, ESI ou EDI. Code C ou C++ ne devrait pas provoquer d'historiques à être modifié, mais le code en langage assembleur doit être vérifié avec soin.
  6. Si votre Win16 fonction cible retourne à un emplacement non valide, assurez-vous qu'il est déclaré et défini comme étant de FAR. Ceci est particulièrement important pour les DLL de petit modèle, les fonctions des DLL de modèle de grandes et moyennes sont FAR par défaut.
  7. Si vous rencontrez une erreur GP une fonction Win16 lorsque vous accédez à plus de 64 Ko de données à partir d'un pointeur passé en tant que paramètre (c'est-à-dire, un pointeur thunked), vous devez allouer un tableau des sélecteurs en mosaïque, comme décrit dans l'article suivant dans la base de connaissances Microsoft :
    132005DOCERR : AllocSelector & FreeSelector Documentation incomplets
    Sur le côté Win16, pointeurs thunked toujours consistent un sélecteur unique avec une limite de 64 Ko, ce qui signifie que vous ne pouvez pas les utiliser en tant que pointeurs énormes. L'intégralité de la plage de données qui résout le pointeur d'origine est accessible à la cible de Win16 DLL - mais uniquement si elle crée un tableau des sélecteurs en mosaïque pour y faire référence, et si elle utilise des variables de pointeur énorme pour accéder aux données.
  8. Assurez-vous que vous utilisez uniquement un pointeur thunked dans le contexte du thunk. Sélecteurs allouées par le compilateur de thunk pour une utilisation par Win16 cibles sont libérées dès que le thunk renvoie.
  9. Placez des points d'arrêt au début de vos fonctions cible pour vous assurer que vous obtenez des informations. Si vous êtes, vous avez débogué indépendamment du thunk côté cible et l'erreur est due à l'intérieur de la cible, puis chances sont de bonne qualités que la cible est de faire quelque chose qui ne peut pas être effectuée dans un thunk ou faisant référence à la mémoire qui n'existe pas. Consultez les étapes 7 et 8.

Propriétés

Numéro d'article: 133722 - Dernière mise à jour: lundi 11 juillet 2005 - Version: 2.3
Les informations contenues dans cet article s'appliquent au(x) produit(s) suivant(s):
  • Microsoft Platform Software Development Kit-January 2000 Edition sur le système suivant
    • Microsoft Windows 95
    • Microsoft Windows 98 Standard Edition
    • Microsoft Windows Millennium Edition
Mots-clés : 
kbmt kbhowto kbkernbase kbprogramming KB133722 KbMtfr
Traduction automatique
IMPORTANT : Cet article est issu du système de traduction automatique mis au point par Microsoft (http://support.microsoft.com/gp/mtdetails). Un certain nombre d?articles obtenus par traduction automatique sont en effet mis à votre disposition en complément des articles traduits en langue française par des traducteurs professionnels. Cela vous permet d?avoir accès, dans votre propre langue, à l?ensemble des articles de la base de connaissances rédigés originellement en langue anglaise. Les articles traduits automatiquement ne sont pas toujours parfaits et peuvent comporter des erreurs de vocabulaire, de syntaxe ou de grammaire (probablement semblables aux erreurs que ferait une personne étrangère s?exprimant dans votre langue !). Néanmoins, mis à part ces imperfections, ces articles devraient suffire à vous orienter et à vous aider à résoudre votre problème. Microsoft s?efforce aussi continuellement de faire évoluer son système de traduction automatique.
La version anglaise de cet article est la suivante: 133722
L'INFORMATION CONTENUE DANS CE DOCUMENT EST FOURNIE PAR MICROSOFT SANS GARANTIE D'AUCUNE SORTE, EXPLICITE OU IMPLICITE. L'UTILISATEUR ASSUME LE RISQUE DE L'UTILISATION DU CONTENU DE CE DOCUMENT. CE DOCUMENT NE PEUT ETRE REVENDU OU CEDE EN ECHANGE D'UN QUELCONQUE PROFIT.

Envoyer des commentaires

 

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