Contenu | Rechercher | Menus

Annonce

DVD, clés USB et t-shirts Ubuntu-fr disponibles sur la boutique En Vente Libre

Si vous avez des soucis pour rester connecté, déconnectez-vous puis reconnectez-vous depuis ce lien en cochant la case
Me connecter automatiquement lors de mes prochaines visites.

À propos de l'équipe du forum.

#176 Le 05/02/2020, à 19:09

Elzen

Re : /* Topic des codeurs [9] */

Dafyd a écrit :

Désolé j’ai pas beaucoup de temps libre en ce moment hmm

Ben pas de souci, c'est surtout pour toi que ce n'est pas chouette.

grim7reaper a écrit :

Alors oui dans l’absolu c’est possible partout.
Après en Python je ne pense pas (sauf bug de l’interpréteur), car il fait beaucoup de chose sur le tas.
un StackOverflow c’est un crash violent comme une segfault quoi.
Autant j’ai déjà vu des MemoryError ou des RecursionError en Python (voire des segfault quand j’appelle du C depuis Python), autant une stack overflow pas encore (d’où ma surprise).

Je m'étais dis que j'allais te filer, à toute fin utile, la trace récupérée dans le terminal pour que tu puisses te faire une idée, sauf que, bien évidemment, je n'en ai gardé aucune des plantages précédents, et ça fait quelques heures que ce message est rédigé par ailleurs et attend d'être envoyé sans qu'il n'y en ait l'ombre d'une qui se produise ^^ Donc bon, j'arrête d'attendre et je te montrerai ça à l'occasion dans un autre post.

Edit : ah, bah, j'ai fini par l'avoir ^^
Donc, si ça t'intéresse :

Fatal Python error: Cannot recover from stack overflow.

Thread 0x00007efe8503c700 (most recent call first):
  File "/opt/touhy/lib/elzlibs/shared.py", line 125 in wait
  File "/usr/lib/python3.7/threading.py", line 870 in run
  File "/usr/lib/python3.7/threading.py", line 926 in _bootstrap_inner
  File "/usr/lib/python3.7/threading.py", line 890 in _bootstrap

Thread 0x00007efe8583d700 (most recent call first):
  File "/opt/touhy/lib/elzlibs/shared.py", line 125 in wait
  File "/usr/lib/python3.7/threading.py", line 870 in run
  File "/usr/lib/python3.7/threading.py", line 926 in _bootstrap_inner
  File "/usr/lib/python3.7/threading.py", line 890 in _bootstrap

Thread 0x00007efe87fff700 (most recent call first):
  File "/opt/touhy/lib/elzlibs/shared.py", line 125 in wait
  File "/usr/lib/python3.7/threading.py", line 870 in run
  File "/usr/lib/python3.7/threading.py", line 926 in _bootstrap_inner
  File "/usr/lib/python3.7/threading.py", line 890 in _bootstrap

Thread 0x00007efea4f5a700 (most recent call first):
  File "/opt/touhy/lib/elzlibs/calls.py", line 184 in wait
  File "/usr/lib/python3.7/threading.py", line 870 in run
  File "/usr/lib/python3.7/threading.py", line 926 in _bootstrap_inner
  File "/usr/lib/python3.7/threading.py", line 890 in _bootstrap

Thread 0x00007efea575b700 (most recent call first):
  File "/opt/touhy/lib/elzlibs/shared.py", line 103 in wait
  File "/usr/lib/python3.7/threading.py", line 870 in run
  File "/usr/lib/python3.7/threading.py", line 926 in _bootstrap_inner
  File "/usr/lib/python3.7/threading.py", line 890 in _bootstrap

Thread 0x00007efea5f5c700 (most recent call first):
  File "/usr/lib/python3.7/socket.py", line 212 in accept
  File "/opt/touhy/lib/elzlibs/shared.py", line 89 in wait
  File "/usr/lib/python3.7/threading.py", line 870 in run
  File "/usr/lib/python3.7/threading.py", line 926 in _bootstrap_inner
  File "/usr/lib/python3.7/threading.py", line 890 in _bootstrap

Thread 0x00007efea675d700 (most recent call first):
  File "/opt/touhy/lib/sencol/joypads/sfml.py", line 61 in mainloop
  File "/usr/lib/python3.7/threading.py", line 870 in run
  File "/usr/lib/python3.7/threading.py", line 926 in _bootstrap_inner
  File "/usr/lib/python3.7/threading.py", line 890 in _bootstrap

Thread 0x00007efea6f5e700 (most recent call first):
  File "/usr/lib/python3.7/socket.py", line 212 in accept
  File "/opt/touhy/lib/elzlibs/shared.py", line 89 in wait
  File "/usr/lib/python3.7/threading.py", line 870 in run
  File "/usr/lib/python3.7/threading.py", line 926 in _bootstrap_inner
  File "/usr/lib/python3.7/threading.py", line 890 in _bootstrap

