X raccroche à cause de l’application (utilisez C ++, Qt, OpenGL)

Mon application obtient des données du réseau et les dessine sur la scène (la scène utilise un moteur OpenGL à la main).

Cela fonctionne pendant plusieurs heures. Lorsque je n’utilise pas mon bureau, mon moniteur, en raison de l’affichage de la signalisation Display Manager (dpms), s’éteint. Et puis, lorsque je touche la souris ou le clavier, le moniteur s’allume et l’application raccroche (X raccroche aussi).

Si je fais xset -dmps le système d’exploitation n’utilise pas dpms et l’application fonctionne de manière stable.

Ces problèmes se produisent dans Centos 6 et Archlinux, mais lorsque je lance l’application sous Ubuntu 12.10, cela fonctionne très bien!

J’ai essayé différents pilotes NVidia. Aucun effet.

J’ai essayé d’utiliser ssh pour la connexion à distance et me connecter au processus avec gdb. Après que le moniteur est allumé, je ne trouve pas l’application dans la table de processus.

Comment diagnostiquer le problème? Que se passe-t-il (dans l’environnement OpengGL) lorsque le moniteur est éteint / allumé? Ubuntu fait-il quelque chose de spécial en utilisant dpms?

Nous avons une idée pour des raisons de problème! Lorsque le moniteur est éteint, nous perdons le contexte OpenGL. Lorsque le moniteur se réveille, l’application se bloque (pas de contexte). Et la différence de comportement en fonction du système d’exploitation est due à des connexions de moniteur différentes: Le moniteur pour Kubuntu est connecté avec un câble VGA. Et donc (probablement) cela n’a aucune influence sur le comportement de X.

Avez-vous essayé d’append un support de robustesse à votre implémentation OpenGL en utilisant GL_ARB_robustness ?

2.6 “Récupération graphique”

Certains événements peuvent entraîner une réinitialisation du contexte GL. Une telle réinitialisation entraîne la perte de tous les états du contexte. La récupération de ces événements nécessite la recréation de tous les objects dans le contexte affecté. L’état actuel de l’état de réinitialisation graphique est renvoyé par

 enum GetGraphicsResetStatusARB(); 

La constante symbolique renvoyée indique si le contexte GL a été à un moment donné depuis le dernier appel à GetGraphicsResetStatusARB. NO_ERROR indique que le contexte GL n’a pas été mis à jour depuis le dernier appel. GUILTY_CONTEXT_RESET_ARB indique qu’une réinitialisation atsortingbuable au contexte GL en cours a été détectée. INNOCENT_CONTEXT_RESET_ARB indique qu’une réinitialisation n’a pas été détectée dans le contexte GL actuel. UNKNOWN_CONTEXT_RESET_ARB indique une réinitialisation graphique détectée dont la cause est inconnue.

Assurez-vous également d’avoir un contexte de débogage lorsque vous initialisez votre contexte et utilisez l’extension ARB_debug_output pour recevoir la sortie du journal.

 void DebugMessageControlARB(enum source, enum type, enum severity, sizei count, const uint* ids, boolean enabled); void DebugMessageInsertARB(enum source, enum type, uint id, enum severity, sizei length, const char* buf); void DebugMessageCallbackARB(DEBUGPROCARB callback, const void* userParam); uint GetDebugMessageLogARB(uint count, sizei bufSize, enum* sources, enum* types, uint* ids, enum* severities, sizei* lengths, char* messageLog); void GetPointerv(enum pname, void** params); 

Par exemple:

 // Initialize GL_ARB_debug_output ASAP if (glfwExtensionSupported("GL_ARB_debug_output")) { typedef void APIENTRY (*glDebugMessageCallbackARBFunc) (GLDEBUGPROCARB callback, const void* userParam); typedef void APIENTRY (*glDebugMessageControlARBFunc) (GLenum source, GLenum type, GLenum severity, GLsizei count, const GLuint* ids, GLboolean enabled); auto glDebugMessageCallbackARB = (glDebugMessageCallbackARBFunc) glfwGetProcAddress("glDebugMessageCallbackARB"); auto glDebugMessageControlARB = (glDebugMessageControlARBFunc) glfwGetProcAddress("glDebugMessageControlARB"); glDebugMessageCallbackARB(debugCallback, this); glDebugMessageControlARB(GL_DONT_CARE, GL_DONT_CARE, GL_DEBUG_SEVERITY_LOW_ARB, 0, nullptr, GL_TRUE); } 

 std::ssortingng GlfwThread::severitySsortingng(GLenum severity) { switch (severity) { case GL_DEBUG_SEVERITY_LOW_ARB: return "LOW"; case GL_DEBUG_SEVERITY_MEDIUM_ARB: return "MEDIUM"; case GL_DEBUG_SEVERITY_HIGH_ARB: return "HIGH"; default: return "??"; } } std::ssortingng GlfwThread::sourceSsortingng(GLenum source) { switch (source) { case GL_DEBUG_SOURCE_API_ARB: return "API"; case GL_DEBUG_SOURCE_WINDOW_SYSTEM_ARB: return "SYSTEM"; case GL_DEBUG_SOURCE_SHADER_COMPILER_ARB: return "SHADER_COMPILER"; case GL_DEBUG_SOURCE_THIRD_PARTY_ARB: return "THIRD_PARTY"; case GL_DEBUG_SOURCE_APPLICATION_ARB: return "APPLICATION"; case GL_DEBUG_SOURCE_OTHER_ARB: return "OTHER"; default: return "???"; } } std::ssortingng GlfwThread::typeSsortingng(GLenum type) { switch (type) { case GL_DEBUG_TYPE_ERROR_ARB: return "ERROR"; case GL_DEBUG_TYPE_DEPRECATED_BEHAVIOR_ARB: return "DEPRECATED_BEHAVIOR"; case GL_DEBUG_TYPE_UNDEFINED_BEHAVIOR_ARB: return "UNDEFINED_BEHAVIOR"; case GL_DEBUG_TYPE_PORTABILITY_ARB: return "PORTABILITY"; case GL_DEBUG_TYPE_PERFORMANCE_ARB: return "PERFORMANCE"; case GL_DEBUG_TYPE_OTHER_ARB: return "OTHER"; default: return "???"; } } // Note: this is static, it is called from OpenGL void GlfwThread::debugCallback(GLenum source, GLenum type, GLuint id, GLenum severity, GLsizei, const GLchar *message, const GLvoid *) { std::cout << "source=" << sourceString(source) << " type=" << typeString(type) << " id=" << id << " severity=" << severityString(severity) << " message=" << message << std::endl; AssertBreak(type != GL_DEBUG_TYPE_ERROR_ARB); } 

Vous avez presque certainement les deux extensions disponibles sur une implémentation OpenGL décente. Ils aident beaucoup . Les contextes de débogage valident tout et se plaignent du journal. Ils donnent même des suggestions de performances dans la sortie du journal dans certaines implémentations OpenGL. Utiliser ARB_debug_output rend obsolète la vérification de glGetError - il vérifie pour vous chaque appel.

Vous pouvez commencer par consulter les journaux de X, généralement situés dans / var / log /, et ~ / .xsession-errors. Il n’est pas exclu que OpenGL fasse quelque chose de fâché, donc si votre application a une connexion, allumez-la. Activez les ulimit -c unlimited exécutant ulimit -c unlimited . Vous pouvez parsingr le vidage en l’ouvrant dans gdb comme ceci:

 gdb   

Voyez si cela produit quelque chose d’utile, alors recherchez quoi que ce soit.