Monitoring de programme, crash

Codes specifiques à Windows
hub73
Messages : 126
Inscription : sam. 16/janv./2021 20:17

Monitoring de programme, crash

Message par hub73 »

Bonjour à tous.
Schématiquement, Mon programme de diffusion pour notre webradio lit à la suite les uns des autres des fichiers .ogg via loadsound et playsound (playsound non utilisé en 'mode' streaming'). Ce programme devrait fonctionner toute la journée.
Sur cette machine, windows 10 famille, fonctionne Rocket Broadcaster (logiciel de streaming vers mon icecast2 sur un VPS hébergé chez OVH). Rocket Broadcaster intègre le vst StereoTool.

Mon logiciel écrit des informations dans un fichier de log, lorsqu'il charge un .ogg, le lit, ...

- Le soucis, c'est que mon système va rebooter au bout de quelques heures et je ne parviens pas à déterminer la cause ! Pas un seul message d'erreur. Si le pc ne reboote pas, et bien c'est l'affichage qui est passé à une résolution inférieure et le programme semble encore tourner, par contre il refuse de charger via loadsound les fichiers : dans mon code IsSound à lire est à 0 après le loadsound.

- J'ai installé sur un autre machine plus puissante (8Go de mémoire, ...) , essayé de monitorer avec le gestionnaire de tâche, d'autres softs... Mon programme semble pourtant utiliser peu de ressource ! Un pic, un dépassement soudain ferait-il planter l'ensemble ?

Je soupçonne un soucis au niveau de la mémoire. Un dépassement RAM ou qqchose en lien avec l'affichage vidéo. Va savoir ! Ou alors la suite des LoadSound. Quelquechose se remplirait, un tampon, sans se vider correctement !

J'utilise un Freesound(MonSonlu) avant d'en relire un autre pour vider la mémoire. Est-ce suffisant ? Il y a un Freesound(#Pb_all) avant le rebouclage des lectures, c'est radical çà non, devrait libérer de la mémoire ?

Q1 : Existe t-il des commandes internes à Purebasic qui me permettent de connaitre l'utilisation de la mémoire de mon application.
Q2 : Playsound, loadsound, freesound. Des conseils d'utilisation pour pallier à mon problème ?

Un extrait de mon programme :

Code : Tout sélectionner

 Procedure Charger_et_jouer_element_liste()
  
  Define NomFichier$
  Define Titre$
  Define Code$
  Define Personnes$
  Define Image$
  Define Duree$
  Define Commentaire$  
  
  NomFichier$ = Tableau_playlist$ (gItem_lecture-1)
  Titre$ = Tableau_elements(gItem_lecture-1)\Titre
  
  If Titre$ <> "<DIRECT>"
  
    If IsSound (gSonLu) <> 0 
        While SoundStatus(gSonLu) > 0 : Wend
        FreeSound (gSonLu)
    EndIf
    
    gSonLu = LoadSound(#PB_Any, gChemin_general_donnees$ + NomFichier$)
    
    If IsSound (gSonLu) <> 0
      
      PlaySound(gSonLu)
      
      gNbreTentativesChargement = 0
      
      Code$ = Tableau_elements(gItem_lecture-1)\Code
      Personnes$ = Tableau_elements(gItem_lecture-1)\Personnes
      Image$ = Tableau_elements(gItem_lecture-1)\Image
      Duree$ = Convertion_affichage_temps ( SoundLength(gSonlu, #PB_Sound_Millisecond) )
      Commentaire$ = Tableau_elements(gItem_lecture-1)\Commentaire
      
      Ajouter_au_log ("Lecture du fichier : '" + Titre$ + "' - " + Code$ + " - " + Duree$ + " - '" + NomFichier$ + "'.")
      Afficher_message ("Lecture du fichier : '" + Titre$ + "' - " + Code$ + " - " + Duree$ + " - '" + NomFichier$ + "'.")
      Envoyer_message_retour_diffusion ("Lecture du fichier : '" + Titre$ + "' - " + Code$ + " - " + Duree$ + " - '" + NomFichier$ + "'.")
      
      Envoyer_requete_site(Titre$, Code$, Duree$, Personnes$, Image$,Commentaire$)
      
      Ecrire_meta_donnees (Tableau_elements(gItem_lecture-1)\Personnes, Tableau_elements(gItem_lecture-1)\Titre)
      
      gEtat_lecture = #LECTURE_LISTE_ITEM_EN_COURS
      
    Else
      
      Ajouter_au_log("ERREUR : Impossible de lire le fichier'" + NomFichier$ + "'")
      Envoyer_message_retour_diffusion ("ERREUR : Impossible de lire le fichier'" + NomFichier$ + "'")
      
      If gNbreTentativesChargement >= #MAX_TENTATIVES_CHARGEMENT
        gEtat_lecture = #LECTURE_LISTE_ITEM_SUIVANT
      Else
        FreeSound (#PB_All) ; pour liberer de la mémoire ?
        Delay (2000)
        gNbreTentativesChargement = gNbreTentativesChargement + 1
        Ajouter_au_log("TENTATIVE RECHARGEMENT DU FICHIER " + Str(gNbreTentativesChargement) + "/" + Str(#MAX_TENTATIVES_CHARGEMENT) + " : " + NomFichier$ + "'")
        Envoyer_message_retour_diffusion ("TENTATIVE RECHARGEMENT DU FICHIER " + Str(gNbreTentativesChargement) + "/" + Str(#MAX_TENTATIVES_CHARGEMENT) + " : " + NomFichier$ + "'")
        Charger_et_jouer_element_liste()
      EndIf
    EndIf
    
  Else
    
    gEtat_lecture = #LECTURE_DIRECT_DEBUT
    
  EndIf
    
 EndProcedure

Merci à vous.
Marc56
Messages : 2146
Inscription : sam. 08/févr./2014 15:19

Re: Monitoring de programme, crash

Message par Marc56 »

Bonjour,

Je n'ai regardé que le début pour l'instant.

Le Wend n'est pas à la bonne place :)

Code : Tout sélectionner

    If IsSound (gSonLu) <> 0 
        While SoundStatus(gSonLu) > 0 : Wend
        FreeSound (gSonLu)
    EndIf
Plutôt

Code : Tout sélectionner

      If IsSound (gSonLu) <> 0 
          While SoundStatus(gSonLu) > 0 
              FreeSound (gSonLu)
          Wend    
      EndIf
ou ça

Code : Tout sélectionner

      If IsSound (gSonLu) And SoundStatus(gSonLu) <> #PB_Sound_Playing
          FreeSound (gSonLu)
      EndIf
« Moins c'est plus » 8)

Bien qu'ici cela ne change rien, utilise Protected plutôt que Define

Pour la mémoire, voir MemoryStatus()

PS. Un PC qui reboote seul et qui n'a pas le temps d'écrire dans les log Windows c'est souvent:
  • Une barrette de RAM défectueuse
  • Une carte vidéo défectueuse
  • Trop chaud, notamment carte vidéo encrassée ou ventilo qui ne tourne plus: Nettoyer tout à la soufflette (penser à coincer les ventilos pour ne pas faire de courant induit pendant le soufflage). Faire de la place autour de la carte vidéo. Si le PC tourne en serveur, mettre la fonction d'extinction d'écran (ou un écran de veille noir) et ne pas juste l'éteindre.
:wink:
hub73
Messages : 126
Inscription : sam. 16/janv./2021 20:17

Re: Monitoring de programme, crash

Message par hub73 »

Merci du retour Marc56 et des précieux conseils. j'ai corrigé mon code.
Les explications sont très claires et utiles !

Du coup, j'aimerai avoir votre avis sur une autre partie de code :

PlaySound(SonLocal)
While SoundStatus(SonLocal) > 0 : Wend
FreeSound (SonLocal)

Ce while... wend laisserait le temps de bien lire le son 'sonlocal' avant de lancer le FreeSound. (Sinon le freesound arriverait trop tôt). Qu'en pensez-vous. SonLocal c'est un fichier de maxi 2 minutes, genre slogan de la radio ou top horaire)

Extrait du code suivant, pour info :

Code : Tout sélectionner

Procedure Jouer_interruption(NomFichier$)
  
  Define SonLocal
  
  If IsSound(gSonLu) <> 0
  
    If SoundStatus(gSonLu) = #PB_Sound_Playing
      PauseSound(gSonLu)
      If gItem_lecture >= 1
          Ajouter_au_log ("Pause fichier en cours '" + Tableau_playlist$ (gItem_lecture-1) +"'.")
          Envoyer_message_retour_diffusion ("Pause fichier en cours '" + Tableau_playlist$ (gItem_lecture-1) +"'.")
        Else
          Ajouter_au_log ("Pause fichier en cours.")
          Envoyer_message_retour_diffusion ("Pause fichier en cours.")
       EndIf
    EndIf
      
  EndIf
      
  SonLocal = LoadSound(#PB_Any, gChemin_general_donnees$ + NomFichier$)
  
  If IsSound (SonLocal) <> 0
    
    Ajouter_au_log ("Lecture du fichier interruption '" + NomFichier$ + "'")
    Afficher_message ("Lecture du fichier interruption '" + NomFichier$ + "'")
    Envoyer_message_retour_diffusion ("Lecture du fichier interruption '" + NomFichier$ + "'")
    PlaySound(SonLocal)
    
    While SoundStatus(SonLocal) > 0 : Wend
    
    FreeSound (SonLocal)
    Ajouter_au_log ("Fichier interruption '" + NomFichier$ + "' libéré.")
    Afficher_message ("Fichier interruption '" + NomFichier$ + "' libéré.")
    Envoyer_message_retour_diffusion ("Fichier interruption '" + NomFichier$ + "' libéré.")
    
    If IsSound (gSonLu) <> 0
      If SoundStatus(gSonLu) = #PB_Sound_Paused
        ResumeSound(gSonLu)
         If gItem_lecture >= 1
          Ajouter_au_log ("Reprise du dernier fichier en cours '" + Tableau_playlist$ (gItem_lecture-1) +"'.")
          Afficher_message ("Reprise du dernier fichier en cours'" + Tableau_playlist$ (gItem_lecture-1) +"'.")
          Envoyer_message_retour_diffusion ("Reprise du dernier fichier en cours '" + Tableau_playlist$ (gItem_lecture-1) +"'.")
        Else
          Ajouter_au_log ("Reprise du dernier fichier en cours.")
          Afficher_message ("Reprise du dernier fichier en cours.")
          Envoyer_message_retour_diffusion ("Reprise du dernier fichier en cours.")
        EndIf
      Else
        FreeSound (gSonLu)
        If gItem_lecture >= 1
          Ajouter_au_log ("Pas de reprise possible du dernier fichier en cours '" + Tableau_playlist$ (gItem_lecture-1) +"'.")
          Afficher_message ("Pas de reprise possible du dernier fichier en cours'" + Tableau_playlist$ (gItem_lecture-1) +"'.")
          Envoyer_message_retour_diffusion ("Pas de reprise possible du dernier fichier en cours '" + Tableau_playlist$ (gItem_lecture-1) +"'.")
        Else
          Ajouter_au_log ("Pas de reprise possible du dernier fichier en cours.")
          Afficher_message ("Pas de reprise possible du dernier fichier en cours.")
          Envoyer_message_retour_diffusion ("Pas de reprise possible du dernier fichier en cours.")
        EndIf
      EndIf
    EndIf  
        
 EndIf
      
EndProcedure
Merci.
hub73
Messages : 126
Inscription : sam. 16/janv./2021 20:17

Re: Monitoring de programme, crash

Message par hub73 »

En fait j'ai mis les économies d'énergie disque dur et écran à 'jamais'. Et j'éteins juste l'écran. Ce n'est pas bon ?
Marc56
Messages : 2146
Inscription : sam. 08/févr./2014 15:19

Re: Monitoring de programme, crash

Message par Marc56 »

While SoundStatus(SonLocal) > 0 : Wend
Ça, à mon avis ça fait beaucoup travailler le CPU (ça peut même bloquer)
Pour faire jouer une liste de fichiers son, il faut mieux tester l'état dans la boucle principale avec une temporisation horaire (ex: 1/2 seconde)
Quelque-chose de ce style:

Code : Tout sélectionner

; Toutes les 1/2 sec 
AddWindowTimer(#Win, #Check_Running, 500)

Repeat
    Select WaitWindowEvent()
            
        Case #PB_Event_Timer
            If EventTimer() = #Check_Running
                ; Un son est initialisé, mais n'est plus joué
                If IsSound (gSonLu) And SoundStatus(gSonLu) <> #PB_Sound_Playing
                    FreeSound (gSonLu)
                    ; Jouer le suivant...
                EndIf
...
En ce qui concerne le moniteur, cela dépend du câblage, mais la plupart n'ont pas de retour d'information vers le PC, donc il ne sait pas que l'écran est éteint et la carte vidéo continue à travailler. Il vaut mieux utiliser la fonction éco d'énergie: elle éteindra l'écran.
Avatar de l’utilisateur
case
Messages : 1527
Inscription : lun. 10/sept./2007 11:13

Re: Monitoring de programme, crash

Message par case »

Code : Tout sélectionner

PlaySound(SonLocal)
While SoundStatus(SonLocal) > 0 : Wend
FreeSound (SonLocal)
je vois un probleme la dedans en tout cas pour un programme fenètré.
si ton son est assez long cela ne rend pas la main au systeme pour la gestion des events et peut conduire a windows fermant le programme
j'ajouterai un waitwindow event dans le while / wend

Code : Tout sélectionner

PlaySound(SonLocal)
While SoundStatus(SonLocal) > 0 :waitwindowevent(1) :Wend
FreeSound (SonLocal)
ImageImage
hub73
Messages : 126
Inscription : sam. 16/janv./2021 20:17

Re: Monitoring de programme, crash

Message par hub73 »

J'apprécie énormément votre aide. Je vais tester tout cela. Je comprend mieux pourquoi l'Os inscrivait 'pas de réponse' dans la fenêtre du programme ! Cette ligne ne m'inspirait pas confiance. Et j'allais vers la proposition de Marc, un timer.
hub73
Messages : 126
Inscription : sam. 16/janv./2021 20:17

Re: Monitoring de programme, crash

Message par hub73 »

J'ai donc corrigé le programme. je ne comprends toujours pas pourquoi quelquefois il refuse de charger le fichier .ogg et le lire. Au bout de 5 tentatives infructueuses, j'ai décidé que le programme devait se terminer. Il est relancé automatiquement (par un autre programme purebasic qui surveille s'il est ouvert). Le programme se relance alors et c'est reparti. C'est génant pour la webradio parce que tout le programme de la journée est recalculé. Si un auditeur écoute à ce moment là ou attend la diffusion d'un programme particulier...

Je ne sais pas si je devrais pas réaliser un loadsound du prochain fichier lu pendant que le précédent est en cours de lecture. Je ne sais pas trop comment fonctionne le système. Je crois que la librairie sound de purebasic est liée à directX sous windows ? un passage sous fMOD serait-il mieux et ou trouver de la doc pour bien l'utiliser avec PB ?

Ce bug est vraiment dommage. Je suis prêt à vous fournir l'intégralité du programme pour une relecture si quelqu'un à le temps d'y jeter un oeil.

Un lien vers les logs : https://lesfloralies.info/diffusion/logs/
Les Floralies Radio en écoute ici : https://www.lesfloralies.info
Avatar de l’utilisateur
Guillot
Messages : 522
Inscription : jeu. 25/juin/2015 16:18

Re: Monitoring de programme, crash

Message par Guillot »

d'accord avec case
moi quand on me pose 2 fois de suite la même question ça me gonfle
là, ton PC, tu lui demande 100 000 000 de fois par seconde:
ça y'est t'as finit ?
ça y'est t'as finit ?
ça y'est t'as finit ?
...
je pense même qu'il devrai y avoir des lois pour condamner ce genre de pratique !
Avatar de l’utilisateur
case
Messages : 1527
Inscription : lun. 10/sept./2007 11:13

Re: Monitoring de programme, crash

Message par case »

jamais eu ce genre de probleme avec le son dans pb

vérifie lors du chargement que ton son est bien chargé, cela peut être du a la mémoire qui serait insuffisante par exemple, le nom du fichier mal ecrit, plusieurs choses comme ca, une bonne pratique et de verifier un asset avant de s'en servir.

par exemple pour un son

Code : Tout sélectionner


if issound(mon_son) ; un son existe dans mon_son
   freesound(mon_son) ; je libere la memoire utilisée par le so(n pour eviter des memoryleaks
endif
mon_son=loadsound("trucbidule.ogg") ; je charge mon_son en memoire
  If IsSound(mon_son) = 0                   ;je teste la validité du son
    debug( "Le son n'est pas valide.")   
  EndIf
n'oublie pas lorsque tu charge un son de liberer la memoire avant avec un freesound()
ImageImage
hub73
Messages : 126
Inscription : sam. 16/janv./2021 20:17

Re: Monitoring de programme, crash

Message par hub73 »

Merci pour votre aide. Case, c'est la construction que j'ai adopté dans ma procédure.

Désolé de n'avoir pas fait attention et d'avoir donné l'impression que je demandais la même chose. QQfois après le retour du boulot, je suis aide-soignant, je n'ai plus les idées claires. Je m'étais levé à 4h15 et je n'avais pas encore mangé.
Avatar de l’utilisateur
case
Messages : 1527
Inscription : lun. 10/sept./2007 11:13

Re: Monitoring de programme, crash

Message par case »

hub73 a écrit : mar. 06/juil./2021 17:25 Merci pour votre aide. Case, c'est la construction que j'ai adopté dans ma procédure.

Désolé de n'avoir pas fait attention et d'avoir donné l'impression que je demandais la même chose. QQfois après le retour du boulot, je suis aide-soignant, je n'ai plus les idées claires. Je m'étais levé à 4h15 et je n'avais pas encore mangé.
je n'ai pas du tout eu cette impression. ;)
j'essayais de trouver une réponse possible au bug que tu rencontre.
tu peux peut être ajouter des tests pour trouver une réponse a ton souci regarde aussi si la mémoire utilisée par ton programme
augmente sans arrêt ou si cela reste a peu prés identique ce qui indiquerai une fuite mémoire ce qui peux saturer la mémoire disponible et empêcher de charger un son fermer le programme libererai la memoire et permetrait de charger ce son. si le son ne se charge pas c'est qu'il y a une raison derrière

je ne crois pas qu'il s'agisse d'un bug de pure basic il y a donc sûrement une solution :) .

tu peux aussi poster ton code quelque part pour voir si quelqu'un a une idée .

ou ajouter des tests dans ton chargement de son comme je l'ai fait ci dessous pour essayer de trouver pourquoi ca foire.

Code : Tout sélectionner

InitSound ()
sound$="monson.ogg"
If IsSound(mon_son) ; un son existe dans 'mon_son'
   FreeSound(mon_son) ; je libere la memoire utilisée par le son pour eviter des memoryleaks
EndIf
mon_son=LoadSound(#PB_Any,sound$) ; je charge mon_son en memoire
  If IsSound(mon_son) = 0                   ;je teste la validité du son
       reason$="raison inconue"
    Debug( "erreur lors du chargement de "+sound$+".")   
   ; ici tu peux ajouter des tests pour savoir pourquoi ca ne fonctionne pas.
   If FileSize(sound$) <=0
     Debug "fichier non trouvé"
     reason$="fichier n'existe pas ou chemin/nom fichier invalide"
   Else
     mem=AllocateMemory(FileSize(sound$))
     If mem=0
       reason$="pas assez de mémoire"       
     Else
       FreeMemory(mem)
      rd=ReadFile(#PB_Any,sound$)
      sig$=""
       If rd
         For a=1 To 4 
           sig$+Chr(ReadByte(rd))
         Next
         If sig$<>"OggS"
           reason$=" n'est pas au format Ogg"
         EndIf         
         CloseFile(rd)
       Else
         reason$=" le fichier ne peut etre lu"
       EndIf              
     EndIf
   EndIf
	wr=  OpenFile(#PB_Any,"errorlog.txt",#PB_File_Append)  
	WriteStringN(wr, sound$ +" "+ reason$)
	CloseFile(wr)
  EndIf
  
ImageImage
hub73
Messages : 126
Inscription : sam. 16/janv./2021 20:17

Re: Monitoring de programme, crash

Message par hub73 »

- Vraiment très intéressant ce code de test et de traque de bug.
- Je n'avais pas pensé à utiliser le AllocateMemory que je connaissais pas.
- J'ai déjà un fichier log qui trace tout ce que réalise le programme. Et justement en ce moment je le consulte pour essayer de comprendre le soucis.

Code : Tout sélectionner

   mem=AllocateMemory(FileSize(sound$))
     If mem=0
       reason$="pas assez de mémoire"  
Dans mon code j'utilise MemoryStatus(). Je n'ai pas constaté de pic d'utilisation de la mémoire (j'affiche utilisée / disponible) . Je vais ajouter l'AllocateMemory. Si je comprends bien ceci me permet de tester s'il y a encore de la place dans la mémoire vive pour ce fichier. Loadsound doit faire la même chose en s'allouant de la mémoire ? Cette mémoire allouée correspondrait à la taille du fichier sur le disque (filesize) ?

Le problème se produirait sur les fichiers plus volumineux (20 minutes de sons), mais j'attends encore des plantages pour confirmer cette information.

Il ne faut pas oublier qu'en parallèle tourne le programme tiers de rocket broadcaster avec le vst stéreo tool. Ces deux logiciels eux aussi utilisent de la mémoire (que je trace) et envoient le stream ogg vers le serveur distant icecast2 hébergé.
Mon programme envoi également des requêtes Get vers le script php du site qui affiche les informations du contenu lu par la webradio.
hub73
Messages : 126
Inscription : sam. 16/janv./2021 20:17

Re: Monitoring de programme, crash

Message par hub73 »

En lien les sources du programme : (en MP si vous êtes intéressé).

- Merci de ne pas l'exécuter pour ne pas mettre le bazar sur la webradio. (il envoi des requetes vers les scripts php).
- Le programme est : programmation_radio.pb et la procédure Charger_et_jouer_element_liste()
Dernière modification par hub73 le ven. 09/juil./2021 18:29, modifié 1 fois.
Avatar de l’utilisateur
case
Messages : 1527
Inscription : lun. 10/sept./2007 11:13

Re: Monitoring de programme, crash

Message par case »

tu devrais peut être virer les lignes qui envoie des scripts php car si quelqu'un de malveillant ou idiot passe par la...
ImageImage
Répondre