IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

GTK+ avec C & C++ Discussion :

erreur du serveur x après un "gtk_widget_show_all"


Sujet :

GTK+ avec C & C++

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Membre averti
    Profil pro
    Inscrit en
    Octobre 2010
    Messages
    56
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Octobre 2010
    Messages : 56
    Par défaut erreur du serveur x après un "gtk_widget_show_all"
    Bonjour à tous,

    J'assaie de faire une application affichant une fenêtre principale (jusqu'ici tout va bien), elle affiche aussi une fenêtre d'attente pendant une transmission sur le port série avec ceci
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
     
    void StartWait(char event)
    {
    	cancel = false;
    	Window_wait = gtk_dialog_new();
    	gtk_window_set_title(GTK_WINDOW(Window_wait), g_strdup_printf("transmission en cours"));
    	switch(event)
    	{
    		case cConf :
    			text_wait = gtk_label_new("veuillez patienter pendant la configuration de la sonde");
    			break;
    		case cCancel_Conf :
    			text_wait = gtk_label_new("veuillez patienter pendant l'annulation des modifications");
    			break;
    		case cIgnor_New :
    			text_wait = gtk_label_new("veuillez patienter pendant la configuration du coordinateur");
    			break;
    		case cAdd_Probe :
    			text_wait = gtk_label_new("veuillez patienter pendant l'ajout de la sonde");
    			break;
    		case cRemove_Probe :
    			text_wait = gtk_label_new("veuillez patienter pendant la suppression de la sonde");
    			break;
    		case cPurge_Rejected :
    			text_wait = gtk_label_new("veuillez patienter pendant la suppression de la liste");
    			break;
    		default :
    			text_wait = gtk_label_new("je ne sais pas ce que j'attends mais j'attends, il y a un bug");
    			break;
    	}
    	spinner_wait = gtk_image_new_from_file("images/patienter.gif");
    	cont_wait = gtk_vbox_new(1, 0);
    	gtk_container_add(GTK_CONTAINER(gtk_dialog_get_content_area (GTK_DIALOG(Window_wait))), cont_wait);
    	gtk_container_add(GTK_CONTAINER(cont_wait), text_wait);
    	gtk_container_add(GTK_CONTAINER(cont_wait), spinner_wait);
    	gtk_widget_show_all(Window_wait);
    }
    Ca va toujours.
    Ensuite quand la transmission est finie, j'appelle la fonction suivante pour détruire la précédente et en créer une nouvelle pour dire que tout s'est bien passé (ou que l'ordinateur va s'autodétruire) :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
     
    void CancelWaitGeneric(const char* title, const char* text)
    {
       lock_wait_window();
       if(cancel == false)
       {
          cancel = true;
          UpdateAll();
          if(GTK_IS_WINDOW(Window_wait))
          {
             gtk_widget_destroy (Window_wait);
          }
          Window_end = gtk_dialog_new_with_buttons(title, 
                                     GTK_WINDOW(sGVar.MainWindow), 
                                     GTK_DIALOG_MODAL | GTK_DIALOG_DESTROY_WITH_PARENT,
                                     GTK_STOCK_OK, GTK_RESPONSE_OK,
                                     NULL);
          text_end = gtk_label_new(text);
          gtk_container_add(GTK_CONTAINER(gtk_dialog_get_content_area (GTK_DIALOG(Window_end))), text_end);
          printf("connect\n");
          g_signal_connect(G_OBJECT(Window_end), "response", G_CALLBACK(CloseWindow_end), NULL);
    //       g_signal_connect(G_OBJECT(Window_end), "delete-event", G_CALLBACK(CloseWindow_end), NULL);
          printf("end connect : showing now\n");
          gtk_widget_show_all(Window_end);
          printf("showed\n");
       }
       unlock_wait_window();
    }
    }
    Et là, je vois sur la console :
    connect
    end connect : showing now

    (probes:10034): Gdk-WARNING **: The program 'probes' received an X Window System error.
    This probably reflects a bug in the program.
    The error was 'RenderBadPicture (invalid Picture parameter)'.
    (Details: serial 3424 error_code 163 request_code 149 minor_code 7)
    (Note to programmers: normally, X errors are reported asynchronously;
    that is, you will receive the error a while after causing it.
    To debug your program, run it with the --sync command line
    option to change this behavior. You can then get a meaningful
    backtrace from your debugger if you break on the gdk_x_error() function.)
    Pour info, CloseWindow_end :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
     
    {
       printf("close wait window\n");
       gtk_widget_destroy(Window_end);
       printf("end close wait_window\n");
    }
    Le crash ne survient pas toujours.
    L'erreur du serveur x apparaît dans les bug 810882, 810767 et autres doublons mais pour le logiciel gnome-settings-daemon.
    J'ai essayé de ne pas supprimer la première fenêtre mais de la modifier pour avoir la seconde (en supprimant le spinner, modifiant le texte et en ajoutant des boutons) mais là, parfois elle se fige, comme si la fonction de callback n'était pas appelée.
    Quelqu'un a-t-il une idée ? je sèche vraiment là, l'affichage semble indiquer que le crash se fait au moment du "gtk_widget_show_all(Window_end)", j'execute mon programme avec l'option --sync.
    configuration : gtk3.0, debian squeeze.
    Merci beaucoup

  2. #2
    Membre confirmé Avatar de Gamall
    Profil pro
    Étudiant ENSEA
    Inscrit en
    Août 2009
    Messages
    252
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations professionnelles :
    Activité : Étudiant ENSEA

    Informations forums :
    Inscription : Août 2009
    Messages : 252
    Par défaut
    Je me souviens avoir déjà eu une erreur comme celle ci, mais c'était pas dans les mêmes circonstances. Tu peux pas regarder avec le debugger, en mettant des breakpoints dans tes fonctions, où se trouve le crash ?

  3. #3
    Membre averti
    Profil pro
    Inscrit en
    Octobre 2010
    Messages
    56
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Octobre 2010
    Messages : 56
    Par défaut
    bonsoir,

    Le temps que j'apprenne (enfin) à me servir d'un debuggeur et je réponds.
    merci.

  4. #4
    Membre confirmé Avatar de Gamall
    Profil pro
    Étudiant ENSEA
    Inscrit en
    Août 2009
    Messages
    252
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations professionnelles :
    Activité : Étudiant ENSEA

    Informations forums :
    Inscription : Août 2009
    Messages : 252
    Par défaut
    Si tu es sous GNU/Linux, tu as Nemiver, c'est ce que j'utilise, et il est vraiment bien, je ne connais pas de meilleure interface pour Gdb

  5. #5
    Modérateur

    Homme Profil pro
    Développeur informatique
    Inscrit en
    Juin 2009
    Messages
    1 395
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : Industrie

    Informations forums :
    Inscription : Juin 2009
    Messages : 1 395
    Par défaut
    Utilises tu des threads ?
    C'est du C++ ? Il manque plein de déclarations de variables.
    Quel est le prototype de la fonction CloseWindow_end ? C'est le plus intéressant et tu ne l'as pas mis...
    Est-ce que le crash survient sans action utilisateur, ou quand tu cliques sur un bouton de la boîte de dialogue ? Perso je penche pour un prototype incorrect pour la callback du signal response...

  6. #6
    Membre averti
    Profil pro
    Inscrit en
    Octobre 2010
    Messages
    56
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Octobre 2010
    Messages : 56
    Par défaut
    Bonjour,
    @artificier59 :
    merci du tuyau, je m'y mets.
    @liberforce
    -J'utilise des threads posix
    -C'est du c (stdc99)
    -le prototype de la fonction CloseWindow_end est :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
     
    void CloseWindow_end(GtkDialog* UNUSED(dialog), gint UNUSED(response_id), gpointer UNUSED(user_data))
    UNUSED est une macro trouvée sur internet pour eviter que gcc râle avec -Wextra (qui comprends -Wunused-parameter) et elle vaut :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
     
    #ifdef UNUSED 
    #elif defined(__GNUC__) 
    # define UNUSED(x) UNUSED_ ## x __attribute__((unused)) 
    #elif defined(__LCLINT__) 
    # define UNUSED(x) /*@unused@*/ x 
    #else 
    # define UNUSED(x) x 
    #endif
    En enlevant unused, j'ai le même resultat, avec des warning à la compilation en plus.
    Mais je ne pense pas que le problème soit là car en faisant directement
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
     
    g_signal_connect(G_OBJECT(Window_end), "response", G_CALLBACK(gtk_widget_destroy), Window_end);
    au lieu de
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
     
    g_signal_connect(G_OBJECT(Window_end), "response", G_CALLBACK(CloseWindow_end), Window_end);
    l'erreur survient également (la différence est que je connecte directement gtk_widget_destroy comme dans l'exemple donné par gtk pour les GtkDialog.
    -Les trois fonctions sont seuls dans un fichier avec des variables globales :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
     
    //wait
    GtkWidget* Window_wait;
    GtkWidget* cont_wait;
    GtkWidget* spinner_wait;
    GtkWidget* text_wait;
    //end
    GtkWidget* Window_end;
    GtkWidget* text_end;
    //cancel
    bool cancel;
    -Le crash survient quand cancel wait generic est appelée, soit par un thread lisant sur le port com soit par un timer, c'est à dire sans action utilisateur.
    J'espère avoir répondu à tout,
    merci

  7. #7
    Membre averti
    Profil pro
    Inscrit en
    Octobre 2010
    Messages
    56
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Octobre 2010
    Messages : 56
    Par défaut
    Voilà la trace donnée par nemiver (effectivement, c'est bien pratique) en pièce jointe.
    Il y a un assert fail peu avant le abort, je pense que c'est celui ci :
    probes: ../../src/xcb_io.c*:140*:*dequeue_pending_request: L'assertion «*req == dpy->xcb->pending_requests*» a échoué.
    Abandon
    Parfois l'erreur x est en version longue et parfois j'ai juste ceci.
    J'ai mis une image car je ne pouvais pas copier/coller la liste. (comment ca la refaire à la main ?)
    merci.
    Images attachées Images attachées  

  8. #8
    Modérateur

    Homme Profil pro
    Développeur informatique
    Inscrit en
    Juin 2009
    Messages
    1 395
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : Industrie

    Informations forums :
    Inscription : Juin 2009
    Messages : 1 395
    Par défaut
    Citation Envoyé par autre mickael Voir le message
    Le crash survient quand cancel wait generic est appelée, soit par un thread lisant sur le port com soit par un timer, c'est à dire sans action utilisateur.
    C'est sans doute la source du problème. Comme la majorité des toolkits, GTK n'est pas thread-safe. Cela veut dire que la manipulation d'objets graphiques ne fonctionne pas de manière transparente à partir d'autres threads. Il y a alors 2 techniques: passer des types primitifs entre ton thread et le thread principal, afin de signaler au thread principal qu'il doit effectuer des actions. L'autre solution est d'utiliser un mécanisme de lock avec gdk_threads_enter et gdk_threads_leave.


    http://developer.gnome.org/gdk/stabl...ds.description

+ Répondre à la discussion
Cette discussion est résolue.

Discussions similaires

  1. [MySQL] Syntaxe erreur apres avoir mis un quote '
    Par AyManoVic dans le forum PHP & Base de données
    Réponses: 3
    Dernier message: 12/07/2010, 16h50

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo