Que se passe-t-il si vous ignorez une erreur X11 BadWindow?

J’ai une application Motif héritée écrite au début des années 1990 (je ne peux pas réécrire l’interface utilisateur dans QT ni même modifier largement l’application sans passer par une évaluation de la sécurité fastidieuse). Cette application fonctionnait sous AIX, où elle fonctionnait pendant des semaines sous utilisation intensive et était stable. Nous l’avons maintenant porté sur Linux. Pendant les tests bêta soutenus sur de longues périodes, l’application s’est écrasée environ une fois par semaine avec le message suivant.

Erreur de demande échouée: BadWindow (paramètre de fenêtre non valide)
Opcode majeur de requête échouée: 4 (X_DestroyWindow)

J’ai depuis appris que ces erreurs peuvent être ignorées en utilisant un gestionnaire d’erreurs X11 personnalisé (le gestionnaire d’erreurs X11 par défaut imprime simplement le message d’erreur et quitte), comme décrit ici:

http://motifdeveloper.com/tips/tip29.html

J’ai implémenté un gestionnaire d’erreur X11 personnalisé qui ignore les erreurs BadWindow décrites dans cet article. Donc, ma question est la suivante: est- ce que quelqu’un qui en sait plus sur le développement de X11 et le fonctionnement interne d’un serveur X que moi peut me dire si les erreurs de BadWindow peuvent vraiment être ignorées?

PS Je vais essayer de déboguer cela en exécutant notre application en mode synchrone, mais cela ralentit car je n’ai aucun moyen de reproduire cette erreur à la demande. Tous les conseils sur le débogage des erreurs BadWindow seraient également appréciés.

Si votre programme consiste en un processus unique (connexion unique à l’affichage X), cette erreur reflétera presque toujours un bogue dans le programme.

Le secret à savoir, c’est comment le déboguer. Comme Xlib est asynchrone, le XDestroyWindow() déclenchera et oubliera certaines opérations post-destruction sur la fenêtre, et il se produira une erreur ultérieurement (pendant un autre appel X sans rapport). Cela signifie qu’une trace de stack de l’erreur X n’a ​​pas de sens et qu’il est difficile de déboguer.

Pour résoudre ce problème, appelez XSynchronize(dpy, True) pour forcer tous les appels à être synchrones. Cela rendra l’application lente, ne le laissez pas en production. http://www.x.org/releases/X11R7.6/doc/man/man3/XSynchronize.3.xhtml

Mais en mode synchronisé, si un appel Xlib utilise une mauvaise fenêtre, il échouera immédiatement. Vous pouvez donc définir un point d’arrêt de débogage, par exemple sur votre fonction de gestionnaire d’erreurs, et obtenir une trace significative. Cela devrait vous montrer quel appel Xlib est à l’origine du problème – et j’espère que cela sera clair s’il s’agit d’une double suppression d’un widget, en utilisant un widget détruit ou quoi.

Si votre application a plusieurs processus ou plusieurs connexions d’affichage, comme dans un gestionnaire de fenêtres, il est possible qu’une BadWindow soit inévitable (si vous essayez d’utiliser la fenêtre d’une autre application, la course est inévitable et la fenêtre de l’autre application peut être détruit). Dans ce cas, ignorer BadWindow est la solution correcte, bien que la meilleure pratique consiste à l’ignorer uniquement pendant les appels connus pour le déclencher, afin que vous puissiez toujours obtenir des erreurs pouvant être des bogues. Un idiome commun pour cela est d’implémenter un error_trap_push() / error_trap_pop() qui installe et error_trap_pop() simplement votre gestionnaire d’erreurs qui ignore les erreurs. Appuyez sur une erreur lorsque vous touchez une fenêtre externe qui pourrait être supprimée en dehors de votre contrôle.

Cela ressemble à un bouton (ou un élément d’interface utilisateur similaire) supprimé plus d’une fois. En règle générale, les boutons sont implémentés en tant que fenêtres dédiées, avec le graphique de bouton qui y est émis, de cette façon, vous pouvez simplement lier le gestionnaire de rappel à un événement de clic dans la fenêtre associée.

L’erreur indique que votre programme a essayé de supprimer un identifiant de fenêtre non existant et que le moyen le plus simple est qu’il a été supprimé deux fois (sinon, quelque chose a changé l’ID enregistré pour un élément d’interface utilisateur).

À ce stade, vous ne voulez pas ignorer l’erreur, vous souhaitez obtenir une journalisation suffisante pour déterminer où se trouve le problème avec votre application.

Dans ce cas, l’erreur vous indique que votre programme a demandé de détruire un identifiant de fenêtre qui n’existe pas. Si vous l’ignorez, alors vous pourriez avoir une fuite de n’importe quelle fenêtre que vous avez vraiment l’intention de détruire; ou vous pouvez simplement essayer de détruire deux fois le même identifiant de fenêtre, et rien ne changera. Sans rechercher la cause première de la raison pour laquelle votre programme appelle XDestroyWindow avec un identifiant invalide, il est difficile de dire ce qui se passe si vous l’ignorez.