Current thread 0x00007efec2ffd700 (most recent call first):
  File "/opt/touhy/lib/elzlibs/utils.py", line 131 in keys
  File "/opt/touhy/lib/elzlibs/types/__init__.py", line 25 in __getitem__
  File "/opt/touhy/lib/elzlibs/types/__init__.py", line 22 in __getitem__
  File "/opt/touhy/lib/elzlibs/types/__init__.py", line 18 in __call__
  File "/opt/touhy/lib/elzlibs/types/iter.py", line 12 in check
  File "/opt/touhy/lib/elzlibs/types/iter.py", line 39 in parse
  File "/opt/touhy/lib/elzlibs/types/__init__.py", line 110 in parse
  File "/opt/touhy/lib/elzlibs/types/__init__.py", line 18 in __call__
  File "/opt/touhy/lib/elzlibs/images/gears.py", line 105 in reframe
  File "/opt/touhy/lib/elzlibs/images/plans.py", line 80 in perform
  File "/opt/touhy/lib/elzlibs/images/plans.py", line 83 in perform
  File "/opt/touhy/lib/elzlibs/images/plans.py", line 103 in perform
  File "/opt/touhy/lib/elzlibs/images/plans.py", line 103 in perform
  File "/opt/touhy/lib/elzlibs/images/plans.py", line 119 in perform
  File "/opt/touhy/lib/elzlibs/images/plans.py", line 103 in perform
  File "/opt/touhy/lib/elzlibs/images/plans.py", line 103 in perform
  File "/opt/touhy/lib/elzlibs/images/__init__.py", line 20 in icon
  File "/opt/touhy/lib/sencol/clips/__init__.py", line 21 in update
  File "/opt/touhy/lib/elzlibs/calls.py", line 126 in threaded
  File "/opt/touhy/lib/elzlibs/calls.py", line 199 in safely
  File "/opt/touhy/lib/elzlibs/calls.py", line 29 in __call__
  File "/opt/touhy/lib/elzlibs/calls.py", line 70 in warn
  File "/opt/touhy/lib/elzlibs/entities/clip.py", line 32 in updates
  File "/opt/touhy/lib/_elzlibs_gtk3/entities/clip.py", line 32 in change
  File "/opt/touhy/lib/_elzlibs_gtk3/entities/clip.py", line 41 in read
  File "/opt/touhy/lib/elzlibs/calls.py", line 126 in threaded
  File "/opt/touhy/lib/elzlibs/entities/clip.py", line 114 in read
  File "/opt/touhy/lib/elzlibs/entities/clip.py", line 100 in replacement
  File "/opt/touhy/lib/elzlibs/images/plans.py", line 235 in text
  File "/opt/touhy/lib/elzlibs/images/gears.py", line 220 in clip
  File "/opt/touhy/lib/elzlibs/images/plans.py", line 80 in perform
  File "/opt/touhy/lib/elzlibs/images/plans.py", line 103 in perform
  File "/opt/touhy/lib/elzlibs/images/plans.py", line 103 in perform
  File "/opt/touhy/lib/elzlibs/images/plans.py", line 103 in perform
  File "/opt/touhy/lib/elzlibs/images/plans.py", line 121 in perform
  File "/opt/touhy/lib/elzlibs/images/plans.py", line 103 in perform
  File "/opt/touhy/lib/elzlibs/images/plans.py", line 103 in perform
  File "/opt/touhy/lib/elzlibs/images/__init__.py", line 20 in icon
  File "/opt/touhy/lib/sencol/clips/__init__.py", line 21 in update
  File "/opt/touhy/lib/elzlibs/calls.py", line 126 in threaded
  File "/opt/touhy/lib/elzlibs/calls.py", line 199 in safely
  File "/opt/touhy/lib/elzlibs/calls.py", line 29 in __call__
  File "/opt/touhy/lib/elzlibs/calls.py", line 70 in warn
  File "/opt/touhy/lib/elzlibs/entities/clip.py", line 32 in updates
  File "/opt/touhy/lib/_elzlibs_gtk3/entities/clip.py", line 32 in change
  File "/opt/touhy/lib/_elzlibs_gtk3/entities/clip.py", line 41 in read
  File "/opt/touhy/lib/elzlibs/calls.py", line 126 in threaded
  File "/opt/touhy/lib/elzlibs/entities/clip.py", line 114 in read
  File "/opt/touhy/lib/elzlibs/entities/clip.py", line 100 in replacement
  File "/opt/touhy/lib/elzlibs/images/plans.py", line 235 in text
  File "/opt/touhy/lib/elzlibs/images/gears.py", line 220 in clip
  File "/opt/touhy/lib/elzlibs/images/plans.py", line 80 in perform
  File "/opt/touhy/lib/elzlibs/images/plans.py", line 103 in perform
  File "/opt/touhy/lib/elzlibs/images/plans.py", line 103 in perform
  File "/opt/touhy/lib/elzlibs/images/plans.py", line 103 in perform
  File "/opt/touhy/lib/elzlibs/images/plans.py", line 121 in perform
  File "/opt/touhy/lib/elzlibs/images/plans.py", line 103 in perform
  File "/opt/touhy/lib/elzlibs/images/plans.py", line 103 in perform
  File "/opt/touhy/lib/elzlibs/images/__init__.py", line 20 in icon
  File "/opt/touhy/lib/sencol/clips/__init__.py", line 21 in update
  File "/opt/touhy/lib/elzlibs/calls.py", line 126 in threaded
  File "/opt/touhy/lib/elzlibs/calls.py", line 199 in safely
  File "/opt/touhy/lib/elzlibs/calls.py", line 29 in __call__
  File "/opt/touhy/lib/elzlibs/calls.py", line 70 in warn
  File "/opt/touhy/lib/elzlibs/entities/clip.py", line 32 in updates
  File "/opt/touhy/lib/_elzlibs_gtk3/entities/clip.py", line 32 in change
  File "/opt/touhy/lib/_elzlibs_gtk3/entities/clip.py", line 41 in read
  File "/opt/touhy/lib/elzlibs/calls.py", line 126 in threaded
  File "/opt/touhy/lib/elzlibs/entities/clip.py", line 114 in read
  File "/opt/touhy/lib/elzlibs/entities/clip.py", line 100 in replacement
  File "/opt/touhy/lib/elzlibs/images/plans.py", line 235 in text
  File "/opt/touhy/lib/elzlibs/images/gears.py", line 220 in clip
  File "/opt/touhy/lib/elzlibs/images/plans.py", line 80 in perform
  File "/opt/touhy/lib/elzlibs/images/plans.py", line 103 in perform
  File "/opt/touhy/lib/elzlibs/images/plans.py", line 103 in perform
  File "/opt/touhy/lib/elzlibs/images/plans.py", line 103 in perform
  File "/opt/touhy/lib/elzlibs/images/plans.py", line 121 in perform
  File "/opt/touhy/lib/elzlibs/images/plans.py", line 103 in perform
  File "/opt/touhy/lib/elzlibs/images/plans.py", line 103 in perform
  File "/opt/touhy/lib/elzlibs/images/__init__.py", line 20 in icon
  File "/opt/touhy/lib/sencol/clips/__init__.py", line 21 in update
  File "/opt/touhy/lib/elzlibs/calls.py", line 126 in threaded
  File "/opt/touhy/lib/elzlibs/calls.py", line 199 in safely
  File "/opt/touhy/lib/elzlibs/calls.py", line 29 in __call__
  File "/opt/touhy/lib/elzlibs/calls.py", line 70 in warn
  File "/opt/touhy/lib/elzlibs/entities/clip.py", line 32 in updates
  File "/opt/touhy/lib/_elzlibs_gtk3/entities/clip.py", line 32 in change
  File "/opt/touhy/lib/_elzlibs_gtk3/entities/clip.py", line 41 in read
  File "/opt/touhy/lib/elzlibs/calls.py", line 126 in threaded
  File "/opt/touhy/lib/elzlibs/entities/clip.py", line 114 in read
  File "/opt/touhy/lib/elzlibs/entities/clip.py", line 100 in replacement
  File "/opt/touhy/lib/elzlibs/images/plans.py", line 235 in text
  File "/opt/touhy/lib/elzlibs/images/gears.py", line 220 in clip
  File "/opt/touhy/lib/elzlibs/images/plans.py", line 80 in perform
  File "/opt/touhy/lib/elzlibs/images/plans.py", line 103 in perform
  File "/opt/touhy/lib/elzlibs/images/plans.py", line 103 in perform
  File "/opt/touhy/lib/elzlibs/images/plans.py", line 103 in perform
  File "/opt/touhy/lib/elzlibs/images/plans.py", line 121 in perform
  File "/opt/touhy/lib/elzlibs/images/plans.py", line 103 in perform
  File "/opt/touhy/lib/elzlibs/images/plans.py", line 103 in perform
  ...

