10 ms·
Whenever the topic of Go bypassing the libc was brought up before the concerns were usually dismissed by the Go devs, saying that it was technically impractical
by simias 6y ago
Whenever the topic of Go bypassing the libc was brought up before the concerns were usually dismissed by the Go devs, saying that it was technically impractical due to some of Go's requirements not matching the libc's semantics.
Does this mean that the Go developers managed to work around this problem or that it was just a flimsy post-hoc justification for chronic NIH syndrome?
TFA itself links to another blog post discussing "Some reasons for Go to not make system calls through the standard C library"[1] but as far as I can tell it doesn't explain why it suddenly stopped being a problem on OpenBSD.
[1] https://utcc.utoronto.ca/~cks/space/blog/programming/GoCLibraryAPIIssues https://utcc.utoronto.ca/~cks/space/blog/programming/GoCLibr...
- killingtime74 6y agoThe NIH one, as always with Go
- knorker 6y agoIt's a clash of two NIH worlds: Go and OpenBSD. :-)
- masklinn 6y agoI mean OpenBSD is hardly the first let alone only system which mandates going through libc (or equivalent) to interact with the OS.
- knorker 6y agoDon't get me wrong, it makes perfect sense. And Go seems to aim more towards pragmaticism than OpenBSD's elegance and correctness. OpenBSD is deciding to invent their own paintbrush without even looking at what other people are painting with, while Go took the closest bucket of paint and threw it on the floor, not realizing they were standing in a corner while doing so. And I say that as a happy user of both.
- AnIdiotOnTheNet 6y ago> Does this mean that the Go developers managed to work around this problem or that it was just a flimsy post-hoc justification for chronic NIH syndrome? No, there is almost certainly a bunch of headache having to do system calls through libc for Go. It didn't stop being a problem, there just isn't another option in OpenBSD's case. UNIXs are tricky for anyone who doesn't want to use libc since they typically define that as the official interface to the system. Linux is the outlier here by keeping its syscall ABI very stable.
- simias 6y agoI understand that but if they're going to go down that route for OpenBSD why not bring it to all platforms? While I can believe that going the raw syscall route can be easier than dealing with libc idiosyncrasies, it seems to me that maintaining both interfaces depending on the target OS would be trickier than just cutting your losses and going the libc route everywhere. After all as far I can tell it's not just an OpenBSD problem since famously they got breakage in MacOS as well. I must admit that I haven't taken the time to analyze in depth the pros and cons here, but Go's history of NIH coupled with the fact that basically every other mainstream language manages to work by binding the libc leaves me very perplex. In particular some of the points raised in the blogpost I linked seem fishy to me. For instance errno being a global: this is in no way a Go-specific problem (multithreaded C couldn't run concurrent syscalls if it was true). In practice errno is thread-local instead of being a true global. It's explicitly documented in the man page: > errno is defined by the ISO C standard to be a modifiable lvalue of type int, and must not be explicitly declared; errno may be a macro. errno is thread-local; setting it in one thread does not affect its value in any other thread. I can believe that there are other issues I fail to consider, but again it works for everybody else, what makes Go so special here?
- wbl 6y agoGo wants low overhead multithreading and static linkage. Glibc is inherently dynamically linked, and sets up threads in ways Go doesn't want. Error doesn't work for everyone else. It's a hack, you wouldn't do it if it wasn't for backwards compatability.
- hda111 6y agoOne reason not to go through libc is the possibility to create a pure Go userland like it’s done with the u-root project that is apparently in use at Google and resembles Busybox based systems with a memory safe language.
- simias 6y agoUnless you plan to never run anything but Go on your system you're going to need a libc at one point or an other. If anything this decision reinforces the NIH hypothesis for me. Almost like a prideful "NO C ALLOWED" stance which is not really pragmatic IMO. The only counterargument I can think off would be to remove the libc footprint for ultra-small, go-only distributions but I highly doubt that it's significant on any modern system (even an embedded one) and if you care so much about reducing the runtime footprint why would you go with a GC language in the first place?
- macksd 6y ago>> Unless you plan to never run anything but Go on your system That's actually exactly the use case for a lot of containerized applications written in Go. edit: I've worked on multiple applications like this and there's the odd service where you need some other dependency, and then that service has to start running on Alpine Linux or something. But if the majority of your many "microservices" are pulling in bits of userland from a distro, they stop being "micro" very quickly which is a big deal when there's a lot of them. It's far preferable in that architecture if the entirety of your userland is your own binary.
- acoard 6y ago>Alpine Linux From their website:[0] >"Alpine Linux is built around musl libc and busybox" I could be off-base here, but it seems to me the better analogy would be some sort of "Go-Linux" that's like a Docker linux OS written entirely in Go. [0]: https://alpinelinux.org/about/ https://alpinelinux.org/about/
- 6y ago
- tyingq 6y agoIt's OpenBSD's plan to eventually shut down any other option via system call origin verification. So golang has to bite the bullet at some point. "The eventual goal would be to disallow system calls from anywhere but the region mapped for libc" https://lwn.net/Articles/806776/ https://lwn.net/Articles/806776/
- quotemstr 6y ago> Go devs, saying that it was technically impractical due to some of Go's requirements not matching the libc's semantics. I've always considered claims like this to be bullshit. I've worked a lot with both libc level system calls and (for crash report generation) direct system calls bypassing libc. They're the same interface. There's nothing you can do with a raw system call interface that you can't do through raw libc --- with rare exceptions for things like libc not having system call wrappers for some new system call or legacy ill-advised emulation like in fallocate. None of these exceptions is a justification for bypassing libc for calling open(2) or write(2). As far as I can tell, the real reason Go eschewed libc system call interfaces is that the Go developers want to think of themselves as "not C".
- ominous_prime 6y agoGo has a different calling convention and stack layout from C, and wanted completely static binaries which you cannot always get when linking to the standard libc implementations. What is "bullshit" about these compatibility concerns? It's not like _Ken Thompson_ was unaware of how to use libc.
- quotemstr 6y agoYet Go can call libc functions just fine on many OSes. Why can't it on Linux? Every single other managed runtime --- Mono, Java, Python --- can call through libc just fine. There is zero technical case for Go not doing the same thing. The bullshit lies in these FUDlike insinuations that using libc would limit Go in some way. These insinuations are never backed up with technical specifics. I don't care that famous names are involved with Go: the presence of these people doesn't make Go's behavior correct or necessary. There is zero technical case for Go doing what it does on Linux. You can make a "fully static binary" (which is a terrible idea anyway) with libc. Nobody should be making static binaries.
- int_19h 6y agoThere are many languages and runtimes that use their own calling conventions - not the least of which is C++ - and even stack layouts. The problem with Go is specifically the spaghetti stack that they need for coroutines. But that is an inherent design issue - a systems programming language is supposed to play well with the system, and that means being able to use the standard OS APIs properly. Which on basically all platforms other than Linux means going via libc or equivalent (e.g. Win32). Go designers just unilaterally decided that the rules don't apply to them, because reasons. And the end result was stuff like this: https://github.com/golang/go/issues/16606 https://github.com/golang/go/issues/16606 So now they're gradually backtracking on all platforms - macOS switched to libc a while ago.
- hacknat 6y agoNormally I agree with anit-NIH sentiments, but why are we all supposed to just have to be happy with a language ABI that's been around since the 1970s?
- macksd 6y agoYou would probably find yourself asking similar questions a lot in OpenBSD land - they're very committed to stability and security even if it means forfeiting many modern features. As I say in another comment, wanting to run Go on OpenBSD the way it does on Linux is a collision of very different philosophies. Hard to say one is wrong, but if they want to coexist one of them would eventually have to compromise, and it was never going to be OpenBSD in the end.
- simias 6y agoIf it ain't broke... Having a common entrypoint into the kernel we can hook into is fairly valuable IMO, especially when said interface is for the most part stable between all unx (and to a somewhat lesser extent even on Windows). Having this lowest common denominator ABI makes interop relatively* painless. But clearly Go wants to eat the world and doesn't seem to care very deeply about this. I suppose it's a valid approach, even if I don't necessarily agree with it.
- convolvatron 6y agoIf it ain't broke... user supplied read addresses getpwent() - actually really the whole notion of users file permissions aynch storage event completion (all asynchrony is pretty broken) system metadata control (sysctl, /proc, interface socket messages...) signals ttys errno affinity interfaces ...
- bshanks 6y agoCould you give any pointers to what is broken about these, and how a better way to do it would be? (I'm thinking about implementing a small system call library interface and I'd like to not repeat the mistakes of the past)
- masklinn 6y ago> as far as I can tell it doesn't explain why it suddenly stopped being a problem on OpenBSD. It doesn't. It's just that as previously with macOS, Illumos, or Windows, the Go project ended up with its back against the wall: in this case, ultimately only the OpenBSD libc will be allowed to make syscalls so their choices are "use libc" and "no Go on OpenBSD". And in all honesty the followup https://utcc.utoronto.ca/~cks/space/blog/unix/CLibraryAPIRequiresC https://utcc.utoronto.ca/~cks/space/blog/unix/CLibraryAPIReq... is much more convincing as to why it's a hassle to go through libc.