jesseduffield / lazygit

simple terminal UI for git commands
MIT License
50.97k stars 1.79k forks source link

`syscall.Errno bad file descriptor` #1745

Open wolfgangwalther opened 2 years ago

wolfgangwalther commented 2 years ago

Describe the bug lazygit dies with the following:

2022/01/29 13:45:11 An error occurred! Please create an issue at: https://github.com/jesseduffield/lazygit/issues

syscall.Errno bad file descriptor
github.com/jesseduffield/lazygit/main.go:145 (0x555f4d362cb9)
runtime/proc.go:255 (0x555f4cdec107)
runtime/asm_amd64.s:1581 (0x555f4ce1a181)

To Reproduce It happened 3 times across the last couple of days, but I couldn't recreate it on purpose so far.

The last time it happened I was just switching tabs - from 3 to 4, I think. Nothing special. I think I just completed a rebase before.

Some jest tests were running at the same time and there was a snapshot updated at the same time. Might be related. Might be not. Can't remember whether that was the case before, too.

Expected behavior Don't die, lazygit!

Desktop:

Additional context Lazygit is great. Thanks a lot!

laurentS commented 2 years ago

I'm seeing the same behaviour with 0.34:

I have the feeling that this happens after some external program deletes/recreates a file that is in the index (maybe partially), which could explain the bad file descriptor error. I've now seen this crash 9 times in a row. Sometimes the crash is on the first keypress, sometimes it survives for several dozen keypresses (only doing j or k for the sake of testing, though using up/down arrow keys crashed it at least once the same way). After unstaging/restaging the file, the crash does not seem to happen anymore, until I rerun external program that deletes/recreates the file again.

Exact stack trace, just in case:

syscall.Errno bad file descriptor
/home/runner/work/lazygit/lazygit/main.go:145 (0xa8c8c5)
/opt/hostedtoolcache/go/1.16.15/x64/src/runtime/proc.go:225 (0x4389b6)
/opt/hostedtoolcache/go/1.16.15/x64/src/runtime/asm_amd64.s:1371 (0x46c5e1)

Thanks for making lazygit, it's brilliant!

jesseduffield commented 2 years ago

thanks for the thorough troubleshooting :) It's unfortunate that we're bubbling the error all the way up without wrapping it initially. That makes it a little trickier to spot where it's happening.

laurentS commented 2 years ago

I just skimmed through the contribution guide. I will try to repro with debug on, and maybe rebuild from source (and fix? :scream:). No Go experience, but it seems like a good opportunity, since I should be able to repro.

jesseduffield commented 2 years ago

Nice :) Let me know if you need anything

laurentS commented 2 years ago

I spent a couple hours trying to follow the code. It's a bit painful as it's my first time with go. I've added a bunch of logging where I thought it would make sense, but haven't nailed it yet. What I saw is that the keypress on j|k|up|down generates a gEvent and immediately after a userEvent (which seems to be enqueued by the first one, and happens asynchronously, is that correct?).

The first event is not where the crash happens, but it might be in the second one, or something that happens as a consequence of it. I'll keep digging, but if there's an obvious place where I should look based on the above, please let me know. Also I'm struggling a bit with logging from the vendorized parts of the code where the logger instance is not available. So far, I've only managed to print stuff to screen in random locations over the UI (with the builtin println), and that does not survive the crash, so it's not very helpful.

jesseduffield commented 2 years ago

Sounds like good progress. As for logging in gocui, here's what I do:

func newLogger() *logrus.Entry {
    // REPLACE THE BELOW PATH WITH YOUR ACTUAL LOG PATH (YOU'LL SEE THIS PRINTED WHEN YOU RUN `lazygit --logs`
    logPath := "/Users/jesseduffieldduffield/Library/Application Support/jesseduffield/lazygit/development.log"
    file, err := os.OpenFile(logPath, os.O_CREATE|os.O_WRONLY|os.O_APPEND, 0666)
    if err != nil {
        panic("unable to log to file")
    }
    logger := logrus.New()
    logger.SetLevel(logrus.WarnLevel)
    logger.SetOutput(file)
    return logger.WithFields(logrus.Fields{})
}

var Log = newLogger()
...
Log.Warn("blah")

I'll add this to the contributing guide

jesseduffield commented 2 years ago

Added to the contribute guide here: https://github.com/jesseduffield/lazygit/blob/master/CONTRIBUTING.md#debugging

laurentS commented 2 years ago

Since I stopped using https://github.com/neoclide/coc.nvim and https://github.com/fannheyward/coc-pyright/ I've not seen this issue anymore. My understanding is that those vim plugins would do autoformatting of files on save using something like:

copy buffer to a tempfile
process tempfile with external program to format it (like `prettier` or `black`)
overwrite original file with formatted temp file

That behaviour seems to be what makes lazygit unhappy. I've not been able to identify where in the code the problem is, but I think it's in some vendorised part. Not really a fix, but a clue which may help?