Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

100% cpu after Xorg exits #33

Open
phromo opened this issue May 14, 2018 · 5 comments
Open

100% cpu after Xorg exits #33

phromo opened this issue May 14, 2018 · 5 comments

Comments

@phromo
Copy link

phromo commented May 14, 2018

I run a single user system and I frequently start and exit X through xrdp. The start of aw-watcher-window is part of my wm launching configuration (.i3/config in my case). When Xorg exits aw-watcher-window goes to 100% cpu usage. I've written https://gist.github.com/phromo/6a41be2bc4d716751eee2eb29856d4bb as a workaround, but that's not the proper way to do it :)

@johan-bjareholt
Copy link
Member

This is primarily an issue with your startup method rather than a activitywatch.

In unix/linux if a process dies it kills all of its children, so if you start aw-watcher-window straight from a terminal window (without tmux or something like that) it will close when you close the window, the same thing goes for your windowmanager. Personally at home I run bspwm and have aw-server running as a systemd service while I start aw-watcher-{window,afk} in my .xinitrc which works fine even after I restart the wm.
I run i3 at my work computer where i simply exec aw-qt in my .i3/config aswell, but have not tested to restart it without restarting my whole computer, will try that when I have the time.

However, even if aw-watcher-window fails to communicate with the Xorg server it should still not use 100% CPU. Not sure what is causing that, maybe take a look at the log and stdout?

@ErikBjare
Copy link
Member

Well that's an interesting bug. From a quick glance I'm not sure what takes up all the CPU but if you could provide the output of python3 -m cProfile --sort=cumtime aw_watcher_window/__main__.py after having it peak CPU for a while then that'd be really helpful!

@phromo
Copy link
Author

phromo commented May 14, 2018

Launching:

⋊>phromo@thingybox ~/p/a/a/aw-watcher-window on eb0f791  env DISPLAY=:10 python -m cProfile --sort=cumtime ~/program/activivity-watch/activitywatch/aw-watcher-window/aw_watcher_window/__main__.py
2018-05-14 19:45:24 [INFO ]: Running watcher with poll time 1.0 seconds  (aw_watcher_window.main:35)
2018-05-14 19:45:24 [INFO ]: aw-watcher-window has started  (aw_watcher_window.main:44)
2018-05-14 19:45:24 [INFO ]: Connection to aw-server established by aw-watcher-window  (aw_client.client:298)

Shutting down Xorg:

2018-05-14 19:45:33 [ERROR]: Exception thrown while trying to get active window: 'BrokenPipeError' object is not subscriptable  (aw_watcher_window.main:69)
Traceback (most recent call last):
  File "/home/phromo/Apps/anaconda3/lib/python3.6/site-packages/python_xlib-0.23-py3.6.egg/Xlib/protocol/display.py", line 584, in send_and_recv
    i = self.socket.send(self.data_send)
BrokenPipeError: [Errno 32] Broken pipe

During handling of the above exception, another exception occurred:

Traceback (most recent call last):
  File "/home/phromo/program/activivity-watch/activitywatch/aw-watcher-window/aw_watcher_window/main.py", line 66, in heartbeat_loop
    current_window = get_current_window()
  File "/home/phromo/program/activivity-watch/activitywatch/aw-watcher-window/aw_watcher_window/lib.py", line 44, in get_current_window
    return get_current_window_linux()
  File "/home/phromo/program/activivity-watch/activitywatch/aw-watcher-window/aw_watcher_window/lib.py", line 7, in get_current_window_linux
    window = xlib.get_current_window()
  File "/home/phromo/program/activivity-watch/activitywatch/aw-watcher-window/aw_watcher_window/xlib.py", line 37, in get_current_window
    window_id = _get_current_window_id()
  File "/home/phromo/program/activivity-watch/activitywatch/aw-watcher-window/aw_watcher_window/xlib.py", line 20, in _get_current_window_id
    window_prop = screen.root.get_full_property(atom, X.AnyPropertyType)
  File "/home/phromo/Apps/anaconda3/lib/python3.6/site-packages/python_xlib-0.23-py3.6.egg/Xlib/xobject/drawable.py", line 472, in get_full_property
    prop = self.get_property(property, property_type, 0, sizehint)
  File "/home/phromo/Apps/anaconda3/lib/python3.6/site-packages/python_xlib-0.23-py3.6.egg/Xlib/xobject/drawable.py", line 461, in get_property
    long_length = length)
  File "/home/phromo/Apps/anaconda3/lib/python3.6/site-packages/python_xlib-0.23-py3.6.egg/Xlib/protocol/rq.py", line 1369, in __init__
    self.reply()
  File "/home/phromo/Apps/anaconda3/lib/python3.6/site-packages/python_xlib-0.23-py3.6.egg/Xlib/protocol/rq.py", line 1381, in reply
    self._display.send_and_recv(request = self._serial)
  File "/home/phromo/Apps/anaconda3/lib/python3.6/site-packages/python_xlib-0.23-py3.6.egg/Xlib/protocol/display.py", line 586, in send_and_recv
    self.close_internal('server: %s' % err[1])
