4 ms·
You can achieve that on other OSes too though, still without requiring libc. For instance, on Windows the syscall API is hidden and changes from release to rel
by kayamon 8y ago
You can achieve that on other OSes too though, still without requiring libc.
For instance, on Windows the syscall API is hidden and changes from release to release, but KERNEL32.DLL persists as the stable system API that you're supposed to call.
Linux desperately needs to get past the notion that libc is the only gateway to the kernel, and instead start supplying a standardized "system/kernel" user-level wrapper library. One which wraps the syscalls nicely but doesn't try to add additional language-specific functionality like printf or memcpy.
- int_19h 8y agoOn Windows, kernel32.dll is basically the Windows equivalent of libc - it's still a userspace library that wraps syscalls, and you're not supposed to use them directly. But I don't see why it's a problem, either. What's the actual benefit of Go invoking syscalls directly on Linux? That it doesn't depend on glibc? But that is only an advantage because glibc is not guaranteed to be there on Linux, the way e.g. kernel32 is on Windows. If it were, there'd be no reason to not use it.
- IshKebab 8y ago> That it doesn't depend on glibc? But that is only an advantage because glibc is not guaranteed to be there on Linux, the way e.g. kernel32 is on Windows. If it were, there'd be no reason to not use it. Yes - but it's an advantage because glibc is a compatibility nightmare. One of Go's really nice features is that you can compile a binary and it will run pretty much anywhere. That would be pretty much impossible if it linked with glibc (even if you ignore the fact that glibc might not be present).
- 4ad 8y agoNot true. On Solaris (and Windows), and more recently in macOS as well we link with libc (or equivalent), and we can still cross compile from any system to these systems. It's not a free lunch of course, doing raw system calls would be preferable, for many reasons. I implemented support for this, for ELF, when I wrote the Solaris port. Other people have done it for PE and Mach-O. It is a fallacy to think that you need access to a shared library in order to link with it. That's only true for C toolchains that don't know better. For Go we have our own toolchain and it doesn't have such a restriction. This is one of the points lost to the "why didn't you just use LLVM?" crowds. Our own toolchain allows us flexibility that simply doesn't exist with traditional toolchains.
- matthewbauer 8y agoHow do you handle changes to the kernel? Can your binaries run on any macOS version or only the very latest? This sounds really cool but also super dangerous. Apple is not known for providing a stable ABI :)
- 4ad 8y agoYou got it backwards, Go used to do raw system calls on macOS, and binaries were occasionally broken by kernel updates. Now Go uses libc on macOS, and binaries are forward compatible with future macOS versions just like any other C/C++/ObjC/swift program. OS X 10.10 (Yosemite) is the current minimum supported version.
- matthewbauer 8y agoOk nice! In many ways it would be cool if apple had a stable interface for XNU like we do in Linux.
- int_19h 8y agoUnfortunately, Go still insists on using syscalls on the BSDs, despite them not being a stable (between major releases) API there either. I hope they're planning to fix that...
- swiley 8y agoThis used to be true, Unfortunately it’s not now. I found this out when trying to copy a go program I had compiled on alpine to an Ubuntu machine and got the “file not found” error from the linker. :( Try it yourself: run ldd on a recent go binary.
- zaarn 8y agoGo uses the glibc for DNS resolution by default, if you set CGO_ENABLED=0 during compiling it should result in a static binary.
- vetinari 8y agoSpecifically Go has very particular ideas about memory and stack layout, which do not go well with C libraries. In order to call a C library, Go has to go through thunking shims. When using syscalls directly, it does not matter. Kernel doesn't care how your laid out your userspace stack.
- cesarb 8y ago> Kernel doesn't care how your laid out your userspace stack. Except when it does: https://github.com/golang/go/issues/20427 https://github.com/golang/go/issues/20427
- zaarn 8y agoIIRC this was because of a rather amusing behaviour of a Gentoo toolchain with some hardening patches, in this case doing a bit of fun on the stack to make sure it's safe. A lot of the hardening patches come with disclaimers that some software might break, and as shown by this bug, for good reason. I'd rather blame the compiler patches for this silly behaviour (and maybe the kernel for not documenting and limiting how much stack VDSO can use)
- ben0x539 8y agoIt's not really obvious to me that the original issue, mentioning os.Exec calls and Ubuntu versions, has the same cause as the crashes from the commenter mentioning patched Gentoo toolchains.
- bregma 8y ago"libc" is the C-language runtime library. The Go language is not the C language. Different things are different. There is no reason for programs written in the Go language to use the C-language runtime in any operating environment, any more than there is a requirement for all programming languages to use curly braces to delimit lexical scope.
- vetinari 8y ago> Linux desperately needs to get past the notion that libc is the only gateway to the kernel, Are you sure about that? Linux doesn't have that notion, it keeps the syscal ABI stable, and anyone can use it directly, like Go does. There's no need to go through blessed syscall library, which on their respective systems are the only gateway to the kernel.
- masklinn 8y agoThe biggest advantage is that it lets other OS easily impersonate linux e.g. SmartOS or Windows can provide kernel-level "linux persona" and have an unmodified linux userland run on top.
- int0x80 8y agoThey can do right now. Both the API and ABI are very rarely (read never but very problematic bugs or similar) broken in a backwards way.
- masklinn 8y agoThat's my point. It's only possible with Linux because Linux provides a stable kernel ABI. You can't impersonate Windows or OSX the same way.