2017-10-03 20 views
0

아주 간단한 화면 보호기는 몇 시간 동안 훌륭하게 작동하고 갑자기 화면이 검게 변하며 CPU가 90 %로 이동합니다. 메모리 소비량은 4kB 씩 증가하며 변경되지 않습니다.Xlib : 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 

편집 : 또 다른 스레드가 이벤트를 처리합니다. 프로그램이 많은 CPU를 소비하기 시작하면 아무것도 출력되지 않습니다. 즉 이벤트가 없습니다. (gcore 명령에 의해 코어 덤프 사용)

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); 
    } 
} 

GDB 출력 : 대

(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?) 

감사/해결하는 방향을 조언한다.

나는 근본 원인을 찾을 수 - 서버의 Xorg 1.19.2 (데비안 9.1)

+1

디버깅 도움말을 찾는 질문 ("이 코드가 작동하지 않는 이유는 무엇입니까?")에는 질문 자체에서이를 재현하는 데 필요한 가장 짧은 코드가 포함되어야합니다. [MCVE]를 만드는 방법을 읽어보십시오. – tambre

+1

gcore를 시도 했습니까? 최고의 CPU 사용 순간에 이미지 덤프를 얻고 디버깅을 시도하십시오. 제발 - g 컴파일 된 버전을 실행하고 있는지 확인하십시오 :) 누군가가 이미 수정을하지 않는 한 stackoverflow 공개 알고 그 대답은 ... –

+1

당신은'XNextEvent' 또는 비슷한 사용해야합니다. X11 서버 *는 이벤트를 보내고 있습니다 (간단한 응용 프로그램이라 할지라도). 당신은 그들을 처리해야합니다 (ICCCM & EWMH 다음) –

답변

0

아니었지만, 문제는 이벤트를 처리하는 두 번째 스레드를 제거함으로써 해결된다.
대신 메인 루프에 비 차단 기능 XCheckTypedEvent()을 추가했습니다. 원래 문제는 어떻게 든 멀티 스레딩과 관련이있었습니다 : 두 번째 스레드가 XNextEvent()을 차단하는 이벤트 대기 중 (대기 이벤트 없음)에도 불구하고 주 루프가 몇 시간 후에 실패했습니다.