TypeError: 'BrokenPipeError' object is not subscriptable

Hitting Ctrl-C after awhile of 100% cpu:

^C         326156379 function calls (326150472 primitive calls) in 75.018 seconds

   Ordered by: cumulative time

   ncalls  tottime  percall  cumtime  percall filename:lineno(function)
    341/1    0.006    0.000   75.019   75.019 {built-in method builtins.exec}
        1    0.000    0.000   75.019   75.019 __main__.py:1(<module>)
        1    0.000    0.000   74.881   74.881 main.py:20(main)
        1    0.000    0.000   74.878   74.878 main.py:59(heartbeat_loop)
       11    0.000    0.000   64.834    5.894 lib.py:42(get_current_window)
       11    0.000    0.000   64.834    5.894 lib.py:5(get_current_window_linux)
       26    0.000    0.000   64.813    2.493 rq.py:1358(__init__)
       11    0.000    0.000   64.813    5.892 xlib.py:36(get_current_window)
       11    0.000    0.000   64.813    5.892 xlib.py:18(_get_current_window_id)
       11    0.000    0.000   64.812    5.892 drawable.py:471(get_full_property)
       11    0.000    0.000   64.812    5.892 drawable.py:454(get_property)
       26   33.512    1.289   64.811    2.493 rq.py:1371(reply)
 46562181   22.061    0.000   26.623    0.000 display.py:388(send_and_recv)
       10   10.009    1.001   10.009    1.001 {built-in method time.sleep}
279373433    9.234    0.000    9.234    0.000 lock.py:36(__noop)
       16    0.000    0.000    0.280    0.018 __init__.py:1(<module>)
    360/2    0.001    0.000    0.159    0.080 <frozen importlib._bootstrap>:966(_find_and_load)
    358/2    0.001    0.000    0.159    0.080 <frozen importlib._bootstrap>:936(_find_and_load_unlocked)
    457/2    0.000    0.000    0.159    0.079 <frozen importlib._bootstrap>:211(_call_with_frames_removed)
    350/2    0.001    0.000    0.159    0.079 <frozen importlib._bootstrap>:651(_load_unlocked)
    310/2    0.001    0.000    0.159    0.079 <frozen importlib._bootstrap_external>:672(exec_module)
        1    0.000    0.000    0.130    0.130 main.py:1(<module>)
   107/18    0.000    0.000    0.123    0.007 {built-in method builtins.__import__}
 1009/446    0.001    0.000    0.111    0.000 <frozen importlib._bootstrap>:997(_handle_fromlist)
      8/1    0.000    0.000    0.109    0.109 <frozen importlib._bootstrap>:622(_load_backward_compatible)
      3/1    0.001    0.000    0.109    0.109 {method 'load_module' of 'zipimport.zipimporter' objects}
        1    0.000    0.000    0.106    0.106 client.py:1(<module>)
        1    0.000    0.000    0.099    0.099 __init__.py:41(<module>)
        1    0.000    0.000    0.043    0.043 pyopenssl.py:43(<module>)
       11    0.000    0.000    0.038    0.003 __init__.py:5(<module>)
        2    0.000    0.000    0.033    0.016 __init__.py:3(<module>)
1400/1398    0.013    0.000    0.031    0.000 {built-in method builtins.__build_class__}
        1    0.000    0.000    0.030    0.030 connectionpool.py:1(<module>)
  353/322    0.001    0.000    0.029    0.000 <frozen importlib._bootstrap>:870(_find_spec)
       10    0.000    0.000    0.029    0.003 client.py:152(heartbeat)

@phromo
Copy link
Author

phromo commented May 14, 2018

in a manner similar to @johan-bjareholt I moved the initialization of aw-watcher-* to .xsession. That makes the processes terminate upon Xorg exit (I don't understand why i3 exec is designed not to have this property)

@johan-bjareholt
Copy link
Member

https://github.com/python-xlib/python-xlib/blob/master/Xlib/protocol/display.py#L427

This is likely the cause, don't have time to dig through the Xlib code now but might later.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants