web-dev-qa-db-fra.com

XIO: fatal IO erreur 11

Oui, cette question a déjà été posée, mais la lecture des réponses ne m'a pas beaucoup éclairé.

J'ai écrit un programme C qui plante après quelques jours d'utilisation. Un point important est qu'il ne génère PAS de fichier core, même si tout est configuré pour qu'il le fasse (core_pattern, ulimit -c unlimited, etc. Je peux déclencher un vidage de mémoire fin avec kill -SIGQUIT).

Le programme enregistre largement ce qu'il fait, mais il n'y a aucune indication sur le plantage dans le journal. Le seul message affiché lors du crash (ou avant?) Est:

XIO:  fatal IO error 11 (Resource temporarily unavailable) on X server ":0"
  after 2322 requests (2322 known processed) with 0 events remaining.

Donc deux questions: - comment est-il possible qu'un programme plante (retourne $? = 1) sans vidage de mémoire. - à quoi sert ce message d'erreur et que puis-je faire?

Le système est RedHat Enterprise 6.4

Edit: J'ai réussi à forcer un vidage de mémoire en appelant abort () depuis un rappel atexit ():

(gdb) bt
#0  0x00bc8424 in __kernel_vsyscall ()
#1  0x0085a861 in raise () from /lib/libc.so.6
#2  0x0085c13a in abort () from /lib/libc.so.6
#3  0x0808f5cf in Unexpected () at MyCode.c:1378
#4  0x0085de9f in exit () from /lib/libc.so.6
#5  0x00c85701 in _XDefaultIOError () from /usr/lib/libX11.so.6
#6  0x00c85797 in _XIOError () from /usr/lib/libX11.so.6
#7  0x00c84055 in _XReply () from /usr/lib/libX11.so.6
#8  0x00c68b8f in XGetImage () from /usr/lib/libX11.so.6
#9  0x004fd6a7 in ?? () from /usr/local/lib/libcvi.so
#10 0x00478ad5 in ?? () from /usr/local/lib/libcvi.so
...
#29 0x001eed9d in ?? () from /usr/local/lib/libcvi.so
#30 0x001eee41 in RunUserInterface () from /usr/local/lib/libcvi.so
#31 0x0808fab4 in main (argc=2, argv=0xbfbdc984) at MyCode.c:1540

N'importe qui peut m'éclairer sur ce problème X11? libcvi.so n'est pas à moi, seulement MyCode.c (LabWindows/CVI).

Edit 2014-12-05: Voici un backtrace encore plus précis. Il se passe certainement des choses dans X11, mais je ne suis pas un programmeur X11, donc en regardant le code source de X à partir de la ligne fournie, dites-moi seulement que le serveur X (?) Est temporairement indisponible. Existe-t-il un moyen de simplement lui dire d'ignorer cette erreur si elle n'est que temporaire?

#4  0x00965eaf in __run_exit_handlers (status=1) at exit.c:78
#5  exit (status=1) at exit.c:100
#6  0x00c356b1 in _XDefaultIOError (dpy=0x88aeb80) at XlibInt.c:1292
#7  0x00c35747 in _XIOError (dpy=0x88aeb80) at XlibInt.c:1498
#8  0x00c340a6 in _XReply (dpy=0x88aeb80, rep=0xbf82fa90, extra=0, discard=0) at xcb_io.c:708
#9  0x00c18c0f in XGetImage (dpy=0x88aeb80, d=27263845, x=0, y=0, width=60, height=20, plane_mask=4294967295, format=2) at GetImage.c:75
#10 0x005f46a7 in ?? () from /usr/local/lib/libcvi.so

Lignes correspondantes:

XlibInt.c: _XDefaultIOError()
1292:   exit(1);

XlibInt.c: _XIOError
1498:   _XDefaultIOError(dpy);

xcb_io.c: _XReply()
708:    if(!reply) _XIOError(dpy);

GetImage.c: XGetImage()
74: if (_XReply (dpy, (xReply *) &rep, 0, xFalse) == 0 || ...
15
dargaud

OK, j'ai finalement trouvé la cause (grâce à quelqu'un chez National Instruments), un meilleur diagnostic et une solution de contournement.

Le bogue est présent dans de nombreuses versions de libxcb et est un problème de retournement de compteur 32 bits connu depuis quelques années: https://bugs.freedesktop.org/show_bug.cgi?id=71338

Toutes les versions de libxcb ne sont pas affectées par libxcb-1.9-5, pas par libxcb-1.5-1. À partir de la liste des bogues, le système d'exploitation 64 bits ne devrait pas être affecté, mais j'ai réussi à le déclencher sur au moins une version.

Ce qui m'amène à un meilleur diagnostic. Le programme suivant plantera en moins de 15 minutes sur les bibliothèques concernées (mieux que toute la semaine précédente):

// Compile with: gcc test.c -lX11 && time ./a.out
#include <X11/Xlib.h>
void main(void) {
    Display *d = XOpenDisplay(NULL);
    if (d)
     for(;;)
        XNoOp(d);
}

Et une dernière chose, le prog ci-dessus compilé et exécuté sur un système 64 bits fonctionne bien, compilé et exécuté sur un ancien système 32 bits fonctionne également très bien, mais si je transfère la version 32 bits vers le système 64 bits, il se bloque après quelques minutes.

10
dargaud

Je viens d'avoir un programme qui a agi exactement comme ça, avec exactement le même message d'erreur. Je m'attendrais à ce que l'erreur de compteur traite 2 ^ 32 événements avant de planter.

Le programme a été structuré de manière à ce qu'un thread de travail dispose d'une connexion X distincte au thread X afin qu'il puisse envoyer des messages au thread X pour mettre à jour la fenêtre.

À la fin, j'ai retracé le problème jusqu'à un endroit où la fonction envoyant les événements à la fenêtre pour la redessiner a été appelée par plusieurs threads, sans mutex dessus, et puisque X vers la même connexion X n'est pas rentrant, s'est écrasé avec cette erreur exacte. Mettez un mutex sur la fonction et aucun problème depuis.

4
camelccc