Windows n'engage pas la pile de mémoire immédiatement; à la place, il réserve l'espace d'adressage pour celui-ci et le valide page par page lorsqu'il est accédé. Lisez this page pour plus d'informations.
En conséquence, l'espace d'adressage de la pile se compose de trois régions contiguës:
- réservé mais la mémoire non validée qui peut être utilisé pour la croissance de la pile (mais n'a encore jamais accédé);
- La page de garde, qui n'a jamais été accédée encore, et sert à déclencher la croissance de la pile lors de l'accès;
- Mémoire validée, c'est-à-dire mémoire de pile à laquelle le thread a déjà accédé.
Cela nous permet de construire une fonction qui obtient la taille de la pile (avec une granularité de taille de la page):
static size_t GetStackUsage()
{
MEMORY_BASIC_INFORMATION mbi;
VirtualQuery(&mbi, &mbi, sizeof(mbi));
// now mbi.AllocationBase = reserved stack memory base address
VirtualQuery(mbi.AllocationBase, &mbi, sizeof(mbi));
// now (mbi.BaseAddress, mbi.RegionSize) describe reserved (uncommitted) portion of the stack
// skip it
VirtualQuery((char*)mbi.BaseAddress + mbi.RegionSize, &mbi, sizeof(mbi));
// now (mbi.BaseAddress, mbi.RegionSize) describe the guard page
// skip it
VirtualQuery((char*)mbi.BaseAddress + mbi.RegionSize, &mbi, sizeof(mbi));
// now (mbi.BaseAddress, mbi.RegionSize) describe the committed (i.e. accessed) portion of the stack
return mbi.RegionSize;
}
Une chose à considérer: CreateThread
permet de spécifier la pile commit initial la taille (via le paramètre dwStackSize
, lorsque STACK_SIZE_PARAM_IS_A_RESERVATION
le drapeau n'est pas défini). Si ce paramètre est différent de zéro, notre fonction renverra une valeur correcte uniquement lorsque l'utilisation de la pile deviendra supérieure à la valeur dwStackSize
.
Votre commentaire n'est pas tout à fait vrai. Toucher la page en question est OK, vraiment. La technique consiste à écrire toute la mémoire pertinente avec une valeur spécifique, puis après un long moment de fonctionnement, voir combien de mémoire n'a plus cette valeur. – JXG
Queueing Microsoft: "Une tentative de lecture ou d'écriture sur une page de garde entraîne l'activation par le système d'une exception STATUS_ACCESS_VIOLATION et la désactivation de l'état de la page de garde, les pages Guard agissant ainsi comme une alarme d'accès unique.". Non, la lecture n'est pas exempte. – MSalters
Je pense que nous parlons les uns des autres. – JXG