2017-10-03 7 views
0

Un économiseur d'écran très simple fonctionne très bien pendant plusieurs heures, puis soudainement l'écran devient noir et le CPU passe à 90%. La consommation de mémoire saute juste de 4kB et reste inchangée. haut de sortieXlib: un simple programme consomme 90% CPU

while (1) 
{ 
    XClearWindow(dpy, win); 
    // draw a logo 259x64 pixels 
    XPutImage(dpy, win, gc, img, 0, 0, random()%(WIDTH-LOGO_WIDTH), random()%(HEIGHT-LOGO_HEIGHT), LOGO_WIDTH, LOGO_HEIGHT); 
    XFlush(dpy); 
    usleep (DELAY_US); // 1 sec delay 
} 

:

PID USER  PR NI VIRT RES SHR S %CPU %MEM  TIME+ COMMAND         
    2717 aspen 20 0 12580 1868 1504 R 91.5 0.4 838:05.68 screensaver 

EDIT: Un autre thread traite les événements. Lorsque le programme commence à consommer beaucoup de CPU, rien n'est imprimé, c'est-à-dire qu'il n'y a pas d'événements.

static events() 
{ 
    XNextEvent (dpy, &event); 
    switch (event.type) 
    { 
     case ButtonPress: 
      XCloseDisplay (dpy); 
      printf ("Let's go work!\n"); 
      exit (1); 
     default: 
      printf ("Event: %d\n", event.type); 
    } 
} 

sortie GDB (en utilisant noyau largué par gcore):

(gdb) thread 1 
[Switching to thread 1 (Thread 0xb6f21000 (LWP 2654))] 
#0 0xb6e22ffa in _XReply() from /usr/lib/arm-linux-gnueabihf/libX11.so.6 
(gdb) bt 
#0 0xb6e22ffa in _XReply() from /usr/lib/arm-linux-gnueabihf/libX11.so.6 
#1 0xb6e24b2c in ??() from /usr/lib/arm-linux-gnueabihf/libX11.so.6 
Backtrace stopped: previous frame identical to this frame (corrupt stack?) 
(gdb) thread 2 
[Switching to thread 2 (Thread 0xb6c54470 (LWP 2655))] 
#0 0xb6d60580 in poll() at ../sysdeps/unix/syscall-template.S:84 
84  in ../sysdeps/unix/syscall-template.S 
(gdb) bt 
#0 0xb6d60580 in poll() at ../sysdeps/unix/syscall-template.S:84 
#1 0xb6cb3ec4 in ??() from /usr/lib/arm-linux-gnueabihf/libxcb.so.1 
Backtrace stopped: previous frame identical to this frame (corrupt stack?) 

Merci de conseille/directions pour dépanner.

xorg-server 1.19.2 (Debian 9.1)

+1

Les questions sur l'aide au débogage ("pourquoi ce code ne fonctionne-t-il pas?") Doivent inclure le code le plus court nécessaire pour le reproduire dans la question elle-même. Veuillez lire comment créer un [MCVE]. – tambre

+1

Avez-vous essayé gcore? Essayez d'obtenir un vidage d'image au moment de l'utilisation du processeur et de débogage. S'il vous plaît assurez-vous que vous exécutez une version compilée -g :) Il n'y a aucun moyen que le public stackoverflow connaisse cette réponse, à moins que quelqu'un ait déjà un correctif ... –

+1

Vous devriez utiliser 'XNextEvent' ou quelque chose de similaire. Le serveur X11 * envoie des * événements (même pour des applications simples). Vous devez les traiter (suivant ICCCM & EWMH) –

Répondre

0

Je n'ai pas pu trouver la cause racine, mais le problème est résolu en supprimant le second fil qui a été le traitement des événements.
Au lieu de cela j'ai ajouté une fonction non-bloquante XCheckTypedEvent() dans la boucle principale. Donc, le problème original était en quelque sorte lié au multi-threading: même si le second thread était inactif en attente d'événements (et il n'y avait aucun événement!) Avec le blocage XNextEvent(), la boucle principale a échoué après plusieurs heures.