readline icon indicating copy to clipboard operation
readline copied to clipboard

Deadlock issues

Open cespare opened this issue 9 years ago • 11 comments

I have a problem where occasionally readline will deadlock. I'm using readline in a couple of different simple CLI tools. There's nothing too unusual or fancy about the usage. I can't share the code, but maybe the information I've got would be useful.

The most recent time the problem happened, my program got stuck calling (*Instance).ReadLine(). Nothing I typed caused that ReadLine call to return.

Here are a couple of the goroutines from the stack trace that I obtained with SIGQUIT:

goroutine 1 [select]:
xxx/vendor/github.com/chzyer/readline.(*Operation).Runes(0xc820317560, 0x0, 0x0, 0x0, 0x0, 0x0)
        /gopath/src/xxx/vendor/github.com/chzyer/readline/operation.go:340 +0x369
xxx/vendor/github.com/chzyer/readline.(*Operation).String(0xc820317560, 0x0, 0x0, 0x0, 0x0)
        /gopath/src/xxx/vendor/github.com/chzyer/readline/operation.go:327 +0x40
xxx/vendor/github.com/chzyer/readline.(*Instance).Readline(0xc820309400, 0x0, 0x0, 0x0, 0x0)
        /gopath/src/xxx/vendor/github.com/chzyer/readline/readline.go:216 +0x3d
main.main()
        /gopath/src/xxx/tool/tool.go:113 +0x1740 // this is where my code calls (*Instance).ReadLine()

goroutine 45 [select]:
xxx/vendor/github.com/chzyer/readline.(*Terminal).ioloop(0xc820304f40)
        /gopath/src/xxx/vendor/github.com/chzyer/readline/terminal.go:108 +0x441
created by xxx/vendor/github.com/chzyer/readline.NewTerminal
        /gopath/src/xxx/vendor/github.com/chzyer/readline/terminal.go:33 +0x186

goroutine 47 [chan receive]:
xxx/vendor/github.com/chzyer/readline.DefaultOnWidthChanged.func1.1(0xc8203175c0)
        /gopath/src/xxx/vendor/github.com/chzyer/readline/utils_unix.go:72 +0x43
created by xxx/vendor/github.com/chzyer/readline.DefaultOnWidthChanged.func1
        /gopath/src/xxx/vendor/github.com/chzyer/readline/utils_unix.go:78 +0x13f

goroutine 48 [chan receive]:
xxx/vendor/github.com/chzyer/readline.(*Operation).ioloop(0xc820317560)
        /gopath/src/xxx/vendor/github.com/chzyer/readline/operation.go:98 +0x5b
created by xxx/vendor/github.com/chzyer/readline.NewOperation
        /gopath/src/xxx/vendor/github.com/chzyer/readline/operation.go:82 +0x4a6

cespare avatar Apr 21 '16 07:04 cespare

Hi, which OS you are using, is it similarity to #21 ?

chzyer avatar Apr 21 '16 07:04 chzyer

It's possible this is the same. I filed a new bug because my issue was different in two ways:

  • It doesn't trip the deadlock detector (the program doesn't crash, it just hangs)
  • I'm on linux/amd64, not Windows

cespare avatar Apr 21 '16 07:04 cespare

How is the stack of terminal.go ? Maybe it will be more useful.

chzyer avatar Apr 21 '16 09:04 chzyer

BTW, is that hangs every time when it start or some keys you pressed ?

chzyer avatar Apr 21 '16 09:04 chzyer

How is the stack of terminal.go ? Maybe it will be more useful.

I'm sorry, I deleted the stack trace, but I'll try to make the problem happen again and report back.

BTW, is that hangs every time when it start or some keys you pressed ?

It's after I press some keys. I'm not sure exactly what triggers it. If I figure out a pattern, I'll let you know.

cespare avatar Apr 21 '16 09:04 cespare

That will be great if you figure out a pattern :)

chzyer avatar Apr 21 '16 09:04 chzyer

Hi @chzyer, I updated the original report to include all of the readline goroutine stacks.

I'm trying to make a small repro case now.

cespare avatar Apr 21 '16 19:04 cespare

I found another, different deadlock on (*Instance).Close():

goroutine 1 [semacquire]:
sync.runtime_Semacquire(0xc82022def4)
        /home/caleb/apps/go/src/runtime/sema.go:47 +0x26
sync.(*WaitGroup).Wait(0xc82022dee8)
        /home/caleb/apps/go/src/sync/waitgroup.go:127 +0xb4
xxx/vendor/github.com/chzyer/readline.(*Terminal).Close(0xc82022dec0, 0x0, 0x0)
        /gopath/src/xxx/vendor/github.com/chzyer/readline/terminal.go:165 +0xa7
xxx/vendor/github.com/chzyer/readline.(*Instance).Close(0xc82030cda0, 0x0, 0x0)
        /gopath/src/xxx/vendor/github.com/chzyer/readline/readline.go:230 +0x31
main.main()
        /gopath/src/xxx/tool/tool.go:166 +0x1fd6 // where my code calls (*Instance).Close()

goroutine 65 [chan send]:
xxx/vendor/github.com/chzyer/readline.(*Terminal).ioloop(0xc82022dec0)
        /gopath/src/xxx/vendor/github.com/chzyer/readline/terminal.go:150 +0x345
created by xxx/vendor/github.com/chzyer/readline.NewTerminal
        /gopath/src/xxx/vendor/github.com/chzyer/readline/terminal.go:33 +0x186

goroutine 67 [chan receive]:
xxx/vendor/github.com/chzyer/readline.DefaultOnWidthChanged.func1.1(0xc8203ca8a0)
        /gopath/src/xxx/vendor/github.com/chzyer/readline/utils_unix.go:72 +0x43
created by xxx/vendor/github.com/chzyer/readline.DefaultOnWidthChanged.func1
        /gopath/src/xxx/vendor/github.com/chzyer/readline/utils_unix.go:78 +0x13f

cespare avatar Apr 21 '16 19:04 cespare

I'm not sure how to trigger the first deadlock, but I made a repro for the second one:

  1. go get -u github.com/cespare/misc/rldemo
  2. Run rldemo
  3. Hold down enter for a few seconds and let the program get delayed (it waits 250ms before returning from each keypress)
  4. Before rldemo catches up, hit ^D. It will print EOF and then hang.

cespare avatar Apr 21 '16 21:04 cespare

Not really sure, but may be caused by race condition I mentioned in #122.

cpacifying avatar Jun 16 '17 14:06 cpacifying

@cespare Hi, I encountered the same problem as you, how did you solve it, thanks

JoeeeeeeeyLee avatar Nov 27 '20 02:11 JoeeeeeeeyLee