La détermination de l'Espace de Pile avec Visual Studio
Je suis à la programmation en C sous Visual Studio 2005. J'ai un programme multi-threadé, mais ce n'est pas particulièrement important, ici.
Comment puis-je déterminer (environ) de combien d'espace de pile mon fils utiliser?
La technique, j'avais l'intention d'utiliser la pile de la mémoire à certains valeur prédéterminée, dire 0xDEADBEEF, l'exécution du programme pendant une longue période, de la suspension du programme, et d'enquêter sur la pile.
Comment puis-je lire et écrire la mémoire de pile avec Visual Studio?
EDIT: Voir, par exemple, "Comment faire pour déterminer le maximum de l'utilisation des piles." Que la question parle d'un système embarqué, mais ici, je suis en train de déterminer la réponse sur un PC ordinaire.
OriginalL'auteur JXG | 2009-11-16
Vous devez vous connecter pour publier un commentaire.
Windows n'engage pas la pile de la mémoire; au lieu de cela, il se réserve l'espace d'adressage pour elle, et l'engage, page par page, lorsqu'il est consulté. Lire cette page pour plus d'info.
En conséquence, la pile l'adresse de l'espace est constitué de trois régions contiguës:
Cela nous permet de construire une fonction qui obtient la taille de la pile (avec une taille de page de la granularité):
Une chose à considérer:
CreateThread
permet de spécifier initiale de la pile la taille de la validation (viadwStackSize
paramètre, lorsqueSTACK_SIZE_PARAM_IS_A_RESERVATION
indicateur n'est pas défini). Si ce paramètre est différent de zéro, notre fonction retourne la valeur correcte uniquement lors de l'utilisation des piles devient supérieure àdwStackSize
valeur.La pile ne poussent vers le bas (sur x86, au moins). Je suis en ajoutant parce que
VirtualQuery
retourne l'adresse de base de l'allocation de mémoire de la région - l'adresse de la dernière (théoriquement) utilisable octet d'une baisse de la croissance de la pile. Sur une plate-forme avec la hausse croissante de la pile, la premièreVirtualQuery
appel aurait donné le résultat requis. Je suppose que je pourrais l'illustrer avec une photo; je vais probablement même le faire plus tard quand j'aurai plus de temps.J'ai une légère inquiétude au sujet de cette solution (ce qui est très utile). Comment savons-nous que lors de l'exécution de cette fonction, ou l'un des VirtualQuery appels qu'il fait, que nous n'avons pas courir sur la page de garde et, par conséquent, la cause réelle de la pile de l'état à modifier en dessous de nous? Ne pouvait pas la page de garde déplacer?
Il ne peut pas (si vous êtes prêt à accepter certaines des hypothèses raisonnables sur
VirtualQuery
internes et compilateur de génération de code, la croissance de la pile devrait être terminée au premierVirtualQuery
appel). Bien que vous pourriez appeler cela fn twise (ou n fois) et de prendre le dernier résultat pour être certain. (Mais pas à 100%; par exemple, un autre processus peut infliger uneWriteProcessMemory
sur nous et nous aimerions être vissé 🙂 ). Le concept de l'utilisation des piles n'a de sens que pour la surveillance de la santé ou de débogage de toute façon, de sorte que le fn devrait être ok.OriginalL'auteur atzz
Vous pouvez faire usage de l'information dans le Win32 Thread Bloc D'Informations
Quand vous voulez dans un thread pour savoir combien d'espace de pile il utilise, vous pouvez faire quelque chose comme ceci:
OriginalL'auteur Sergei Kurenkov
La pile ne fonctionne pas de la façon dont vous vous attendez trop. La pile est une séquence linéaire de pages, la dernière (en haut) dont l'un est marqué par une page de garde bits. Lorsque cette page est touché, la garde bits est supprimé, et la page peut être utilisée. Pour plus de croissance, une nouvelle page de garde est attribué.
Donc, la réponse que vous voulez, c'est là où le gaurd page est affectée. Mais la technique que vous proposez d'en toucher la page en question, et comme un résultat, il rendrait la chose même que vous êtes en train de mesurer.
Le non-invasive pour déterminer si un (pile), la page de garde de bits est via
VirtualQuery()
.Qupting Microsoft: "Une tentative de lecture ou d'écriture sur une page de garde, le système de soulever une exception STATUS_ACCESS_VIOLATION et désactiver la page de garde de statut. Pages de garde donc agir comme un one-shot d'accès alarme.". Non, la lecture n'est pas exonérée.
Je pense que nous parlons les uns les autres.
Mais si je vous comprends bien, votre solution a une résolution de page. Votre réponse est utile, mais il ne veut pas me donner une réponse spécifique comme je l'espérais.
En fait, c'est la bonne réponse, car une page attribuées à une pile est exclusivement attribuée à la pile et du fil. Par conséquent, la taille de la pile est toujours qu'un certain nombre de pages. Voir aussi MSVC options du compilateur - options comme "pile initiale de l'espace" sont précisées dans des multiples de la taille de la page.
OriginalL'auteur MSalters
Vous pouvez utiliser GetThreadContext() fonction pour déterminer le thread actuel du pointeur de pile. Ensuite, utilisez VirtualQuery() pour trouver la base de la pile pour que ce pointeur. Soustrayant ces deux pointeurs vous donnera la taille de la pile de thread donné.
OriginalL'auteur denisenkom