4 ms·
The problem is the "write everything in Go" mentality doesn't result in the best result. Syscall interfaces aren't easy, and glibc has been doing this properly
by marcan_42 5y ago
The problem is the "write everything in Go" mentality doesn't result in the best result. Syscall interfaces aren't easy, and glibc has been doing this properly for ages; Go reinvented it and screwed up vDSO calls.
I want whatever programming language I use to allow me to make use of the best possible code available. These days, that means C libraries very often, especially when performance is concerned (this isn't a "C is fast" thing, it's a "people have already spent decades optimizing C libraries, often with architecture-specific SIMD and assembly" thing). Not only that, but this is required on Windows for syscalls. Go started off with this idea of prioritizing reinventing the world over a good FFI, and is now paying the price in overhead on Windows, because they couldn't reinvent the world there. If they had a good FFI, they also wouldn't have had to reinvent glibc, and would avoid the potential bugs that come with that.
In the end, I just don't agree with treating FFI as a second class citizen. You need to be able to interoperate well with the C world (Rust is a good example of this).
- matheusmoreira 5y ago> Syscall interfaces aren't easy The Linux system call binary interface is pretty easy though. Put a bunch of values in registers, system call instruction, get result back in register. I'm surprised the Go compiler can't emit code that follows this calling convention. I've seen projects here that do just that and it's really nice. I agree that the vDSO is more complex. It's a shared object that exports symbols with the C binary interface. Much harder to interface with. > These days, that means C libraries very often, especially when performance is concerned (this isn't a "C is fast" thing, it's a "people have already spent decades optimizing C libraries, often with architecture-specific SIMD and assembly" thing). I can respect that. Go always had a focus on eliminating dependencies though. Using system calls directly allows Go executables to be freestanding, they don't even require system libc. I think this is an interesting proposition for systems programming. Great for executables that must work even when the rest of the system is screwed up. > Not only that, but this is required on Windows for syscalls. > Go started off with this idea of prioritizing reinventing the world over a good FFI I completely agree with your criticism of Go here. They shouldn't have attempted this on other systems. I read your description of how some macOS update broke Go software because the kernel ABI changed. That's insane and should never have happened. Linux is the only kernel with a stable system call binary interface, the only system where reinventing the world is possible. > In the end, I just don't agree with treating FFI as a second class citizen. Absolutely agree with you. Rust does this much better, it has proper support for foreign calling conventions. Don't think the vDSO problem would have happened in Rust. It also supports freestanding code! Thanks for replying. I agree with you. I think this is a good idea on Linux specifically but as you noted it's problematic if applied to other platforms.
- Abishek_Muthian 5y agoFor the first time I've seen some seemingly valid criticism Go (thanks Marcan) and some good counter reasoning in the replies. To summarize, If I don't use CGO, Don't mind the increasingly large binary and run my Go production application only on Linux I wouldn't be facing the issues faced by Marcan?
- matheusmoreira 5y ago> If I don't use CGO Well, the vDSO bug Marcan described happened because the Go runtime itself was supposed to properly interoperate with a C library but didn't. https://github.com/torvalds/linux/blob/master/Documentation/ABI/stable/vdso https://github.com/torvalds/linux/blob/master/Documentation/... > These functions are called just like ordinary C function according to your platform's ABI. > Call them from a sensible context. Go wasn't calling them from a sensible context. The functions didn't have enough stack space. Not sure if there are more ABI problems like that in the Go runtime. Probably not since the vDSO is Linux-specific and it's already been fixed. > run my Go production application only on Linux You should be fine. Linux system call binary interface is stable. https://github.com/torvalds/linux/blob/master/Documentation/ABI/stable/syscalls https://github.com/torvalds/linux/blob/master/Documentation/... If Linux is all you're depending on then you're good.
- Abishek_Muthian 5y agoUnderstood, Thanks for being precise and succinct. > Not sure if there are more ABI problems like that in the Go runtime. Probably not since the vDSO is Linux-specific and it's already been fixed. Thanks to people like Marcan who put the effort in debugging and getting them fixed. Although it's a shame that the time-frame wasn't reasonable to Marcan and it seems to have influenced his decision to not indulge in such activities further.