pazz / alot

Terminal-based Mail User Agent
GNU General Public License v3.0
696 stars 165 forks source link

Alot becomes unresponsive trying to quit #1236

Open varac opened 6 years ago

varac commented 6 years ago

Software Versions

Python version: 2.7.14

Notmuch version: 0.26

Alot version (either a number or sha for master): 0.7

Observed behavior

I try to quit alot with 'q' but it immediatly freezes, becomes unresponsive and rejects to quit. This is the tail from the debug log:

DEBUG:__init__:cmd parms {'movement': [u'page', u'down']}
DEBUG:search:page down
DEBUG:ui:Got key (['q'], [113])
DEBUG:ui:cmdline: 'exit'
DEBUG:ui:search command string: "exit"
DEBUG:__init__:mode:search got commandline "exit"
DEBUG:__init__:ARGS: [u'exit']
DEBUG:__init__:cmd parms {}
DEBUG:globals:flush complete
DEBUG:manager:Worker process 25287 returned error code 1

Expected behavior

I'd like to exit alot !

dcbaker commented 6 years ago

I can't reproduce this. Do you have any hooks that might be in flight preventing an exit?

varac commented 6 years ago

@dcbaker Here is my hooks.py.txt.

I took out my email adr. transitions on line 22.

meelapshah commented 6 years ago

I'm seeing this issue as well.

I can only trigger the issue with this hook from the wiki:

def pre_buffer_focus(ui, dbm, buf):
  if buf.modename == 'search':
    buf.rebuild()

I can reliably cause a hang with:

  1. open a search buffer matching few messages (in my case ~10)
  2. open another search buffer matching a lot of messanges (in my case 60k) 3a. exit causes a UI hang 3b. bclose the large buffer, then exit also causes UI hang

When hung, there are 2 alot processes. A parent wait()ing on a child, and a child blocked in pipe_write:

$ cat /proc/19360/stack
[<0>] pipe_wait+0x6c/0xb0
[<0>] pipe_write+0x16c/0x3f0
[<0>] __vfs_write+0x127/0x170
[<0>] vfs_write+0xa9/0x190
[<0>] ksys_write+0x4f/0xb0
[<0>] do_syscall_64+0x5b/0x170
[<0>] entry_SYSCALL_64_after_hwframe+0x44/0xa9
[<0>] 0xffffffffffffffff

This child is the first of 2 processes that were spawned when the large buffer was opened:

DEBUG:__init__:mode:search got commandline "search (not tag:ignore and not tag:killed)"
DEBUG:__init__:ARGS: [u'search', u'(not', u'tag:ignore', u'and', u'not', u'tag:killed)']
DEBUG:__init__:cmd parms {'sort': None, 'query': [u'(not', u'tag:ignore', u'and', u'not', u'tag:killed)']}
DEBUG:manager: Worker process 19360 spawned
DEBUG:manager: Worker process 19361 spawned
...
DEBUG:ui:Got key (['q'], [113])
DEBUG:ui:cmdline: 'exit'
DEBUG:ui:search command string: "exit"
DEBUG:__init__:mode:search got commandline "exit"
DEBUG:__init__:ARGS: [u'exit']
DEBUG:__init__:cmd parms {}
DEBUG:globals:flush complete
DEBUG:manager:Worker process 19361 returned error code 1

Adding a log statement just before this line in dbman to print traceback.format_stack() prevents the issue, so it looks like some kind of race.