[R] Erreur suite à saturation mémoire ?

Aide et conseils concernant AutoIt et ses outils.
Règles du forum
.
Répondre
jpascal
Niveau 6
Niveau 6
Messages : 239
Enregistré le : jeu. 16 oct. 2008 16:21
Status : Hors ligne

[R] Erreur suite à saturation mémoire ?

#1

Message par jpascal »

Bonjour,

J'ai créé un script qui récupère une liste d'une page HTML à l'aide du code HTML et de RegEx.

Ensuite, je teste si la case de chaque objet de la liste est coché avec ce code et j'ajoute son nom dans un fichier si c'est le cas :

Code : Tout sélectionner

For $i = 0 To UBound($aArray) - 1 Step 2
		$res = _IEFormElementCheckBoxSelect($oForm, 0, $sPrefixe & $aArray[$i] & $sSuffixe, -1, "byIndex")
		If @error Then Exit MsgBox($MB_SYSTEMMODAL + $MB_ICONERROR, '', 'Erreur ' & @error & ' (' & $aArray[$i] & ')')
		If $res = 1 Then FileWrite($hFile, $aArray[$i + 1] & @CRLF)
Next
Le programme plante aléatoirement.
Là je viens de faire des essais, ça plante à l'objet 450.

La récupération de la liste est immédiate mais mon tableau contient plus de 2200 entrées.

Je pense que c'est un problème mémoire. Comment puis-je le vérifier ? Le régler ?
Modifié en dernier par jpascal le mar. 28 juin 2016 14:45, modifié 2 fois.
AutoIt 3.3.16.1 - AutoIt3Wrapper 21.316.1639.1
Avatar du membre
TomAijerrie
Niveau 5
Niveau 5
Messages : 192
Enregistré le : lun. 02 juin 2014 09:55
Localisation : Lyon
Status : Hors ligne

Re: [..] Erreur suite à saturation mémoire ?

#2

Message par TomAijerrie »

Pour vérifier, tu peux lancer le gestionnaire des taches (Ctrl + Maj + Echap) et tu regarde la courbe d'utilisation de la mémoire RAM.
Si ça viens un peut trop près du plafond, c'est que le problème est effectivement un problème memoire.
Avatar du membre
orax
Modérateur
Modérateur
Messages : 1479
Enregistré le : lun. 23 mars 2009 04:50
Localisation : ::1
Status : Hors ligne

Re: [..] Erreur suite à saturation mémoire ?

#3

Message par orax »

Quelle est exactement l'erreur lors du plantage ?
De petits détails peuvent faire toute la différence. — Quand la boule de neige commence à rouler… poussez-la. (Columbo)
jpascal
Niveau 6
Niveau 6
Messages : 239
Enregistré le : jeu. 16 oct. 2008 16:21
Status : Hors ligne

Re: [..] Erreur suite à saturation mémoire ?

#4

Message par jpascal »

L'utilisation mémoire ne varie pas.

L'erreur est :

Code : Tout sélectionner

IE.au3 T3.0-2 Warning from function _IEFormElementCheckBoxSelect, $_IESTATUS_NoMatch
Donc grosso modo, il récupère correctement l'état des 450 premières cases à cocher.
Les 120 tests suivants, j'obtiens cette erreur.
Ensuite AutoIt plante avec une belle fenêtre : "AutoIt v3 Script a cessé de fonctionner."
Et le déboqueur indique : "Une exception win32 non gérée s'est produite dans AutoIt.exe"
AutoIt 3.3.16.1 - AutoIt3Wrapper 21.316.1639.1
jpascal
Niveau 6
Niveau 6
Messages : 239
Enregistré le : jeu. 16 oct. 2008 16:21
Status : Hors ligne

Re: [..] Erreur suite à saturation mémoire ?

#5

Message par jpascal »

A noter que l'erreur n'est pas systématique. Je peux l'avoir deux fois et cela fonctionnera au troisième essai.

De plus, si je remplace For $i = 0 par For $i = 2 ou For $i = 4, la case à cocher posant problème sera décalée d'autant.

On peut donc exclure un problème dans le code source de la page.
Le problème doit se situer au niveau de l'UDF IE.au3

Rajouter un Sleep(100) dans la boucle ne change rien.
AutoIt 3.3.16.1 - AutoIt3Wrapper 21.316.1639.1
jpascal
Niveau 6
Niveau 6
Messages : 239
Enregistré le : jeu. 16 oct. 2008 16:21
Status : Hors ligne

Re: [..] Erreur suite à saturation mémoire ?

#6

Message par jpascal »

Si je récupère à nouveau le contenu de mon cadre puis de mon formulaire, le traitement peut poursuivre.
Mais à la seconde erreur, c'est inefficace.

La seule solution trouvée est d'enregistrer la checkbox où le traitement est en erreur et de relancer le programme.

La page web n'étant pas actualisée, le programme se situe donc bien au niveau d'AutoIt (fuite mémoire ?)
AutoIt 3.3.16.1 - AutoIt3Wrapper 21.316.1639.1
Avatar du membre
orax
Modérateur
Modérateur
Messages : 1479
Enregistré le : lun. 23 mars 2009 04:50
Localisation : ::1
Status : Hors ligne

Re: [..] Erreur suite à saturation mémoire ?

#7

Message par orax »

J'ai essayé de reproduire le problème, pour voir quelle en serait l'origine, mais sans succès. Donc c'est assez difficile de t'aider puisque je n'ai pas de plantage.
Dans le but de pouvoir reproduire les plantages, serait-il possible d'avoir l'adresse du site ou le code HTML qui pose des problèmes ?
De petits détails peuvent faire toute la différence. — Quand la boule de neige commence à rouler… poussez-la. (Columbo)
jpascal
Niveau 6
Niveau 6
Messages : 239
Enregistré le : jeu. 16 oct. 2008 16:21
Status : Hors ligne

Re: [..] Erreur suite à saturation mémoire ?

#8

Message par jpascal »

Le site étant interne, il m'est impossible de donner un accès.
J'ai donc enregistré le code source et nettoyé certaines références.

Voici le lien de téléchargement : http://dl.free.fr/nXecO8tbi

A noter que la page originale est plus lourde, je n'ai conservé que la partie tableau contenant les fameuses checkbox.

Le tableau contenant toutes les tâches est généré comme cela :

Code : Tout sélectionner

$ePrefixe = "m_c_gridTasks_v_ctl"
$eSuffixe = "_s"
$sPattern = '<label for="' & $ePrefixe & '(\d+)' & $eSuffixe & '">.*?onmouseout="UnTip\(\)">(.*?)</span></td><td class="wrap-normal">'
$aArray = StringRegExp($sHTML, $sPattern, 3)
AutoIt 3.3.16.1 - AutoIt3Wrapper 21.316.1639.1
Avatar du membre
orax
Modérateur
Modérateur
Messages : 1479
Enregistré le : lun. 23 mars 2009 04:50
Localisation : ::1
Status : Hors ligne

Re: [..] Erreur suite à saturation mémoire ?

#9

Message par orax »

Je n'ai toujours pas d'erreur.

Code : Tout sélectionner

#include <IE.au3>

$sURL = 'http://au3.96.lt/temp/prob_autoit.html'
$oIE = _IECreate($sURL)
;~ $oIE = _IEAttach('prob_autoit.html', 'url')
Sleep(10000) ; le temps de cocher des cases

For $j = 1 To 50
	$sHTML = _IEBodyReadHTML($oIE)

	$sPrefixe = "m_c_gridTasks_v_ctl"
	$sSuffixe = "_s"
	$sPattern = '<label for="' & $sPrefixe & '(\d+)' & $sSuffixe & '">.*?onmouseout="UnTip\(\)">(.*?)</span></td><td class="wrap-normal">'
	$aArray = StringRegExp($sHTML, $sPattern, 3)
	$oForm = _IEFormGetObjByName($oIE, 'maform')
;~ _ArrayDisplay($aArray)
	For $i = 0 To UBound($aArray) - 1 Step 2
;~ 		ConsoleWrite($sPrefixe & $aArray[$i] & $sSuffixe & @CRLF)
		$res = _IEFormElementCheckBoxSelect($oForm, 0, $sPrefixe & $aArray[$i] & $sSuffixe, -1, "byIndex")
		If @error Then Exit MsgBox($MB_SYSTEMMODAL + $MB_ICONERROR, '', 'Erreur ' & @error & ' (' & $aArray[$i] & ')')
		;If $res = 1 Then FileWrite($hFile, $aArray[$i + 1] & @CRLF)
		If $res = 1 Then ConsoleWrite($aArray[$i + 1] & @CRLF)
	Next
Next
Modifié en dernier par orax le ven. 24 juin 2016 12:33, modifié 1 fois.
De petits détails peuvent faire toute la différence. — Quand la boule de neige commence à rouler… poussez-la. (Columbo)
jpascal
Niveau 6
Niveau 6
Messages : 239
Enregistré le : jeu. 16 oct. 2008 16:21
Status : Hors ligne

Re: [..] Erreur suite à saturation mémoire ?

#10

Message par jpascal »

Je te remercie d'avoir pris de ton temps pour tester.
Je n'ai pas d'erreur si j'utilise ton script et mon code épuré (j'ai modifié le premier $i en $j pour que la boucle fonctionne).

J'ai bien peur que cela soit la structure du site et les javascripts intégrés qui posent problème.
J'ai en effet un message qui apparaît au bout d'un certain temps qui me déconnecte du site.
De plus la page est insérée dans plusieurs cadres.

Un code plus complet pour voir comment je procède :

Code : Tout sélectionner

	ProgressOn($g_eTitleApp, 'Récupération des tâches', '', Default, Default, $DLG_MOVEABLE)
	Local $iLines = UBound($g_aLines) - 1

	For $i = $ibegin To $iLines Step 2
		;ConsoleWrite($g_aLines[$i] & @CRLF)
		$res = _IEFormElementCheckBoxSelect($g_oForm, 0, $ePrefixe & $g_aLines[$i] & $eSuffixe, -1, "byIndex")
		If @error Then
			ConsoleWrite('Erreur on line ' & $i & @CRLF)
			ReloadContent()
			Sleep(3000)
			$res = _IEFormElementCheckBoxSelect($g_oForm, 0, $ePrefixe & $g_aLines[$i] & $eSuffixe, -1, "byIndex")
			If @error Then
				ProgressOff()
				FileDelete($eFileResume)
				FileWrite($eFileResume, $i)
				MsgBox($MB_SYSTEMMODAL + $MB_ICONERROR, $g_eTitleApp, 'Erreur sur la tâche ' & $g_aLines[$i] & ' :' & @CRLF & $g_aLines[$i + 1] & @CRLF & @CRLF & 'Veuillez relancer le programme.')
				Exit
			EndIf
		EndIf
		ProgressSet($i * 100 / $iLines, 'Tâche ' & $g_aLines[$i] & ' / ' & $g_aLines[$iLines - 1])
		If $res = 1 Then FileWrite($hFile, $g_aLines[$i + 1] & @CRLF)
		;Sleep(100)
	Next

	ProgressOff()

Code : Tout sélectionner

Func ReloadContent()
	Local $oFrame0 = _IEFrameGetCollection($g_oIE, 0)
	If @error Then Exit MsgBox($MB_SYSTEMMODAL + $MB_ICONERROR, $g_eTitleApp, 'Erreur de récupération du cadre 0 (' & @error & ')')
	Local $oFrame1 = _IEFrameGetCollection($oFrame0, 0)
	If @error Then Exit MsgBox($MB_SYSTEMMODAL + $MB_ICONERROR, $g_eTitleApp, 'Erreur de récupération du cadre 1 (' & @error & ')')
	Local $oFrame = _IEFrameGetCollection($oFrame1, 1)
	If @error Then Exit MsgBox($MB_SYSTEMMODAL + $MB_ICONERROR, $g_eTitleApp, 'Erreur de récupération du cadre (' & @error & ')')
	$g_oForm = _IEFormGetCollection($oFrame, 0)
	If @error Then Exit MsgBox($MB_SYSTEMMODAL + $MB_ICONERROR, $g_eTitleApp, 'Erreur de récupération du formulaire (' & @error & ')')
	$g_oSelect = _IEFormElementGetObjByName($g_oForm, "m$c$gridTasks$p$drpPageSize")
	If @error Then Exit MsgBox($MB_SYSTEMMODAL + $MB_ICONERROR, $g_eTitleApp, 'Erreur de récupération de la liste déroulante (' & @error & ')')

	Local $sHTML = _IEBodyReadHTML($oFrame)
	If @Compiled = 0 Then
		FileDelete('_debug' & $g_iDebug & '.htm')
		FileWrite('_debug' & $g_iDebug & '.htm', $sHTML)
		$g_iDebug += 1
	EndIf
	$sPattern = '<label for="' & $ePrefixe & '(\d+)' & $eSuffixe & '">.*?onmouseout="UnTip\(\)">(.*?)</span></td><td class="wrap-normal">'
	$g_aLines = StringRegExp($sHTML, $sPattern, 3)
	If @error <> 0 Then Exit MsgBox($MB_SYSTEMMODAL + $MB_ICONERROR, $g_eTitleApp, "Le code du site a changé.")