Thread 0x00007efec37fe700 (most recent call first):
  File "/usr/lib/python3.7/socket.py", line 212 in accept
  File "/opt/touhy/lib/elzlibs/shared.py", line 89 in wait
  File "/usr/lib/python3.7/threading.py", line 870 in run
  File "/usr/lib/python3.7/threading.py", line 926 in _bootstrap_inner
  File "/usr/lib/python3.7/threading.py", line 890 in _bootstrap

Thread 0x00007efec3fff700 (most recent call first):
  File "/usr/lib/python3.7/socket.py", line 212 in accept
  File "/opt/touhy/lib/elzlibs/shared.py", line 89 in wait
  File "/usr/lib/python3.7/threading.py", line 870 in run
  File "/usr/lib/python3.7/threading.py", line 926 in _bootstrap_inner
  File "/usr/lib/python3.7/threading.py", line 890 in _bootstrap

Thread 0x00007efee0e3d700 (most recent call first):
  File "/usr/lib/python3.7/socket.py", line 212 in accept
  File "/opt/touhy/lib/elzlibs/shared.py", line 89 in wait
  File "/usr/lib/python3.7/threading.py", line 870 in run
  File "/usr/lib/python3.7/threading.py", line 926 in _bootstrap_inner
  File "/usr/lib/python3.7/threading.py", line 890 in _bootstrap

Thread 0x00007efee163e700 (most recent call first):
  File "/usr/lib/python3.7/socket.py", line 212 in accept
  File "/opt/touhy/lib/elzlibs/shared.py", line 89 in wait
  File "/usr/lib/python3.7/threading.py", line 870 in run
  File "/usr/lib/python3.7/threading.py", line 926 in _bootstrap_inner
  File "/usr/lib/python3.7/threading.py", line 890 in _bootstrap

Thread 0x00007efee1e3f700 (most recent call first):
  File "/usr/lib/python3.7/socket.py", line 212 in accept
  File "/opt/touhy/lib/elzlibs/shared.py", line 89 in wait
  File "/usr/lib/python3.7/threading.py", line 870 in run
  File "/usr/lib/python3.7/threading.py", line 926 in _bootstrap_inner
  File "/usr/lib/python3.7/threading.py", line 890 in _bootstrap

Thread 0x00007efee2640700 (most recent call first):
  File "/opt/touhy/lib/elzlibs/shared.py", line 223 in modchecker
  File "/usr/lib/python3.7/threading.py", line 870 in run
  File "/usr/lib/python3.7/threading.py", line 926 in _bootstrap_inner
  File "/usr/lib/python3.7/threading.py", line 890 in _bootstrap

Thread 0x00007efee2e41700 (most recent call first):
  File "/usr/lib/python3.7/socket.py", line 212 in accept
  File "/opt/touhy/lib/elzlibs/shared.py", line 89 in wait
  File "/usr/lib/python3.7/threading.py", line 870 in run
  File "/usr/lib/python3.7/threading.py", line 926 in _bootstrap_inner
  File "/usr/lib/python3.7/threading.py", line 890 in _bootstrap

Thread 0x00007efee3682700 (most recent call first):
  File "/opt/touhy/lib/elzlibs/calls.py", line 184 in wait
  File "/usr/lib/python3.7/threading.py", line 870 in run
  File "/usr/lib/python3.7/threading.py", line 926 in _bootstrap_inner
  File "/usr/lib/python3.7/threading.py", line 890 in _bootstrap

Thread 0x00007efee3e83700 (most recent call first):
  File "/usr/lib/python3.7/socket.py", line 212 in accept
  File "/opt/touhy/lib/elzlibs/shared.py", line 89 in wait
  File "/usr/lib/python3.7/threading.py", line 870 in run
  File "/usr/lib/python3.7/threading.py", line 926 in _bootstrap_inner
  File "/usr/lib/python3.7/threading.py", line 890 in _bootstrap

Thread 0x00007efee4684700 (most recent call first):
  File "/usr/lib/python3.7/socket.py", line 212 in accept
  File "/opt/touhy/lib/elzlibs/shared.py", line 89 in wait
  File "/usr/lib/python3.7/threading.py", line 870 in run
  File "/usr/lib/python3.7/threading.py", line 926 in _bootstrap_inner
  File "/usr/lib/python3.7/threading.py", line 890 in _bootstrap

Thread 0x00007efee947f740 (most recent call first):
  File "/usr/lib/python3.7/threading.py", line 296 in wait
  File "/usr/lib/python3.7/queue.py", line 170 in get
  File "/opt/touhy/lib/elzlibs/calls.py", line 210 in mainloop
  File "/opt/touhy/lib/elzlibs/utils.py", line 87 in selfdestructing
  File "/opt/touhy/lib/sencol/__main__.py", line 54 in <module>
  File "<frozen importlib._bootstrap>", line 219 in _call_with_frames_removed
  File "<frozen importlib._bootstrap_external>", line 728 in exec_module
  File "<frozen importlib._bootstrap>", line 677 in _load_unlocked
  File "<frozen importlib._bootstrap>", line 967 in _find_and_load_unlocked
  File "<frozen importlib._bootstrap>", line 983 in _find_and_load
  File "<frozen importlib._bootstrap>", line 219 in _call_with_frames_removed
  File "<frozen importlib._bootstrap>", line 1035 in _handle_fromlist
