Microsoft Access et VBA Comment augmenter la taille de la pile d exécution? Quand une application développée en VBA provoque une erreur de dépassement de la pile d exécution, il s agit bien souvent d une erreur de programmation, d un mauvais choix de conception, voire d un algorithme récursif mal maîtrisé. On peut aussi avoir vraiment besoin d augmenter la taille de la pile d exécution. Voici une démarche possible qui implique de modifier l en-tête du fichier exécutable, ici Microsoft Access. 1. Processus, thread et taille de pile Pour commencer une citation de la MSDN Library qui rappelle que la pile d exécution est liée au thread : Architecture de threads et de tâches Les applications complexes peuvent exécuter plusieurs tâches en même temps. Les threads sont une caractéristique du système d'exploitation qui permettent à la logique de l'application d'être séparée en plusieurs chemins d'exécution simultanés. Lorsqu'un système d'exploitation [NDR. Windows] exécute l'instance d'une application, il crée une unité appelée processus pour gérer l'instance. Le processus possède un thread d'exécution, c'est-à-dire une série d'instructions de programmation exécutées par le code de l'application. Dans le cas d'une application simple avec un seul ensemble d'instructions qui peut être exécuté en série, il n'y a qu'un seul chemin d'exécution, ou thread, dans toute l'application. Les applications plus complexes peuvent exécuter plusieurs tâches en même temps, mais pas en série. L'application pourrait faire cela en lançant des processus séparés pour chaque tâche, mais le lancement d'un processus est une opération qui nécessite beaucoup de ressources. Par contre, une application peut exécuter des threads différents, ce qui nécessite relativement peu de ressources. Chaque thread peut être programmé pour être exécuté de manière indépendante des autres threads associées à un processus. Chaque thread stocke les données qui lui sont uniques dans une zone de mémoire appelée pile. Une application comme Access exécute plusieurs threads : sur mon PC Access utilise 6 threads. Chaque thread possède sa propre pile d exécution. Donc, l augmentation de la taille de la pile d exécution s applique à tous les threads et, par conséquent, peut considérablement entamer la mémoire virtuelle de Windows. 2. En-tête de l exécutable et taille de pile La taille de la pile qui sera réservée par Windows pour chaque nouveau thread d un processus est fixée dans l en-tête du fichier exécutable. Ce qui veut dire que pour modifier cette taille il faut, soit recompiler l exécutable (qui possède le code source d Access?), soit modifier le fichier exécutable présent sur votre disque dur. L en-tête de l exécutable comporte de nombreuses informations et vous pouvez les consulter, voire les modifier (à vos risques et périls) au moyen d outils utilitaires comme éditeur de fichier (hexadécimal, décimal), voire beaucoup mieux, un éditeur d en-tête d exécutable. Deux informations nous intéressent particulièrement dans la section optionnelle de l en-tête. DWORD SizeOfStackReserve The amount of virtual memory to reserve for the initial thread's stack. Not all of this memory is committed, however (see the next field). This field defaults to 0x100000 (1MB). If you specify 0 as the stack size to CreateThread, the resulting thread will also have a stack of this same size. =JBO= Microsoft Access et VBA Comment augmenter la taille de la pile d exécution? 1 / 5
DWORD SizeOfStackCommit The amount of memory initially committed for the initial thread's stack. This field defaults to 0x1000 bytes (1 page) for the Microsoft Linker while TLINK32 makes it two pages. Pour en savoir plus : http://fr.wikipedia.org/wiki/portable_executable_file_format 3. Éditeur d en-tête d exécutable : PE Tools Il existe plusieurs éditeurs d en-tête d exécutable, certains payant, certains gratuits. Tous ne permettent pas de modifier l en-tête, ou bien seulement certaines informations. Je vous propose d utiliser l excellent freeware de NEOx, PE Tools 1.5.400, disponible en téléchargement sur l internet. Je l ai téléchargé ici : http://www.softpedia.com/get/programming/file-editors/pe-tools.shtml PE Tools est vraiment très puissant, et nous n allons exploiter qu une petite partie de son potentiel. Je vous laisse la joie de procéder à son installation sur votre PC. 4. Jeu d essai : une procédure récursive en VBA Pour mesurer l impact des modifications apportées à l en-tête d exécutable, je vous propose une petite procédure récursive en VBA, à exécuter via la fenêtre d exécution de l éditeur de VBA. Public Sub StackLimit(Optional ncount As Long = 1) On Error GoTo ErrStack Debug.Print ncount & "."; If (ncount Mod 20) = 0 Then Debug.Print StackLimit ncount + 1 Exit Sub ErrStack: Debug.Print vbcrlf & "ncount: " & ncount MsgBox Err.Description, vbcritical, "StackLimit: " & ncount End Sub En temps normal, lorsque je lance l exécution de cette procédure, une erreur de dépassement de pile d exécution se déclenche au 3.715 ème appel récursif. La profondeur d appels de la pile est donc de 3.715 pas. 5. Modifier la taille de la pile d exécution d Access avec PE Tools 1.5.400 Tout d abord, je vous conseille de travailler sur une copie de l exécutable d Access L exécutable se trouve (en général) à cet emplacement du disque dur de votre PC : C:\Program Files\Microsoft Office\Office\MSACCESS.EXE Pour ma part, je l ai copié dans le dossier C:\temp du disque dur. Bien sûr, il ne faut pas qu Access soit en cours d exécution si on veut modifier le fichier exécutable. =JBO= Microsoft Access et VBA Comment augmenter la taille de la pile d exécution? 2 / 5
Lancer PE Tools et exécuter la commande de menu Tools>> PE Editor : Une boîte de dialogue s ouvre pour sélectionner le fichier exécutable à éditer. Sélectionner la copie de l exécutable d Access placée préalablement dans c:\temp. =JBO= Microsoft Access et VBA Comment augmenter la taille de la pile d exécution? 3 / 5
La boîte de dialogue PE Editor affiche les informations de l en-tête. Cliquer sur le bouton Optional Header. La boîte de dialogue Image Optional Header Editor affiche les informations optionnelles de l entête (notation hexadécimale), et plus particulièrement celles qui nous intéressent : Size Of Stack Reserve, par défaut à &h100000, soit 1 méga-octet. Size Of Stack Commit, par défaut à &h1000, soit 4 kilo-octets. Fixer de nouvelles valeurs pour ces informations. Pour commencer je conseille de simplement les multiplier par 4 soit : Size Of Stack Reserve, fixé à &h400000, soit 4 méga-octets. Size Of Stack Commit, par défaut à &h4000, soit 16 kilo-octets. =JBO= Microsoft Access et VBA Comment augmenter la taille de la pile d exécution? 4 / 5
Enfin, pour appliquer ces modifications, cliquer sur les boutons OK des deux boîtes de dialogue ouvertes. Il ne reste plus qu à quitter PE Tools. 6. Résultats Maintenant vous pouvez lancer l exécutable modifié d Access et tester la procédure récursive. Voici un petit tableau de résultats, assez édifiant! Size Of Stack Reserve Size Of Stack Commit Profondeur d appels de la procédure StackLimit &h100000 (1 Mo) &h1000 (4 Ko) 3 715 appels &h400000 (4 Mo) &h4000 (16 Ko) 15 631 appels &h10000000 (256 Mo) &h100000 (1 Mo) 1 016 244 appels Bien évidemment, je vous déconseille formellement d augmenter la taille de la pile à 256 Mo. C était juste à titre expérimental. =JBO= =JBO= Microsoft Access et VBA Comment augmenter la taille de la pile d exécution? 5 / 5