EndFunc   ;==>ReloadContent
J'ai rajouté FileWrite('_debug' & $g_iDebug & '.htm', $sHTML) de manière à conserver le code source après chaque ReloadContent.

C'est systématique.
Soit le programme récupère les checkbox SANS ERREUR.
Soit j'obtiens une erreur, le prog récupère le code HTML, j'obtiens une seconde erreur, le prog récupère le code HTML, mais impossible de récupérer l'état des checkbox suivantes.

J'ai comparé les 3 fichiers (avant erreur, après première erreur, après seconde erreur), le code est identique.
AutoIt 3.3.16.1 - AutoIt3Wrapper 21.316.1639.1
Avatar du membre
orax
Modérateur
Modérateur
Messages : 1479
Enregistré le : lun. 23 mars 2009 04:50
Localisation : ::1
Status : Hors ligne

Re: [..] Erreur suite à saturation mémoire ?

#11

Message par orax »

Il n'y a pas besoin de récupérer le code HTML, on pourrait aussi faire comme ça :

Code : Tout sélectionner

#include <IE.au3>

$sURL = 'http://au3.96.lt/temp/prob_autoit.html'
$oIE = _IECreate($sURL)
;~ $oIE = _IEAttach('prob_autoit.html', 'url')
Sleep(10000) ; le temps de cocher des cases

$oInputs = $oIE.document.getElementsByTagName("input")
For $oInput In $oInputs
	If $oInput.checked Then
		$oSpan = $oInput.parentElement.parentElement.parentElement.getElementsByTagName('span').item(4)
		If IsObj($oSpan) Then
			ConsoleWrite($oInput.id & " - nom de la tâche : " & $oSpan.textContent & @CRLF)
		EndIf
	EndIf
Next
Dans cet exemple, on navigue dans le DOM pour trouver les éléments.
Quand on est au niveau du l'INPUT, on remonte au TR (avec les parentElement) pour rechercher, dans les éléments enfants, le SPAN qui contient le nom de la tâche.
<tr> <= on remonte ici
 <td>
    <span>
      <input> <= [x] checkbox
 <td>
  <td>
    <span>
      nom de la tâche
De petits détails peuvent faire toute la différence. — Quand la boule de neige commence à rouler… poussez-la. (Columbo)
jpascal
Niveau 6
Niveau 6
Messages : 239
Enregistré le : jeu. 16 oct. 2008 16:21
Status : Hors ligne

Re: [..] Erreur suite à saturation mémoire ?

#12

Message par jpascal »

Quelle bonne idée. Comme quoi les habitudes c'est mal.

J'utilisais le DOM pour les scripts GreaseMonkey mais jamais dans AutoIt.

J'essaierai la semaine prochaine et je ferai un retour pour voir si c'est mieux.

Merci.
AutoIt 3.3.16.1 - AutoIt3Wrapper 21.316.1639.1
Avatar du membre
orax
Modérateur
Modérateur
Messages : 1479
Enregistré le : lun. 23 mars 2009 04:50
Localisation : ::1
Status : Hors ligne

Re: [..] Erreur suite à saturation mémoire ?

#13

Message par orax »

En fait, je ne t'apprends sans doute rien, mais c'est ce que font les fonctions _IE*. D'ailleurs, dans mon code, getElementsByTagName aurait pu être remplacé par _IETagNameGetCollection.
De petits détails peuvent faire toute la différence. — Quand la boule de neige commence à rouler… poussez-la. (Columbo)
jpascal
Niveau 6
Niveau 6
Messages : 239
Enregistré le : jeu. 16 oct. 2008 16:21
Status : Hors ligne

Re: [..] Erreur suite à saturation mémoire ?

#14

Message par jpascal »

Bonjour orax,

Détrompe-toi, je ne le savais pas. J'avoue ne pas avoir eu la curiosité d'aller regarder le code de l'UDF.

Et bien c'est magniiiiifiiiique ! Le traitement prend une seconde désormais contre plus d'une minute auparavant (sans compter le fait de devoir relancer le programme).

Un grand merci à toi.
AutoIt 3.3.16.1 - AutoIt3Wrapper 21.316.1639.1
Répondre