Abandon

Re-edit : et du coup, vu que j'étais précisément en train de faire quelques petites retouches sur ce qui semble être le module coupable, j'en profite pour inspecter ça… Ces deux lignes-là en particulier attirent mon attention :

  File "/opt/touhy/lib/_elzlibs_gtk3/entities/clip.py", line 32 in change
  File "/opt/touhy/lib/_elzlibs_gtk3/entities/clip.py", line 41 in read

Elles sont placées successivement, donc un appel suit immédiatement l'autre. Or, la méthode read n'appelle à aucun moment la méthode change. En revanche, à ce qui était jusque là la ligne 41 (c'est en train de changer ^^), on trouve « clip(selection).wait_for_text() », et la méthode change est branchée sur l'événement « owner-change » du presse-papier GTK. Puisque la méthode wait_for_text() peut laisser passer plusieurs itérations de la boucle principale GTK avant de renvoyer son résultat, je suppose donc que ce qui cause le crash doit être la modification du contenu du presse-papier pendant que sencol est en train de générer les images montrant ledit contenu (quand c'est du texte, il fait un petit aperçu où on voit les premiers caractères). Modification du contenu qui déclenche la mise à jour desdites images, et donc une sorte d'appel récursif.
Ceci dit, vu que c'est au niveau de la mécanique interne de GTK (et que tout se passe dans le thread GTK, pas de souci d'accès concurent à ce niveau), à part essayer de débrancher l'écouteur de modifications le temps de finir la lecture, je ne vois pas trop ce qui est faisable…

(En parlant de crash violents : d'après le collègue spécialiste dudit langage avec qui j'ai donné quelques cours au semestre dernier, en C#, il ne serait pas possible de récupérer d'une division par zéro ? yikes)

grim7reaper a écrit :

Là je pensais qu’on était dans un cas où on nous parlera plus jamais.

A priori, c'est bien le cas : ce sont les cas où le fichier qui servait à identifier la socket a été supprimé, donc je ne pense pas qu'il y ait moyen de la récupérer dans ce cas (ceci dit, j'ai tendance dans mon code à utiliser socket.sendto pour communiquer avec les socket DGRAM, donc sans passer par socket.connect, mais, je viens de vérifier, c'est tout à fait possible de connecter la socket d'abord, puis de supprimer le fichier, puis de continuer à envoyer des choses qui sont bien reçues).

Un comportement possiblement intelligent serait, plutôt qu'un message qui termine le thread directement, d'envoyer un message qui fait que le thread vérifie si son fichier existe toujours et se termine si ce n'est pas le cas ? (En utilisant dans ce cas la manip' sus-mentionnées pour que le message arrive après la suppression effective du fichier, tant qu'à faire).

D'ailleurs, ce même message pourrait aussi servir à vérifier que le programme est toujours à l'écoute, au cas où il aurait lamentablement crashé sans nettoyer proprement derrière lui…

grim7reaper a écrit :

Ça serait pas déconnant tongue
J’ai découvert qu’il y avait une espèce de guerre trébuchet vs catapulte similaire à tab vs space ou Vim vs Emacs tongue
Genre ici ^^

Oui, c'est pour ça que je disais ça smile
(Mais on me souffle dans l'oreillette que les gens de LineageOS y ont déjà pensé)

Sinon, on vient de me suggérer de partir plutôt sur les lanceurs de fusée. En anglais, ça s'appelle « Launch Vehicle » (pas forcément très cool à utiliser), mais aussi « Carrier Rocket ». Du coup, je me dit que « crocket » pourrait être un nom sympa, qu'en dites-vous ? ^^

Dernière modification par Elzen (Le 05/02/2020, à 20:16)

Hors ligne

#177 Le 06/02/2020, à 08:16

grim7reaper

Re : /* Topic des codeurs [9] */

Elzen a écrit :

Edit : ah, bah, j'ai fini par l'avoir ^^

Ho, en effet!
C’est bien la première fois que je vois ça ^^

Je pensais que t’aurais toujours une RecursionError propre avant ça.
Mais gars disait

The recursion limit is just a guard to limit the likelihood of a stack overflow, but if you allocate large objects on every stack frame, you can still overflow.

C’est peut-être ton cas ici.
Où alors c’est le code C de GTK qui crash et ça remonte jusqu’a Python (plus probable).

Elzen a écrit :

(En parlant de crash violents : d'après le collègue spécialiste dudit langage avec qui j'ai donné quelques cours au semestre dernier, en C#, il ne serait pas possible de récupérer d'une division par zéro ? yikes)

Bah en C c’est impossible aussi (sur des entiers du moins, encore qu’en POSIX y’a moyen de moyenner mais c’est un terrain miné).
Par contre je ne connais pas du tout C# mais ça semble possible.

Elzen a écrit :

c'est tout à fait possible de connecter la socket d'abord, puis de supprimer le fichier, puis de continuer à envoyer des choses qui sont bien reçues).

Je pense que c’est comme les fichiers, tant qu’il est ouvert il est pas réellement supprimé (même si tu rm, il existe toujours dans le kernel/sur le disque, juste tu ne le vois plus).
Ça peut-être utile des fois (annuler un rm mal placé) et des fois c’est chiant.


Elzen a écrit :

Sinon, on vient de me suggérer de partir plutôt sur les lanceurs de fusée. En anglais, ça s'appelle « Launch Vehicle » (pas forcément très cool à utiliser), mais aussi « Carrier Rocket ». Du coup, je me dit que « crocket » pourrait être un nom sympa, qu'en dites-vous ? ^^

Ouais , «crocket» c’est pas mal (même si je pense pas que beaucoup de gens feront le rapprochement ^^).

Dernière modification par grim7reaper (Le 06/02/2020, à 08:17)

Hors ligne

#178 Le 19/02/2020, à 16:22

Elzen

Re : /* Topic des codeurs [9] */

Allez, quelques nouvelles smile

grim7reaper a écrit :

Où alors c’est le code C de GTK qui crash et ça remonte jusqu’a Python (plus probable).

big_smile

J'ai fini par refaire de très gros bouts de la gestion du presse-papier, et, normalement, le souci ne devrait plus arriver. Je laisse tourner un moment avant de commiter pour être sûr ^^

Edit : commité entre temps, par contre j'ai quand même eu une belle stack overflow quand même hier soir, donc ç't'assez déprimant hmm Je n'ai pas regardé en détail, il reste possible que ça vienne d'un autre bout de code, mais d'un autre côté, c'est arrivé une seule fois depuis la rédaction de ce message, donc au minimum la fréquence d'arrivée a été réduite, c'est déjà ça.

grim7reaper a écrit :

Bah en C c’est impossible aussi (sur des entiers du moins, encore qu’en POSIX y’a moyen de moyenner mais c’est un terrain miné).

Oui, mais, C n'a pas de mécanisme natif de try/catch, à ma connaissance⁽¹⁾.

Autant, une stack overflow, je peux comprendre, mais qu'une division par zéro ne puisse pas être interceptée de cette façon-là, ça me semble étrange. Mais bon smile

grim7reaper a écrit :

Je pense que c’est comme les fichiers, tant qu’il est ouvert il est pas réellement supprimé (même si tu rm, il existe toujours dans le kernel/sur le disque, juste tu ne le vois plus).
Ça peut-être utile des fois (annuler un rm mal placé) et des fois c’est chiant.

Oui, je me souvenais de cet article ^^

Comment on s'y prend, pour l'annulage de rm, tiens ? Ça pourrait m'être utile de temps en temps :-°

Sinon, j'ai donc fait la manip' pour que les socket DGRAM s'arrêtent proprement en cas de suppression (j'envoie un caractère \5 pour dire au programme de vérifier si son fichier est toujours là ou pas, dites si vous voyez plus approprié comme message).
Le problème reste en revanche pour les sockets STREAM : les connexions des clients se ferment sans problème ; mais le thread qui attend les connexions, pour sa part, reste vraisemblablement à attendre éternellement (ce n'est pas un recv() mais un listen(), mais je n'sais pas interrompre ça non plus). Après, dans mon code en tout cas, les sockets STREAM sont très rarement supprimées, donc bon, 'pas très grave.

grim7reaper a écrit :

Ouais , «crocket» c’est pas mal (même si je pense pas que beaucoup de gens feront le rapprochement ^^).

Certes ^^ Il faudrait une jolie petite icône de fusée, pour le fun, mais je n'ai pas le talent pour ça. Il y a quand même « Carrier Rocket » écrit en toutes lettres comme titre de la fenêtre, donc c'est possiblement affiché par le gestionnaire de fenêtres au alt+tab (en tout cas, c'est le cas avec Xfwm).


Sinon, donc, globalement, après plusieurs jours d'utilisation, la nouvelle version me plaît bien smile
Par contre, la motivation manque beaucoup pour finir les trucs qui restent à faire dans SenCol, comme prévu :-° J'ai des entités en état de marche pour l'audio (avec AlsaAudio), le réseau (avec Wicd, d'ailleurs j'en ai profité pour faire du rapport de bugs), les manettes (SFML), le presse-papiers, les tablettes graphiques, la batterie et la température (avec ACPI pour ces deux derniers),  et il me reste à gérer les disques durs, l'écran, la souris d'une manière générale, et le clavier (pour ces deux derniers, j'aimerais que l'entité permette de simuler des déplacements/clics/appuis de touches, c'est tout à fait faisable, mais avec de la Xlib, donc pas enthousiasmant…).

Tiens, d'ailleurs, au sujet du clavier : en Python 2, j'utilisais xklavier pour récupérer la disposition active et des intitulés localisés pour les différentes dispositions disponibles. Sauf que ça passait par un module python-xklavier qui reposait lui-même sur GObject, donc forcément, ça n'a pas été porté. Je ne trouve pas de python3-xklavier à vue de nez, et il n'y a pas l'air non plus d'y avoir ce qui va bien dans GIrepository. Quelqu'un aurait des infos là-dessus ou sur une bibli à utiliser à la place ?

Edit : question subsidiaire, vu que grim a du *BSD sous la main smile Pour les supports de stockage, avec le noyau Linux, on a conventionnellement :

  • /dev/sd* pour les disques durs (c'était /dev/hd*, avant, non ? Pourquoi ça a changé ?),

  • /dev/mmcblk* pour les cartes SD,

  • /dev/sr* pour les CD/DVD,

  • /dev/fd* pour les disquettes (enfin, si ça existe encore, ces machins tongue),

  • /dev/loop* utilisé pour le montage des images disques (il me semble).

Par contre, il me semble (vagues souvenirs de Debian GNU/kFreeBSD ^^) que ça varie selon les noyaux, donc vous sauriez où on peut trouver une liste, ou si non, me dire ce que ça donne chez vous comme noms ?

(Sinon, une fois terminé SenCol, il me restera à faire une appli pour gérer un peu mieux les fenêtres (pour permettre de contrôler à la manette les fenêtres pour lesquelles c'est pertinent, passer des fenêtres en négatif quand c'est possible, ou effectuer des actions arbitraires, par exemple cacher la souris et les notifications quand un lecteur PDF est en plein écran), et quand ça ce sera fait, ce sera normalement fini pour les outils d'arrière-plan de l'environnement, et je pourrai enchaîner sur des applis un peu plus sympas)


(1) Ce qui me fait penser que j'avais à une époque un T-shirt (malheureusement plus utilisable) avec la mention :

while(!succeed=try());

Il y a d'autres langages que le C où ça marche, vu que try est un mot-clef réservé à peu près partout ailleurs ?

Dernière modification par Elzen (Le 21/02/2020, à 11:13)

Hors ligne

#179 Le 04/03/2020, à 12:36

grim7reaper

Re : /* Topic des codeurs [9] */

Elzen a écrit :

Edit : commité entre temps, par contre j'ai quand même eu une belle stack overflow quand même hier soir, donc ç't'assez déprimant hmm Je n'ai pas regardé en détail, il reste possible que ça vienne d'un autre bout de code, mais d'un autre côté, c'est arrivé une seule fois depuis la rédaction de ce message, donc au minimum la fréquence d'arrivée a été réduite, c'est déjà ça.

Ha, chiant.
Mais si c’est plus rare c’est déjà ça de pris.

Elzen a écrit :

Oui, mais, C n'a pas de mécanisme natif de try/catch, à ma connaissance⁽¹⁾.
Autant, une stack overflow, je peux comprendre, mais qu'une division par zéro ne puisse pas être interceptée de cette façon-là, ça me semble étrange. Mais bon smile

Doit y avoir moyen de faire des trucs avec SIGFPE et/ou longjmp, mais je pense que c’est pas fiable du tout.
Mais bon, comme je donnais dans mon lien ça semble gérable en C# en tout cas (le contraire serait surprenant en effet).

Elzen a écrit :

Comment on s'y prend, pour l'annulage de rm, tiens ? Ça pourrait m'être utile de temps en temps :-°

Annuler est peut-être pas le bon mot, mais si le fichier est encore ouvert par un programme, tu vas trouver le fd dans /proc/<PID>/fd/<FD> et tu peux le cat/cp pour récupérer son contenu.

Elzen a écrit :

(j'envoie un caractère \5 pour dire au programme de vérifier si son fichier est toujours là ou pas, dites si vous voyez plus approprié comme message).

EOT: \4

Elzen a écrit :

mais le thread qui attend les connexions, pour sa part, reste vraisemblablement à attendre éternellement (ce n'est pas un recv() mais un listen(), mais je n'sais pas interrompre ça non plus).

C’est bloquant le listen? Me semblait que c’est le accept qui l'était.
shutdown devrait faire le taf pourtant.

Elzen a écrit :

Il y a quand même « Carrier Rocket » écrit en toutes lettres comme titre de la fenêtre, donc c'est possiblement affiché par le gestionnaire de fenêtres

Ouais donc ça aide à la compréhension, en effet ^^

Elzen a écrit :

Quelqu'un aurait des infos là-dessus ou sur une bibli à utiliser à la place ?

Je ne connais pas d’alternative, et une rapide recherche n’a rien donné.
Tu l’utilisais pour faire quoi?

Elzen a écrit :

Edit : question subsidiaire, vu que grim a du *BSD sous la main smile Pour les supports de stockage, avec le noyau Linux, on a conventionnellement :

  • /dev/sd* pour les disques durs (c'était /dev/hd*, avant, non ? Pourquoi ça a changé ?),

  • /dev/mmcblk* pour les cartes SD,

  • /dev/sr* pour les CD/DVD,

  • /dev/fd* pour les disquettes (enfin, si ça existe encore, ces machins tongue),

  • /dev/loop* utilisé pour le montage des images disques (il me semble).

Par contre, il me semble (vagues souvenirs de Debian GNU/kFreeBSD ^^) que ça varie selon les noyaux, donc vous sauriez où on peut trouver une liste, ou si non, me dire ce que ça donne chez vous comme noms ?

Pour le sd vs hd c’est la différence entre SCSI (sd) et IDE (hd) (cf. ici)
Les loop device c’est utilisé pour le montage de disque en effet, mais pas uniquement.

Les *BSD que j’ai sous la main ce sont des serveurs remote donc jpeux pas vraiment vérifier pour lecteur CD ou disquette mais en gros j’ai vu du da* et du ada*.
Ça semble correspondre à ce que je vois .


Elzen a écrit :

(1) Ce qui me fait penser que j'avais à une époque un T-shirt (malheureusement plus utilisable) avec la mention :

while(!succeed=try());

Il y a d'autres langages que le C où ça marche, vu que try est un mot-clef réservé à peu près partout ailleurs ?

Ruby et Perl je pense (pour rester dans de la syntaxe C-like).

Hors ligne

#180 Le 12/09/2020, à 19:37

Laërte

Re : /* Topic des codeurs [9] */

Bonjour tout le monde, Elzen m’a dit que je pourrais peut-être trouver de l’aide ici donc je tente le coup.

C’est un programme en C qui me pose soucis, plus précisément la valeur de retour de fread. Si je me fie à la doc,

fread(ptr, size, count, file)

me renvoie la quantité de données lues, en bytes (sous réserve que size vaille 1, ce qui est le cas ici). Jusque là pas de soucis, je lis un joli bout de 512000 bytes et un petit

printf("%i", read_data)

m’affiche bien 512000.

C’est quand la bibliothèque zlib rentre en jeu que rien ne va plus.

L’idée c’est que je veux compresser mes données fraîchement lues. Du coup, un petit coup de

compress(dstbuffer, &dstbuffer_size, ptr, read_data)

, et je me retrouve avec mes données compressées dans dstbuffer, et dstbuffer_size a comme valeur la taille compressée des données. Sauf que: read_data vaut désormais 0! Et ça c’est chiant, déjà parce que je lui ai jamais demandé de modifier read_data (ce n’est pas un pointeur que je lui passe), ensuite parce que je me sers de cette variable dans la suite de mon programme et que ça m’arrange pas trop qu’elle soit réinitialisée…

Par contre, je sais que compress modifie ptr: elle le fait avancer d’autant de données compressées avec succès. Donc, si toutes mes données sont compressées, ptr est à la fin de la chaîne, et est donc un pointeur NULL. Je me dis que la réinitialisation de read_data vient peut-être de là, puisque c’est normalement la quantité de données lues, les données en question étant stockées dans ptr. Mais encore une fois, read_data c’est sensé être un gentil size_t callé dans un coin de ma mémoire, et il ne devrait pas bouger quand je touche à ptr.

Je vous mets un bout de code ci-dessous:

    /* Read data from file into buffer */
    read_data = fread(srcbuffer, 1, 512000, infile);
    printf("read_data: %i\n",read_data);
    /* Compress data */
    returnval = compress(dstbuffer, (unsigned long *)&size_compressed, srcbuffer, read_data);
    printf("read_data: %i\n",read_data);

Qui me renvoie:

read_data: 512000
read_data: 0

Est-ce quelqu’un comprend ce qu’il se passe et pourrait m’aider?
Merci!

Hors ligne

#181 Le 14/09/2020, à 14:52

grim7reaper

Re : /* Topic des codeurs [9] */

Salut Laërte,

Est-ce que tu aurais un exemple minimal & compilable qui reproduit le problème (genre un programme qui lit un fichier, le compresse et qui à le bug que tu rencontres)?

Sinon, quand il y’a des variables qui changent de valeurs magiquement comme ça, c’est souvent signe de corruption mémoire (buffer overflow, …).
Tu as essayé de lancer Valgrind sur ton programme?

Hors ligne

#182 Le 14/09/2020, à 18:10

Elzen

Re : /* Topic des codeurs [9] */

Au fait, j'avais oublié de repasser ici répondre, désolé ^^'

grim7reaper a écrit :
Elzen a écrit :

(j'envoie un caractère \5 pour dire au programme de vérifier si son fichier est toujours là ou pas, dites si vous voyez plus approprié comme message).

EOT: \4

J'ai pas mal hésité entre les deux, mais il me semble que si c'est pour dire au programme de vérifier, c'est qu'on demande, donc enquiry va un peu mieux, non ? Enfin, de toute façon, j'ai pas mal changé le système depuis.

grim7reaper a écrit :

C’est bloquant le listen? Me semblait que c’est le accept qui l'était.
shutdown devrait faire le taf pourtant.

Oui, j'ai foncondu les deux ^^ Je ne suis pas sûr de savoir exactement comment on est censé utiliser shutdown, il faudra que je me repenche là-dessus à l'occasion.

grim7reaper a écrit :

Je ne connais pas d’alternative, et une rapide recherche n’a rien donné.
Tu l’utilisais pour faire quoi?

Essentiellement, repérer quel mapping clavier est actuellement actif, avec un joli nom localisé et tout smile

J'ai remarqué récemment qu'il était bien dans le GIr, mais sous le nom de « Xkl », forcément, ça n'aide pas à repérer. Ceci dit, entre temps, j'ai fait tout le reste de ce dont j'avais besoin pour gérer le clavier en utilisant la Xlib, donc bon ^^ Je n'ai pas encore trouvé comment obtenir le nom de la dispo clavier active (localisé ou pas), mais ce pourrait être cool d'avoir ce choix-là en plus. Pas bien important, ceci dit.


Sinon, je me suis donc remis au code sur Touhy il y a une semaine ou deux (après une grosse coupure, d'où l'absence de réponse ici), en faisant pas mal d'améliorations sur le fonctionnement de la bibli pour la rendre encore plus chouette, je tâcherai de vous faire un semblant de doc' quand j'aurai le courage. Pour le moment, je me focalise sur Tuco (le lanceur de jeu), parce que c'est un bon moyen de bosser sur une bonne partie des trucs chiants à faire (qui finalement, après mes retouches actuelles, sont loin de l'être tant que ça) comme le clavier, les fenêtres, etc., et il faudra que j'impacte les modifs sur le reste du code quand ce sera prêt, mais au moins j'pourrai facilement me faire des pauses jeu vidéo après ça :-°

En gros, les changements principaux fait sur la bibliothèque :
– Séparation propre entre le code de base et ce qui utilise des dépendances optionnelles (psutil, cairo/PIL pour les images, etc.), avec un outil qui liste automatiquement les modules pythons/commandes externes utilisées par dépôt.
– Gestion un peu plus transparente des threads (pour lire les sockets, par exemple, ça se lance en arrière-plan automatiquement et ça te ramène le message dans le thread principal).
– Mécanisme d'entités partagées amélioré et mieux intégré, notamment les fichiers sont maintenant directement des entités de base, et le système de listing des entités existantes a été revu.
– Quelques petites améliorations sur la communication entre les processus, avec notamment le retour de la possibilité de lancer un programme en standalone (sans daemon à l'arrière-plan) quand c'est pertinent.
Globalement, je trouve que ces quelques petites retouches rendent l'utilisation du truc encore plus simple et agréable qu'avant smile

Hors ligne

#183 Le 14/09/2020, à 19:46

Laërte

Re : /* Topic des codeurs [9] */

grim7reaper a écrit :

Salut Laërte,

Est-ce que tu aurais un exemple minimal & compilable qui reproduit le problème (genre un programme qui lit un fichier, le compresse et qui à le bug que tu rencontres)?

Sinon, quand il y’a des variables qui changent de valeurs magiquement comme ça, c’est souvent signe de corruption mémoire (buffer overflow, …).
Tu as essayé de lancer Valgrind sur ton programme?

Alors, de fait, avec l’aide de captnfab sur #play.it, j’ai réussi à trouver le soucis. C’était lié au type de mes variables. Elles étaient pour une bonne part en uint32_t (parce que je devais les écrire dans un fichier et fallait qu’elles fassent exactement 4 bytes), ce qui n’allait pas avec le type attendu par compress (entre autres).

Donc passer les variables dans les types appropriés (unsigned long, size_t, etc.), et convertir au moment de l’écriture seulement (quitte à créer d’autres variables qui ne servent qu’à accueillir la conversion avant l’écriture) a résolu le problème.

Pour les curieux, le code qui posait souci est ici: https://forge.dotslashplay.it/snippets/10

Merci pour ton aide toutefois grim7reaper, et puisqu’on y est, m’expliquerais-tu ce qu’est Valgrind et à quoi il sert? big_smile

Hors ligne

#184 Le 14/09/2020, à 23:24

grim7reaper

Re : /* Topic des codeurs [9] */

Alors Valgrind c’est un outil très pratique pour déboguer des erreurs assez difficile à comprendre.

C’est un logiciel qui peut faire pas mal de truc, mais sa fonctionnalité la plus connue c’est de vérifier l’utilisation de la mémoire.

En gros, il surveille toutes les allocations/déallocation de mémoire, et aussi tout les accès mémoire (lecture et écriture).
Grâce à ça, il peut détecter tout un tas d’erreurs, du genre utilisation de mémoire déjà libérée ou lecture en dehors d’une zone allouée, qui sont difficile à étudier car une petite erreur peut changer le comportement du programme 1000 lignes plus loin, et pas de façon systématique ^^"

Ça s’utilise aussi simplement que :

valgrind ./mon_binaire

Du fait de son fonctionnement interne, ça ralenti de beaucoup la vitesse d’exécution (mais c’est rarement un souci sur de petits programmes).
De nos jours, il a des mécanismes dans clang et gcc quifont peu ou prou la même chose : il faut les activer à la compilation, et ils ont un impact moindre sur les performances.

Si tu veux plus de détails sur comment ça fonctionne sous le capot, j’avais écris un article sur le sujet (autopromo tongue)

Hors ligne

#185 Le 19/09/2020, à 15:51

Laërte

Re : /* Topic des codeurs [9] */

Bonjour tout le monde,
je continue à pratiquer mon C tranquillement, et je tombe sur une autre erreur (toujours dans le même programme). L’erreur en question c’est :

free(): double free detected in tcache 2

Grâce aux (nombreux) messages de debug que j’ai intégré à mon programme, j’ai pu identifier la fonction exacte qui me sort ce soucis. Je pensais au départ que c’était dû à un free que j’y utilisais, mais après avoir jeté un œil à valgrind (merci grim7reaper!), en fait c’est realloc() qui fout la merde.

Donc plutôt que de passer des heures à essayer de trouver pourquoi il ne marche pas, je vais vous expliquer pourquoi je m’en sers, et vous demander comment je peux faire autrement. big_smile

Dans mon programme j’ai cette structure:

typedef struct
  /* structure representing a file to be compressed into a bzf archive */
{
  uint32_t fname_l;         // filename length
  uint32_t dirname_l;       // dirname length
  uint32_t numchunks;       // number of chunks compressed
  uint32_t compressed_size; // total compressed size, including infos
  char *fname;              // filename
  char *dirname;            // dirname
} bzfile;

En gros c’est tout plein d’informations dont j’ai besoin à propos d’un fichier, avant de compresser le fichier et de l’insérer dans une archive.
Pour initialiser un truc comme ça, je fais quelque chose du genre:

/* Allocate memory for structure */
fprop = (bzfile *)malloc(sizeof(bzfile));
/* Get dir and file names’ length */
fprop->dirname_l = (uint32_t)strlen(dirname);
fprop->fname_l = (uint32_t)strlen(filename);
/* Allocate memory for names */
fprop->dirname = (char *)malloc(fprop->dirname_l + 1);
fprop->fname = (char *)malloc(fprop->fname_l + 1);
/* Fill in file properties */
strcpy(fprop->dirname, dirname);
strcpy(fprop->fname, filename);

Bon, déjà rien que ça ça ne me semble pas super chouette: j’ai beaucoup trop de malloc, et si je fais un free(fprop), est-ce que ses attributs dirname et fname sont aussi libérés, j’en doute, bref, c’est pas top.

Mais c’est pas tout! Des trucs comme ça, il m’en faut tout une liste! big_smile (Ce ne serait pas drôle sinon.) Et je dis bien une liste et pas un tableau: je n’en connais pas le nombre à l’avance. Du coup, en pratique, ça ressemble plus à ça:

      /* Allocate memory for files prop */
      fprop = (bzfile **)extend((char *)fprop, (*files_count + 1) * sizeof(bzfile *));
      fprop[*files_count] = (bzfile *)malloc(sizeof(bzfile));
      /* Get dir and file names’ length */
      fprop[*files_count]->dirname_l = (uint32_t)strlen(dirname);
      fprop[*files_count]->fname_l = (uint32_t)strlen(filename);
      /* Allocate memory for names */
      fprop[*files_count]->dirname = (char *)malloc(fprop[*files_count]->dirname_l + 1);
      fprop[*files_count]->fname = (char *)malloc(fprop[*files_count]->fname_l + 1);
      /* Fill in file properties */
      strcpy(fprop[*files_count]->dirname, dirname);
      strcpy(fprop[*files_count]->fname, filename);
      /* Increase files count */
      (*files_count)++;

(Vous aurez compris que le tout est inséré dans une boucle.)

Où extend(char* ptr, int size) est une fonction de ma création qui étend la mémoire allouée à ptr jusqu’à une taille de size. Je vous en mets le code là, elle est relativement courte et vous pourrez me faire des retours dessus comme ça:

char* extend(char *ptr, size_t new_size)
  /* Extends a pointer */
{
  /* Reallocates memory in a temporary pointer */
  char* tmp = realloc(ptr, new_size); // temporary pointer

  if(tmp != NULL)
  {
    /* Allocation succeded, change pointer */
    ptr = tmp;
  }
  else
  {
    /* Allocation failed: quit or free memory */
    fprintf(stderr, "Memory allocation error");
    exit(-1);
    /*
    free(ptr);
    ptr = NULL; /**/
  }
  return ptr;
}

Bon, même en admettant que je n’utilise pas cette structure (cette liste de structures!) en respectant les bons usages, c’est une approche qui tend à multiplier les erreurs possible, en particulier les trucs relous du genre double free qui ne sont pas faciles à débugger, voire qui m’amène à créer des UB au petit bonheur la chance. Donc plutôt que d’essayer de débugguer ce code un peu crâde, qu’est-ce que vous me conseilleriez comme structure de données pour ce genre de problème?

Pour rappel, le problème en question c’est: j’ai besoin des informations ci-dessus pour une quantité de fichiers dont j’ignore la taille (et je ne peux pas les traiter au fur et à mesure: il me faut toutes les stocker en mémoire).

Merci!

Hors ligne

#186 Le 19/09/2020, à 21:07

Laërte

Re : /* Topic des codeurs [9] */

Hehe, bon j’ai trouvé tout seul pour finir. cool

Le soucis c’était que non seulement j’allouais ma mémoire dans une boucle, mais également dans une fonction récursive. Eh ouais… Et quand je réallouais dans une itération de ma fonction, bah en ressortant j’avais l’ancienne adresse en mémoire, que je tentais de réallouer lors du tour de boucle suivant, et ça marchait pas, et pour cause, ç’avait déjà été réalloué, donc libéré, et en tentant de réallouer une deuxième fois, je tentais de libérer une deuxième fois, d’où le double free.

Modifier ma fonction récursive pour qu’elle renvoie la dernière adresse de ma liste de pointeurs, et récupérer cette adresse lors de l’appel a résolu le soucis.

Hors ligne

#187 Le 20/09/2020, à 00:52

grim7reaper

Re : /* Topic des codeurs [9] */

Laërte a écrit :

si je fais un free(fprop), est-ce que ses attributs dirname et fname sont aussi libérés, j’en doute, bref, c’est pas top.

Comme tu t’en doutais, la mémoire des attributs ne sera pas libéré.
En générale, quand on a des structures de ce genre il est pratique de faire deux fonctions : une qui alloue les ressources pour la structure (create_bzfile, alloc_bzfile, …) et une qui fait la libération (free_bzfile, destroy_bzfile, …)

Sinon, strcpy est une fonction assez dangereuse.
Comme tu connais la taille de la string dans le cas présent, tu pourrais utiliser memcpy.
Ou sinon, si tu code en POSIX, tu peux utiliser strdup.

Laërte a écrit :

qu’est-ce que vous me conseilleriez comme structure de données pour ce genre de problème?

Une liste chaînée éviterai les realloc à répétition, mais bon y’a pas de solutions miracle : en C tu finis souvent par te recoder ton type string, ton type array, … (où tu utilises une bibliothèque qui le fait pour toi).

Hors ligne