[GH-ISSUE #244] Tview stuck in infinite loop after shelling out.... #187

Open
opened 2026-03-04 01:02:46 +03:00 by kerem · 29 comments
Owner

Originally created by @derailed on GitHub (Mar 1, 2019).
Original GitHub issue: https://github.com/rivo/tview/issues/244

Hi,

First off thank you for this great project! I am having an issue in the latest code base while shelling out using Suspend. I issue a command and forward stdin, stdout, stderr. When the command completes tview is completely non responsive and the screen is partially drawn + cpu pegged. Ctrl-C has no effect. It seems I am stuck in a screen rendering loop somewhere. Any advise or things I could try out? Thanks! BTW this used to work fine a few month ago....

Originally created by @derailed on GitHub (Mar 1, 2019). Original GitHub issue: https://github.com/rivo/tview/issues/244 Hi, First off thank you for this great project! I am having an issue in the latest code base while shelling out using Suspend. I issue a command and forward stdin, stdout, stderr. When the command completes tview is completely non responsive and the screen is partially drawn + cpu pegged. Ctrl-C has no effect. It seems I am stuck in a screen rendering loop somewhere. Any advise or things I could try out? Thanks! BTW this used to work fine a few month ago....
Author
Owner

@rivo commented on GitHub (Mar 9, 2019):

I just tried this myself but couldn't reproduce your problem. Could you send a short code snippet that illustrates this?

<!-- gh-comment-id:471172626 --> @rivo commented on GitHub (Mar 9, 2019): I just tried this myself but couldn't reproduce your problem. Could you send a short code snippet that illustrates this?
Author
Owner

@k8sland commented on GitHub (Mar 12, 2019):

@rivo thanks for looking into it and for tview!!

I think there is a race in this code (link below) where we init the new screen after it's been set in the application when the app is suspended. I've moved the lock block after the init and this seem to be working now. This is hard to repro as I think the draw routine timing is a play here...

Here is a ref: github.com/rivo/tview@3938f60085/application.go (L189)

Thanks!

<!-- gh-comment-id:472223422 --> @k8sland commented on GitHub (Mar 12, 2019): @rivo thanks for looking into it and for tview!! I think there is a race in this code (link below) where we init the new screen after it's been set in the application when the app is suspended. I've moved the lock block after the init and this seem to be working now. This is hard to repro as I think the draw routine timing is a play here... Here is a ref: https://github.com/rivo/tview/blob/3938f6008527a10cc1b94159960970798f962558/application.go#L189 Thanks!
Author
Owner

@rivo commented on GitHub (May 13, 2019):

@k8sland Do you mean you set a.screen between the call to Init() and a.draw() and that solved it?

<!-- gh-comment-id:491813248 --> @rivo commented on GitHub (May 13, 2019): @k8sland Do you mean you set `a.screen` between the call to `Init()` and `a.draw()` and that solved it?
Author
Owner

@rivo commented on GitHub (Jun 26, 2019):

Will reopen when there is more information.

<!-- gh-comment-id:505882517 --> @rivo commented on GitHub (Jun 26, 2019): Will reopen when there is more information.
Author
Owner

@derricw commented on GitHub (May 7, 2020):

I'm experiencing this same issue. I am using app.Suspend to run Vim and compose a document. About 1/3 of the time, tview seems to get into some kind of infinite loop where it becomes unresponsive and pegs CPU. The other 2/3 of the time it works correctly.

Code snippet looks like this:

func (c *ChatWindow) Compose() {
	msg := ""
	success := c.app.Suspend(func() {
		msg = FancyCompose()
	})
	if !success {
		log.Error("failed to suspend")
		return
	}
	if msg != "" {
		contact := c.currentContact
		go c.Send(msg, contact)
		log.Infof("sent message: %s to contact: %s", msg, contact)
	}
}

And FancyCompose looks like this:

func FancyCompose() string {
	tmpFile, err := ioutil.TempFile(os.TempDir(), "compose-")
	if err != nil {
		log.Error("failed to create temp file for compose: %v", err)
		return ""
	}
	editor := os.Getenv("EDITOR")
	if editor == "" {
		log.Error("cannot compose: no EDITOR set in environment")
		return ""
	}
	fname := tmpFile.Name()
	defer os.Remove(fname)
	cmd := exec.Command(editor, fname)
	cmd.Stdout = os.Stdout
	cmd.Stdin = os.Stdin
	cmd.Stderr = os.Stderr
	if err = cmd.Run(); err != nil {
		log.Error("failed to start editor: %v", err)
		return ""
	}
	b, err := ioutil.ReadFile(fname)
	if err != nil {
		log.Error("failed to read temp file: %v", err)
		return ""
	}
	return string(b)
}
<!-- gh-comment-id:625540772 --> @derricw commented on GitHub (May 7, 2020): I'm experiencing this same issue. I am using `app.Suspend` to run Vim and compose a document. About 1/3 of the time, tview seems to get into some kind of infinite loop where it becomes unresponsive and pegs CPU. The other 2/3 of the time it works correctly. Code snippet looks like this: ``` func (c *ChatWindow) Compose() { msg := "" success := c.app.Suspend(func() { msg = FancyCompose() }) if !success { log.Error("failed to suspend") return } if msg != "" { contact := c.currentContact go c.Send(msg, contact) log.Infof("sent message: %s to contact: %s", msg, contact) } } ``` And `FancyCompose` looks like this: ``` func FancyCompose() string { tmpFile, err := ioutil.TempFile(os.TempDir(), "compose-") if err != nil { log.Error("failed to create temp file for compose: %v", err) return "" } editor := os.Getenv("EDITOR") if editor == "" { log.Error("cannot compose: no EDITOR set in environment") return "" } fname := tmpFile.Name() defer os.Remove(fname) cmd := exec.Command(editor, fname) cmd.Stdout = os.Stdout cmd.Stdin = os.Stdin cmd.Stderr = os.Stderr if err = cmd.Run(); err != nil { log.Error("failed to start editor: %v", err) return "" } b, err := ioutil.ReadFile(fname) if err != nil { log.Error("failed to read temp file: %v", err) return "" } return string(b) } ```
Author
Owner

@raziman18 commented on GitHub (Jul 24, 2020):

I have this issue before but I solved it by making sure there are no tview widgets methods being called when calling app.Suspend

@rivo thanks for looking into it and for tview!!

I think there is a race in this code (link below) where we init the new screen after it's been set in the application when the app is suspended. I've moved the lock block after the init and this seem to be working now. This is hard to repro as I think the draw routine timing is a play here...

Here is a ref:

github.com/rivo/tview@3938f60085/application.go (L189)

Thanks!

also this workaround doesn't work

<!-- gh-comment-id:663511879 --> @raziman18 commented on GitHub (Jul 24, 2020): I have this issue before but I solved it by making sure there are no tview widgets methods being called when calling `app.Suspend` > @rivo thanks for looking into it and for tview!! > > I think there is a race in this code (link below) where we init the new screen after it's been set in the application when the app is suspended. I've moved the lock block after the init and this seem to be working now. This is hard to repro as I think the draw routine timing is a play here... > > Here is a ref: > > https://github.com/rivo/tview/blob/3938f6008527a10cc1b94159960970798f962558/application.go#L189 > > Thanks! also this workaround doesn't work
Author
Owner

@lenormf commented on GitHub (Feb 1, 2021):

I'm hitting this issue, and it's making my program useless because it locks up constantly.

Here's a standalone reproducer:

package main

import (
    "os"
    "os/exec"
    "io/ioutil"
    "github.com/gdamore/tcell"
    "github.com/rivo/tview"
)

func main() {
    app := tview.NewApplication()
    box := tview.NewBox().
        SetBorder(true).
        SetTitle("Box Demo")

    box.SetInputCapture(func (event *tcell.EventKey) *tcell.EventKey {
        switch key := event.Key(); key {
            case tcell.KeyRune:
                switch event.Rune() {
                    // Hit `e` to spawn the editor
                    case 'e':
                        tmpfile, err := ioutil.TempFile("", "test.*.txt")
                        if err != nil {
                            panic(err)
                        }

                        path_tmpfile := tmpfile.Name()
                        tmpfile.Close()

                        app.Suspend(func () {
                            env_editor := os.Getenv("EDITOR")

                            path_editor, err := exec.LookPath(env_editor)
                            if err != nil {
                                panic(err)
                            }

                            cmd_editor := exec.Command(path_editor, path_tmpfile)

                            cmd_editor.Stdin = os.Stdin
                            cmd_editor.Stdout = os.Stdout
                            cmd_editor.Stderr = os.Stderr

                            if err := cmd_editor.Run(); err != nil {
                                panic(err)
                            }
                        })

                        // Without the following, it's much harder to reproduce the issue
                        if _, err := ioutil.ReadFile(path_tmpfile); err != nil {
                            panic(err)
                        }

                        os.Remove(path_tmpfile)

                        return nil
                }
        }

        return event
    })

    if err := app.SetRoot(box, true).Run(); err != nil {
        panic(err)
    }
}

When I strace the process, I see that it's stuck on a call to futex(0x675688, FUTEX_WAIT_PRIVATE, 0, NULL and it takes 100% of the CPU.

Any ideas?

<!-- gh-comment-id:770851919 --> @lenormf commented on GitHub (Feb 1, 2021): I'm hitting this issue, and it's making my program useless because it locks up constantly. Here's a standalone reproducer: ```go package main import ( "os" "os/exec" "io/ioutil" "github.com/gdamore/tcell" "github.com/rivo/tview" ) func main() { app := tview.NewApplication() box := tview.NewBox(). SetBorder(true). SetTitle("Box Demo") box.SetInputCapture(func (event *tcell.EventKey) *tcell.EventKey { switch key := event.Key(); key { case tcell.KeyRune: switch event.Rune() { // Hit `e` to spawn the editor case 'e': tmpfile, err := ioutil.TempFile("", "test.*.txt") if err != nil { panic(err) } path_tmpfile := tmpfile.Name() tmpfile.Close() app.Suspend(func () { env_editor := os.Getenv("EDITOR") path_editor, err := exec.LookPath(env_editor) if err != nil { panic(err) } cmd_editor := exec.Command(path_editor, path_tmpfile) cmd_editor.Stdin = os.Stdin cmd_editor.Stdout = os.Stdout cmd_editor.Stderr = os.Stderr if err := cmd_editor.Run(); err != nil { panic(err) } }) // Without the following, it's much harder to reproduce the issue if _, err := ioutil.ReadFile(path_tmpfile); err != nil { panic(err) } os.Remove(path_tmpfile) return nil } } return event }) if err := app.SetRoot(box, true).Run(); err != nil { panic(err) } } ``` When I `strace` the process, I see that it's stuck on a call to `futex(0x675688, FUTEX_WAIT_PRIVATE, 0, NULL` and it takes 100% of the CPU. Any ideas?
Author
Owner

@lenormf commented on GitHub (Feb 8, 2021):

@rivo Could we please re-open this, we have a reproducer and several reports of the issue occurring, it'd be nice to have a workaround — or even better, a hot fix.

<!-- gh-comment-id:774915678 --> @lenormf commented on GitHub (Feb 8, 2021): @rivo Could we please re-open this, we have a reproducer and several reports of the issue occurring, it'd be nice to have a workaround — or even better, a hot fix.
Author
Owner

@rivo commented on GitHub (Apr 26, 2021):

I tried this with your code and there was no deadlock. We're on tcell v2 now and work has been done on suspending applications. Maybe that has fixed it?

Can you please let me know if this is still an issue?

<!-- gh-comment-id:826906368 --> @rivo commented on GitHub (Apr 26, 2021): I tried this with your code and there was no deadlock. We're on `tcell` v2 now and work has been done on suspending applications. Maybe that has fixed it? Can you please let me know if this is still an issue?
Author
Owner

@lenormf commented on GitHub (Apr 27, 2021):

It looks like the issue went away with tcell/v2. One side effect (potentially unrelated) seems to be that inputs are buffered, and hitting e won't do anything until another key is hit.

<!-- gh-comment-id:827315734 --> @lenormf commented on GitHub (Apr 27, 2021): It looks like the issue went away with `tcell/v2`. One side effect (potentially unrelated) seems to be that inputs are buffered, and hitting <kbd>e</kbd> won't do anything until another key is hit.
Author
Owner

@rivo commented on GitHub (Apr 27, 2021):

I didn't experience this. I tried it on macOS with iTerm2 and hitting e immediately sent me to my editor. What OS and terminal are you on?

<!-- gh-comment-id:827406455 --> @rivo commented on GitHub (Apr 27, 2021): I didn't experience this. I tried it on macOS with iTerm2 and hitting <kbd>e</kbd> immediately sent me to my editor. What OS and terminal are you on?
Author
Owner

@lenormf commented on GitHub (Apr 27, 2021):

I'm using ArchLinux, the same issue is reproducible with Kitty (v0.20.1) and Xterm (v367) for me.

<!-- gh-comment-id:827658718 --> @lenormf commented on GitHub (Apr 27, 2021): I'm using ArchLinux, the same issue is reproducible with Kitty (`v0.20.1`) and Xterm (`v367`) for me.
Author
Owner

@rivo commented on GitHub (Apr 27, 2021):

I'm sorry but I don't have any way to test and debug it on these systems. Key events are produced by tcell and consumed by tview here:

github.com/rivo/tview@09cec83b17/application.go (L267)

Then they are queued and picked up again here:

github.com/rivo/tview@09cec83b17/application.go (L303)

You may want to check if this code gets executed when you press e. If the screen.PollEvent() function doesn't even return when it's pressed, then it's an issue of tcell and you might want to open an issue there. If it returns with the correct *tcell.EventKey event, we can take it from there over here.

<!-- gh-comment-id:827713429 --> @rivo commented on GitHub (Apr 27, 2021): I'm sorry but I don't have any way to test and debug it on these systems. Key events are produced by `tcell` and consumed by `tview` here: https://github.com/rivo/tview/blob/09cec83b1732556d91c984b2baa56f19b819b463/application.go#L267 Then they are queued and picked up again here: https://github.com/rivo/tview/blob/09cec83b1732556d91c984b2baa56f19b819b463/application.go#L303 You may want to check if this code gets executed when you press <kbd>e</kbd>. If the `screen.PollEvent()` function doesn't even return when it's pressed, then it's an issue of `tcell` and you might want to open an issue there. If it returns with the correct `*tcell.EventKey` event, we can take it from there over here.
Author
Owner

@derailed commented on GitHub (Apr 27, 2021):

@lenormf - which version of tcell are you running? I think tcell v2.2.1 or later contains a fix for the first char being swallowed during suspend/resume operations...

<!-- gh-comment-id:827737655 --> @derailed commented on GitHub (Apr 27, 2021): @lenormf - which version of tcell are you running? I think tcell v2.2.1 or later contains a fix for the first char being swallowed during suspend/resume operations...
Author
Owner

@lenormf commented on GitHub (Apr 27, 2021):

I'm using v2.2.1.

The first e is not swallowed up, I just have to hit another key for it to be executed.

The other weird thing is if I double tap e, the editor spawns (first e). When I quit the editor, the program resumes. If I hit another key, the editor spawns again (second e, for the double tap). So it looks like keys are buffered, until the buffer hits a size of 2.

The issue also occurs with different values of $EDITOR.

<!-- gh-comment-id:827762311 --> @lenormf commented on GitHub (Apr 27, 2021): I'm using `v2.2.1`. The first <kbd>e</kbd> is not swallowed up, I just have to hit another key for it to be executed. The other weird thing is if I double tap <kbd>e</kbd>, the editor spawns (first <kbd>e</kbd>). When I quit the editor, the program resumes. If I hit another key, the editor spawns again (second <kbd>e</kbd>, for the double tap). So it looks like keys are buffered, until the buffer hits a size of 2. The issue also occurs with different values of `$EDITOR`.
Author
Owner

@rivo commented on GitHub (Apr 27, 2021):

Well, for sure tview doesn't buffer any key events.

<!-- gh-comment-id:827808565 --> @rivo commented on GitHub (Apr 27, 2021): Well, for sure `tview` doesn't buffer any key events.
Author
Owner

@jeewangue commented on GitHub (May 2, 2021):

@lenormf

I'm using v2.2.1.

The first e is not swallowed up, I just have to hit another key for it to be executed.

The other weird thing is if I double tap e, the editor spawns (first e). When I quit the editor, the program resumes. If I hit another key, the editor spawns again (second e, for the double tap). So it looks like keys are buffered, until the buffer hits a size of 2.

The issue also occurs with different values of $EDITOR.

I had exactly the same issue with Arch Linux & termite.
I had to press any other keys whenever app.stop() is executed by a keystroke.

versions:

  • tview: 09cec83 (latest by now)
  • tcell: v2.2.1

IMO the issue is related to https://github.com/gdamore/tcell/issues/452, saying that

the cause is that a read block occurs in the inputLoop of tscreen.go.
(In v2.2.0, it was os.Stdin, so it could be finished.)

for the quick fix, I just downgraded tview to 7df0389 and tcell to v2.2.0
(not really far from the latest, 6 days ago from now)

go get github.com/rivo/tview@7df0389
go get github.com/gdamore/tcell/v2@v2.2.0
<!-- gh-comment-id:830847584 --> @jeewangue commented on GitHub (May 2, 2021): @lenormf > I'm using `v2.2.1`. > > The first e is not swallowed up, I just have to hit another key for it to be executed. > > The other weird thing is if I double tap e, the editor spawns (first e). When I quit the editor, the program resumes. If I hit another key, the editor spawns again (second e, for the double tap). So it looks like keys are buffered, until the buffer hits a size of 2. > > The issue also occurs with different values of `$EDITOR`. I had exactly the same issue with Arch Linux & termite. I had to press any other keys whenever `app.stop()` is executed by a keystroke. versions: - tview: `09cec83` (latest by now) - tcell: `v2.2.1` IMO the issue is related to <https://github.com/gdamore/tcell/issues/452>, saying that > the cause is that a read block occurs in the inputLoop of `tscreen.go`. > (In v2.2.0, it was os.Stdin, so it could be finished.) for the quick fix, I just downgraded tview to `7df0389` and tcell to `v2.2.0` (not really far from the latest, 6 days ago from now) ```bash go get github.com/rivo/tview@7df0389 go get github.com/gdamore/tcell/v2@v2.2.0 ```
Author
Owner

@gdamore commented on GitHub (May 19, 2021):

tcell's issue 452 is fixed now... please retest.

<!-- gh-comment-id:844542394 --> @gdamore commented on GitHub (May 19, 2021): tcell's issue 452 is fixed now... please retest.
Author
Owner

@rivo commented on GitHub (May 20, 2021):

Echoing @gdamore here, please let us know if the problem still persists with the latest version.

<!-- gh-comment-id:845295581 --> @rivo commented on GitHub (May 20, 2021): Echoing @gdamore here, please let us know if the problem still persists with the latest version.
Author
Owner

@dundee commented on GitHub (Sep 1, 2021):

I am getting panic: read /dev/tty: i/o timeout on ArchLinux.

github.com/rivo/tview v0.0.0-20210624165335-29d673af0ce2
github.com/gdamore/tcell/v2 v2.4.0
go version go1.17 linux/amd64

Code the same as in https://github.com/rivo/tview/issues/244#issuecomment-770851919 except using tcell/v2.

Tried multiple shells and terminals.

<!-- gh-comment-id:910632343 --> @dundee commented on GitHub (Sep 1, 2021): I am getting `panic: read /dev/tty: i/o timeout` on ArchLinux. ``` github.com/rivo/tview v0.0.0-20210624165335-29d673af0ce2 github.com/gdamore/tcell/v2 v2.4.0 go version go1.17 linux/amd64 ``` Code the same as in https://github.com/rivo/tview/issues/244#issuecomment-770851919 except using `tcell/v2`. Tried multiple shells and terminals.
Author
Owner

@rivo commented on GitHub (Sep 2, 2021):

@dundee Could you please run the program listed here: https://github.com/gdamore/tcell/issues/480 and let me know if this results in the same error?

<!-- gh-comment-id:911816327 --> @rivo commented on GitHub (Sep 2, 2021): @dundee Could you please run the program listed here: https://github.com/gdamore/tcell/issues/480 and let me know if this results in the same error?
Author
Owner

@dundee commented on GitHub (Sep 3, 2021):

Yes, same error. I will paste details there.

<!-- gh-comment-id:912361134 --> @dundee commented on GitHub (Sep 3, 2021): Yes, same error. I will paste details there.
Author
Owner

@gdamore commented on GitHub (Sep 3, 2021):

So, does this only happen on ArchLinux? I wonder if there is a bug in the terminal code there.

The panic indicates a timeout reading from /dev/tty, but I don't think we actually attempt to read from that -- we issue a ioctls in the code path that has the panic, but not reads.

Which version of ArchLinux are you using? I unfortunately don't have any experience with Arch, but I don't want to burn cycles trying to fix a problem only to find I can't reproduce it because I don't have the right version of Arch.

<!-- gh-comment-id:912593368 --> @gdamore commented on GitHub (Sep 3, 2021): So, does this *only* happen on ArchLinux? I wonder if there is a bug in the terminal code there. The panic indicates a timeout reading from /dev/tty, but I don't think we actually attempt to read from that -- we issue a ioctls in the code path that has the panic, but not reads. Which version of ArchLinux are you using? I unfortunately don't have any experience with Arch, but I don't want to burn cycles trying to fix a problem only to find I can't reproduce it because I don't have the right version of Arch.
Author
Owner

@dundee commented on GitHub (Sep 5, 2021):

I can confirm that the fix from https://github.com/gdamore/tcell/issues/480 fixes this issue as well.

<!-- gh-comment-id:913207473 --> @dundee commented on GitHub (Sep 5, 2021): I can confirm that the fix from https://github.com/gdamore/tcell/issues/480 fixes this issue as well.
Author
Owner

@dundee commented on GitHub (Sep 8, 2021):

Looks like some problem still persists on Windows.

The test script in https://github.com/gdamore/tcell/issues/480 works but tview application is not able to resume after being paused. It falls into deadlock:

fatal error: all goroutines are asleep - deadlock!

goroutine 1
 [select]:
github.com/rivo/tview.(*Application).Run(0xc0000ae000)
    C:/Users/danie/go/pkg/mod/github.com/rivo/tview@v0.0.0-20210624165335-29d673af0ce2/application.go:302 +0x325
github.com/dundee/gdu/v5/tui.(*UI).StartUILoop(0xc000107d60)
    C:/Users/danie/Downloads/gdu-master/gdu-master/tui/tui.go:156 +0x22
github.com/dundee/gdu/v5/cmd/gdu/app.(*App).Run(0xc000107d60)
    C:/Users/danie/Downloads/gdu-master/gdu-master/cmd/gdu/app/app.go:120 +0x2d2
main.runE(0xcbd260, {0xd15df0, 0x0, 0x0})
    C:/Users/danie/Downloads/gdu-master/gdu-master/cmd/gdu/main.go:96 +0x438
github.com/spf13/cobra.(*Command).execute(0xcbd260, {0xc000042200, 0x0, 0x0})
    C:/Users/danie/go/pkg/mod/github.com/spf13/cobra@v1.2.1/command.go:856 +0x60e
github.com/spf13/cobra.(*Command).ExecuteC(0xcbd260)
    C:/Users/danie/go/pkg/mod/github.com/spf13/cobra@v1.2.1/command.go:974 +0x3bc
github.com/spf13/cobra.(*Command).Execute(...)
    C:/Users/danie/go/pkg/mod/github.com/spf13/cobra@v1.2.1/command.go:902
main.main()
    C:/Users/danie/Downloads/gdu-master/gdu-master/cmd/gdu/main.go:100 +0x25

goroutine 57 [chan send]:
github.com/gdamore/tcell/v2.(*cScreen).PostEventWait(...)
    C:/Users/danie/go/pkg/mod/github.com/gdamore/tcell/v2@v2.4.1-0.20210905002822-f057f0a857a1/console_win.go:334
github.com/gdamore/tcell/v2.(*cScreen).getConsoleInput(0xc0001900f0)
    C:/Users/danie/go/pkg/mod/github.com/gdamore/tcell/v2@v2.4.1-0.20210905002822-f057f0a857a1/console_win.go:717 +0x735
github.com/gdamore/tcell/v2.(*cScreen).scanInput(0xc0001900f0, 0x0)
    C:/Users/danie/go/pkg/mod/github.com/gdamore/tcell/v2@v2.4.1-0.20210905002822-f057f0a857a1/console_win.go:770 +0x7e
created by github.com/gdamore/tcell/v2.(*cScreen).engage
    C:/Users/danie/go/pkg/mod/github.com/gdamore/tcell/v2@v2.4.1-0.20210905002822-f057f0a857a1/console_win.go:329 +0x292

goroutine 21 [chan receive]:
github.com/rivo/tview.(*Application).Run.func2()
    C:/Users/danie/go/pkg/mod/github.com/rivo/tview@v0.0.0-20210624165335-29d673af0ce2/application.go:275 +0x118
created by github.com/rivo/tview.(*Application).Run
    C:/Users/danie/go/pkg/mod/github.com/rivo/tview@v0.0.0-20210624165335-29d673af0ce2/application.go:254 +0x1c5
exit status 2
require (
	github.com/fatih/color v1.12.0
	github.com/gdamore/tcell/v2 v2.4.1-0.20210905002822-f057f0a857a1
	github.com/mattn/go-isatty v0.0.13
	github.com/rivo/tview v0.0.0-20210904173154-2f13f81dcb15
	github.com/sirupsen/logrus v1.8.1
	github.com/spf13/cobra v1.2.1
	github.com/stretchr/testify v1.7.0
	golang.org/x/sys v0.0.0-20210903071746-97244b99971b // indirect
	golang.org/x/term v0.0.0-20210615171337-6886f2dfbf5b // indirect
	golang.org/x/text v0.3.7 // indirect
)

Not sure if it's worth the debugging though :)

<!-- gh-comment-id:915477966 --> @dundee commented on GitHub (Sep 8, 2021): Looks like some problem still persists on Windows. The test script in https://github.com/gdamore/tcell/issues/480 works but tview application is not able to resume after being paused. It falls into deadlock: ``` fatal error: all goroutines are asleep - deadlock! goroutine 1 [select]: github.com/rivo/tview.(*Application).Run(0xc0000ae000) C:/Users/danie/go/pkg/mod/github.com/rivo/tview@v0.0.0-20210624165335-29d673af0ce2/application.go:302 +0x325 github.com/dundee/gdu/v5/tui.(*UI).StartUILoop(0xc000107d60) C:/Users/danie/Downloads/gdu-master/gdu-master/tui/tui.go:156 +0x22 github.com/dundee/gdu/v5/cmd/gdu/app.(*App).Run(0xc000107d60) C:/Users/danie/Downloads/gdu-master/gdu-master/cmd/gdu/app/app.go:120 +0x2d2 main.runE(0xcbd260, {0xd15df0, 0x0, 0x0}) C:/Users/danie/Downloads/gdu-master/gdu-master/cmd/gdu/main.go:96 +0x438 github.com/spf13/cobra.(*Command).execute(0xcbd260, {0xc000042200, 0x0, 0x0}) C:/Users/danie/go/pkg/mod/github.com/spf13/cobra@v1.2.1/command.go:856 +0x60e github.com/spf13/cobra.(*Command).ExecuteC(0xcbd260) C:/Users/danie/go/pkg/mod/github.com/spf13/cobra@v1.2.1/command.go:974 +0x3bc github.com/spf13/cobra.(*Command).Execute(...) C:/Users/danie/go/pkg/mod/github.com/spf13/cobra@v1.2.1/command.go:902 main.main() C:/Users/danie/Downloads/gdu-master/gdu-master/cmd/gdu/main.go:100 +0x25 goroutine 57 [chan send]: github.com/gdamore/tcell/v2.(*cScreen).PostEventWait(...) C:/Users/danie/go/pkg/mod/github.com/gdamore/tcell/v2@v2.4.1-0.20210905002822-f057f0a857a1/console_win.go:334 github.com/gdamore/tcell/v2.(*cScreen).getConsoleInput(0xc0001900f0) C:/Users/danie/go/pkg/mod/github.com/gdamore/tcell/v2@v2.4.1-0.20210905002822-f057f0a857a1/console_win.go:717 +0x735 github.com/gdamore/tcell/v2.(*cScreen).scanInput(0xc0001900f0, 0x0) C:/Users/danie/go/pkg/mod/github.com/gdamore/tcell/v2@v2.4.1-0.20210905002822-f057f0a857a1/console_win.go:770 +0x7e created by github.com/gdamore/tcell/v2.(*cScreen).engage C:/Users/danie/go/pkg/mod/github.com/gdamore/tcell/v2@v2.4.1-0.20210905002822-f057f0a857a1/console_win.go:329 +0x292 goroutine 21 [chan receive]: github.com/rivo/tview.(*Application).Run.func2() C:/Users/danie/go/pkg/mod/github.com/rivo/tview@v0.0.0-20210624165335-29d673af0ce2/application.go:275 +0x118 created by github.com/rivo/tview.(*Application).Run C:/Users/danie/go/pkg/mod/github.com/rivo/tview@v0.0.0-20210624165335-29d673af0ce2/application.go:254 +0x1c5 exit status 2 ``` ``` require ( github.com/fatih/color v1.12.0 github.com/gdamore/tcell/v2 v2.4.1-0.20210905002822-f057f0a857a1 github.com/mattn/go-isatty v0.0.13 github.com/rivo/tview v0.0.0-20210904173154-2f13f81dcb15 github.com/sirupsen/logrus v1.8.1 github.com/spf13/cobra v1.2.1 github.com/stretchr/testify v1.7.0 golang.org/x/sys v0.0.0-20210903071746-97244b99971b // indirect golang.org/x/term v0.0.0-20210615171337-6886f2dfbf5b // indirect golang.org/x/text v0.3.7 // indirect ) ``` Not sure if it's worth the debugging though :)
Author
Owner

@dundee commented on GitHub (Sep 8, 2021):

Minimal example:

package main

import (
	"fmt"
	"os"
	"os/exec"

	"github.com/gdamore/tcell/v2"
	"github.com/rivo/tview"
)

func main() {
	s, e := tcell.NewScreen()
	if e != nil {
		fmt.Fprintf(os.Stderr, "%v\n", e)
		os.Exit(1)
	}
	if e := s.Init(); e != nil {
		fmt.Fprintf(os.Stderr, "%v\n", e)
		os.Exit(1)
	}

	termApp := tview.NewApplication()
	termApp.SetScreen(s)

	box := tview.NewBox().SetBorder(true).SetTitle("Hello, world!")
	termApp.SetRoot(box, true)

	termApp.SetInputCapture(func(key *tcell.EventKey) *tcell.EventKey {
		if key.Rune() == 's' {
			termApp.Suspend(func() {
				cmd := exec.Command("vim", "/tmp/foo")
				cmd.Stdout = os.Stdout
				cmd.Stdin = os.Stdin
				_ = cmd.Run()
			})
		}
		return key
	})

	termApp.Run()
}
module example.com/m

go 1.17

require (
	github.com/gdamore/tcell/v2 v2.4.1-0.20210905002822-f057f0a857a1
	github.com/rivo/tview v0.0.0-20210904173154-2f13f81dcb15
)

require (
	github.com/gdamore/encoding v1.0.0 // indirect
	github.com/lucasb-eyer/go-colorful v1.2.0 // indirect
	github.com/mattn/go-runewidth v0.0.13 // indirect
	github.com/rivo/uniseg v0.2.0 // indirect
	golang.org/x/sys v0.0.0-20210309074719-68d13333faf2 // indirect
	golang.org/x/term v0.0.0-20210220032956-6a3ed077a48d // indirect
	golang.org/x/text v0.3.6 // indirect
)

This example doesn't crash on the first suspend but on the second one:

fatal error: all goroutines are asleep - deadlock!

goroutine 1 [select]:
github.com/rivo/tview.(*Application).Run(0xc00016e000)
        C:/Users/danie/go/pkg/mod/github.com/rivo/tview@v0.0.0-20210904173154-2f13f81dcb15/application.go:302 +0x325
main.main()
        C:/Users/danie/test/main.go:41 +0x2d5

goroutine 5 [chan receive]:
github.com/rivo/tview.(*Application).Run.func2()
        C:/Users/danie/go/pkg/mod/github.com/rivo/tview@v0.0.0-20210904173154-2f13f81dcb15/application.go:275 +0x118
created by github.com/rivo/tview.(*Application).Run
        C:/Users/danie/go/pkg/mod/github.com/rivo/tview@v0.0.0-20210904173154-2f13f81dcb15/application.go:254 +0x1c5

goroutine 6 [chan send]:
github.com/gdamore/tcell/v2.(*cScreen).PostEventWait(...)
        C:/Users/danie/go/pkg/mod/github.com/gdamore/tcell/v2@v2.4.1-0.20210905002822-f057f0a857a1/console_win.go:334
github.com/gdamore/tcell/v2.(*cScreen).getConsoleInput(0xc000150000)
        C:/Users/danie/go/pkg/mod/github.com/gdamore/tcell/v2@v2.4.1-0.20210905002822-f057f0a857a1/console_win.go:717 +0x735
github.com/gdamore/tcell/v2.(*cScreen).scanInput(0xc000150000, 0x0)
        C:/Users/danie/go/pkg/mod/github.com/gdamore/tcell/v2@v2.4.1-0.20210905002822-f057f0a857a1/console_win.go:770 +0x7e
created by github.com/gdamore/tcell/v2.(*cScreen).engage
        C:/Users/danie/go/pkg/mod/github.com/gdamore/tcell/v2@v2.4.1-0.20210905002822-f057f0a857a1/console_win.go:329 +0x292
exit status 2
<!-- gh-comment-id:915490728 --> @dundee commented on GitHub (Sep 8, 2021): Minimal example: ``` package main import ( "fmt" "os" "os/exec" "github.com/gdamore/tcell/v2" "github.com/rivo/tview" ) func main() { s, e := tcell.NewScreen() if e != nil { fmt.Fprintf(os.Stderr, "%v\n", e) os.Exit(1) } if e := s.Init(); e != nil { fmt.Fprintf(os.Stderr, "%v\n", e) os.Exit(1) } termApp := tview.NewApplication() termApp.SetScreen(s) box := tview.NewBox().SetBorder(true).SetTitle("Hello, world!") termApp.SetRoot(box, true) termApp.SetInputCapture(func(key *tcell.EventKey) *tcell.EventKey { if key.Rune() == 's' { termApp.Suspend(func() { cmd := exec.Command("vim", "/tmp/foo") cmd.Stdout = os.Stdout cmd.Stdin = os.Stdin _ = cmd.Run() }) } return key }) termApp.Run() } ``` ``` module example.com/m go 1.17 require ( github.com/gdamore/tcell/v2 v2.4.1-0.20210905002822-f057f0a857a1 github.com/rivo/tview v0.0.0-20210904173154-2f13f81dcb15 ) require ( github.com/gdamore/encoding v1.0.0 // indirect github.com/lucasb-eyer/go-colorful v1.2.0 // indirect github.com/mattn/go-runewidth v0.0.13 // indirect github.com/rivo/uniseg v0.2.0 // indirect golang.org/x/sys v0.0.0-20210309074719-68d13333faf2 // indirect golang.org/x/term v0.0.0-20210220032956-6a3ed077a48d // indirect golang.org/x/text v0.3.6 // indirect ) ``` This example doesn't crash on the first suspend but on the second one: ``` fatal error: all goroutines are asleep - deadlock! goroutine 1 [select]: github.com/rivo/tview.(*Application).Run(0xc00016e000) C:/Users/danie/go/pkg/mod/github.com/rivo/tview@v0.0.0-20210904173154-2f13f81dcb15/application.go:302 +0x325 main.main() C:/Users/danie/test/main.go:41 +0x2d5 goroutine 5 [chan receive]: github.com/rivo/tview.(*Application).Run.func2() C:/Users/danie/go/pkg/mod/github.com/rivo/tview@v0.0.0-20210904173154-2f13f81dcb15/application.go:275 +0x118 created by github.com/rivo/tview.(*Application).Run C:/Users/danie/go/pkg/mod/github.com/rivo/tview@v0.0.0-20210904173154-2f13f81dcb15/application.go:254 +0x1c5 goroutine 6 [chan send]: github.com/gdamore/tcell/v2.(*cScreen).PostEventWait(...) C:/Users/danie/go/pkg/mod/github.com/gdamore/tcell/v2@v2.4.1-0.20210905002822-f057f0a857a1/console_win.go:334 github.com/gdamore/tcell/v2.(*cScreen).getConsoleInput(0xc000150000) C:/Users/danie/go/pkg/mod/github.com/gdamore/tcell/v2@v2.4.1-0.20210905002822-f057f0a857a1/console_win.go:717 +0x735 github.com/gdamore/tcell/v2.(*cScreen).scanInput(0xc000150000, 0x0) C:/Users/danie/go/pkg/mod/github.com/gdamore/tcell/v2@v2.4.1-0.20210905002822-f057f0a857a1/console_win.go:770 +0x7e created by github.com/gdamore/tcell/v2.(*cScreen).engage C:/Users/danie/go/pkg/mod/github.com/gdamore/tcell/v2@v2.4.1-0.20210905002822-f057f0a857a1/console_win.go:329 +0x292 exit status 2 ```
Author
Owner

@gdamore commented on GitHub (Sep 8, 2021):

Interesting -- I tested this on Linux, but not Windows. I guess maybe there is a completely separate bug on Windows. One thing I did try is the mouse.go demo -- which goes through this several times.

<!-- gh-comment-id:915543280 --> @gdamore commented on GitHub (Sep 8, 2021): Interesting -- I tested this on Linux, but not Windows. I guess maybe there is a completely separate bug on Windows. One thing I did try is the mouse.go demo -- which goes through this several times.
Author
Owner

@bcspragu commented on GitHub (Oct 15, 2023):

EDIT: Adding an app.Sync() after the app.Suspend call fixed my issue.

Found this issue after hitting the same thing with a more/less identical chunk of code. Relevant snippet:

	editor := os.Getenv("EDITOR")
	if editor == "" {
		editor = "vi"
	}

	success := true
	u.app.Suspend(func() {
		cmd := exec.CommandContext(ctx, editor, f.Name())
		cmd.Stdin = os.Stdin
		cmd.Stdout = os.Stdout
		cmd.Stderr = os.Stderr

		if err := cmd.Run(); err != nil {
			log.Printf("error while editing file: %v", err)
			success = false
		}
	})

The editor opens fine, but the program hangs after closing. I'm on Arch Linux, using alacritty + tmux, and using the latest versions of both tview (6c844bdc5f7a) and tcell (v2.6.0). The whole TUI app is available here: https://git.sr.ht/~bsprague/logseq-ui/tree/main/item/tui/tui.go

<!-- gh-comment-id:1763238989 --> @bcspragu commented on GitHub (Oct 15, 2023): EDIT: Adding an `app.Sync()` after the `app.Suspend` call fixed my issue. Found this issue after hitting the same thing with a more/less identical chunk of code. Relevant snippet: ```go editor := os.Getenv("EDITOR") if editor == "" { editor = "vi" } success := true u.app.Suspend(func() { cmd := exec.CommandContext(ctx, editor, f.Name()) cmd.Stdin = os.Stdin cmd.Stdout = os.Stdout cmd.Stderr = os.Stderr if err := cmd.Run(); err != nil { log.Printf("error while editing file: %v", err) success = false } }) ``` The editor opens fine, but the program hangs after closing. I'm on Arch Linux, using alacritty + tmux, and using the latest versions of both tview (`6c844bdc5f7a`) and tcell (`v2.6.0`). The whole TUI app is available here: https://git.sr.ht/~bsprague/logseq-ui/tree/main/item/tui/tui.go
Author
Owner

@bcspragu commented on GitHub (Oct 20, 2023):

just go running the latest git clone from your repo seems to work dandy. are you all good now?

I'm not the original poster, just someone who ran into the same behavior, but I was indeed able to fix the problem by adding an app.Sync(), so it may or may not be related to the underlying issue other folks have mentioned here.

<!-- gh-comment-id:1772709987 --> @bcspragu commented on GitHub (Oct 20, 2023): > just go running the latest git clone from your repo seems to work dandy. are you all good now? I'm not the original poster, just someone who ran into the same behavior, but I was indeed able to fix the problem by adding an `app.Sync()`, so it may or may not be related to the underlying issue other folks have mentioned here.
Sign in to join this conversation.
No milestone
No project
No assignees
1 participant
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set.

Reference
starred/tview#187
No description provided.