Puis-je définir le débogueur Visual Studio pour casser la création de fil? P>
(Notez que ce n'est pas la même chose que la rupture de l'interrupteur de contexte, comme demandé dans cette autre question: Puis-je définir un point d'arrêt dans Visual Studio (C ++) pour casser sur un interrupteur de contexte de fil? ) P >
6 Réponses :
Oui, le débogueur obtient une notification pour cela. Non, l'interface utilisateur ne vous permet pas de le dire de casser cette notification. Si tel est pour le code géré, vous pouvez utiliser l'échantillon MDBG et la modifier. P>
Vous pouvez définir un point d'arrêt au premier appel à créatethread code> (peut-être que vous insérez un faux appel à cet effet).
Lorsqu'il est touché, changez de la vue Code source en vue de la vue de désassser et entrez dans l'appel. Parcourez le code ImportLib et définissez un point d'arrêt. Pas parfait, mais ça marche. P>
Si vous savez que le thread est créé par la classe de thread gérée, une solution simple serait de mettre un point d'arrêt sur son entrée (en allant à la fenêtre des points d'arrêt, cliquez sur Nouveau-> Pause en fonction de la fonction et de marquage. Start. ). p>
Sinon, comme l'a dit HANS, vous devriez utiliser une solution plus complexe comme MDBG ou utiliser une implémentation open source du profileur CLR (comme SAE ) et mettre une instruction" ASM INT 3 "dans l'ICORPROFILERCallback :: méthode filetée. p>
En outre, si vous avez la VS2010 Ultimate, vous pouvez simplement rechercher l'événement de fil créé dans IntelliTrace Events et éventuellement obtenir les informations dont vous avez besoin de là (bien que cela ne casse pas lorsque le thread est créé, mais cela vous donnera plutôt Info sur la trace de la pile / Valeurs variables au moment de sa création, dans Retrospect). P>
Un indice associé est qu'entrer dans une boîte à outils à points d'arrêt (Ctrl + Alt + B), frapper Ajoutez un point d'arrêt et en tapant Foo.foo (où FOO est un nom de classe, comme le filetage ou le travail d'arrière-plan), il mettrait des points d'arrêt sur tous les constructeurs de FOO .
Il suffit d'ajouter un point d'arrêt pour thread.start code> dès que mon application a commencé, vs l'a attrapé. Ensuite, je n'avais aucun moyen de reprendre et à chaque fois que j'ai cliqué sur VS2010, cela me dirait que cela attend un processus. Point étant, n'ajoutez pas le point d'arrêt tant que votre application ne commence.
J'ai trouvé un moyen de le faire. Alors que Googling j'ai vu la question opposée: Est-il possible de casser la sortie de fil avec code d'erreur spécifique? p>
i Mettez un point d'arrêt à la fonction rtlexituserthread code>, après avoir réalisé que tous les threads créaient avec la fonction rtluserthreadstart code>, alors mettez donc un autre point d'arrêt à cette fonction et c'est tout :) p>
Cela vous dérangerait-il d'élaborer comment exactement b> vous "mettez un point d'arrêt à la fonction rtluserthreadstart"? Je semble être incapable de mettre des points d'arrêt sur les fonctions de DLL internes Windows Même avec des techniques expliquées dans d'autres postes.
Dans Visual Studio, dans la fenêtre Points d'arrêt (débogage / Windows / Points d'arrêt ou Alt + F9), vous pouvez définir des points d'arrêt sur les symboles de fonctions. Cliquez sur "Nouveau" / "Point d'arrêt des fonctions ..." ou Ctrl + B dans la fenêtre Points d'arrêt et entrez le nom de la fonction dans la boîte de dialogue, dans ce cas, rtluserthreadstart. Pour moi, cela fonctionne même sans chargement de symboles Microsoft NTDLL.PDB.
Ok c'est impair. J'ai des exportations et des symboles activés et je n'ai jamais fait un point d'arrêt sur rtluserthreadstart code> hit ... J'étais cependant capable de trouver la signature de stdcall de celui-ci que le débogueur rompt avec succès. Aussi kudos à Visual Studio pour ne pas donner de message d'erreur lorsque la création d'un nouveau point d'arrêt échoue pour une raison quelconque.
Il y a au moins 2 choses potentielles que vous pourriez signifier lorsque vous dites que vous voulez casser la création de fil: p>
Pour la première option, vous voudrez casser dans Createthread, _breginthread ou _breginthreadex. P>
Pour la deuxième option, vous voudrez casser dans RTLuserThreadStart ou BasethReadInitThunk pour attraper le nouveau fil au début de son exécution avant que le code d'utilisateur ne soit appelé. P>
Malheureusement, Visual Studio ne brisera pas ces fonctions si vous créez un point d'arrêt avec les noms de fonction que j'ai énumérés ci-dessus, au moins pas par défaut. Le problème est que pour le débogage indigène, il ne charge pas les exportations dll par défaut, et sans cela, le débogueur n'a aucune idée de la recherche des noms que j'ai fournis ci-dessus. P>
Avant de commencer le débogage, dans Visual Studio, accédez aux outils, options, débogage, puis développez l'arborescence des options de débogage dans le volet de gauche. Cliquez ensuite sur "Natif" et vérifiez "Charger les exportations DLL". Ensuite, vous pouvez commencer à déboguer à nouveau à nouveau votre exécutable. P>
Après cela, vous devriez pouvoir créer un point d'arrêt sur l'une des fonctions que j'ai mentionnées en tapant le nom. Vous pouvez avoir ou non besoin de spécifier la DLL de la fonction en créant le point d'arrêt avec le nom comme suit: p>
{, kernel32.dll} créethread p>
ou p>
{, ntdll.dll} rtluserthreadstart p>
J'ai reçu cette information en commençant ici: p>
HTTPS: //blogs.msdn.microsoft.com/reiley/2011/07/26/debugging-tips-for-multi-Threeded-Application/ P>
et faire des expériences seuls. Je sais que ceci est une réponse à une vieille question, mais j'espère que cela sauve une partie de la douleur que j'ai eu pour essayer de déboguer des accidents qui se produisent immédiatement après le démarrage du fil. P>
La première réponse utile sur ce sujet ... Je faisais défiler trop longtemps pour cela. Le seul problème que j'ai toujours avec votre explication est que les points d'arrêt définis via la convention {, dll} Funcname ne semblent toujours pas déclencher. Je devais faire de la copie de pointeur hacky pour accéder aux signatures STDCALL de ces fonctions qui semblaient alors déclencher. Je ne sais pas si ce n'est qu'un problème à ma fin cependant. Je vais écrire une autre réponse au cas où quelqu'un lit toujours sur cela.
C'était très heureux, merci. Cependant, êtes-vous sûr que vous devez redémarrer VisualStudio et charger des exportations? J'ai juste un processus interrompu à mi-parcours et écrivant Createthread ou _breginthreadex dans le panneau code> code>, je peux voir leurs adresses tout simplement bien. En fait, les adresses d'importation les conduites leur conduisant. D'autre part, si je colle {, kernel32.dll} créethread code> dans montre, je reçois kernel32.dll! 0x00007FFE8659B540 (chargez des informations supplémentaires) code>. J'ai pu utiliser ce kernel32.dll! 0x00007FFE8659B540 CODE> dans "Pause en fonction" et cela l'a attrapé juste.
Comme expliqué par @george, il y a deux fonctions que vous pouvez rompre. Si vous souhaitez découvrir ce qui crée le nouveau thread em> vous devez casser sur le thread Création des appels de fonction WinapI tels que Cependant, il y a deux conditions préalables à pouvoir briser Dans l'une de ces: p> pour que les points d'arrêt fonctionnent au débogueur doivent connaître des informations de symbole de base des DLL natives. Assurez-vous que le chargement de symboles des serveurs MS est activé (Outils -> Options -> Débogage -> Symboles) P> 2. Vous avez besoin des signatures STDCALL réelles des fonctions cible forte> p> Pour une raison quelconque, même avec une chargement d'exportation activée, VS n'a pas été incapable de trouver les fonctions dont je avais besoin pour me casser. Je suis donc allé vérifier quelles sont les signatures réelles. Ceci peut être fait en utilisant le Outil de lignes CMD de Dumbin de VS , ou en exécutant un court test sur le code: p> exécutant ce code dans le débogueur révèle l'adresse et la signature du C'est aussi simple que de choisir Débogou -> Nouveau point d'arrêt -> Casser en fonction. Pour le nom de la fonction, vous mettez l'un ou l'autre Ceci déclenche alors quand un nouveau fil est en train d'être Créé. P> Createthread code> ou _breginthread (ex) code>. Si vous souhaitez briser le début du fil nouvellement créé (sur la pile d'appel de ce fil lui-même), vous devez vous casser dans rtluserthreadstart code>. créatethread code> par exemple qui est _CreatthreadStub @ 24 code> Pour moi (application Win7 32 bits). Pour rtluserthreadstart code> il était ___ rtluserthreadstart @ 8 code> pour moi. P> _creetthreadstub @ 24 code> ou ___ rtluserthreadstart @ 8 code> et laissez le reste être. P> _Creatthreadstub @ 24 code> semble couvrir les fonctions Createthread, _breginthread et _breginthreadex. p> < / p>
Avez-vous déjà compris cela?
@Derek Tomes: Je ne l'ai pas fait. Je ne travaille pas avec Windows ou Visual Studio ces jours-ci, alors je ne cherche plus une solution moi-même.