
On Go, Portability, and System Interfaces (2015) - Annatar
http://garrett.damore.org/2015/09/on-go-portability-and-system-interfaces.html?m=1
======
masklinn
> The problem I believe stems from some misconceptions, and some historical
> precedents in the Go community.

It's not just "historical precedents in the Go community" it's "ongoing in Go
itself": Go's developers will try as hard and as long as they can to perform
raw syscalls even on platforms where it's not officially supported, and even
on the one platform where it is genuinely actually supported they'll do raw
vDSO calls (which are not) which predictably blows up
([https://marcan.st/2017/12/debugging-an-evil-go-runtime-
bug/](https://marcan.st/2017/12/debugging-an-evil-go-runtime-bug/)).

[0] which is pretty much all of them aside from Linux, Golang 1.11 finally
stops performing raw syscalls on OSX

~~~
Immortalin
Other than buffering, why are libc calls faster than system calls?

~~~
masklinn
libc calls are not faster than system calls.

~~~
Immortalin
Explain this comment:
[https://news.ycombinator.com/item?id=18057649](https://news.ycombinator.com/item?id=18057649)

~~~
masklinn
This comment is saying that the _overhead_ of the libc calls is (or should be)
almost nothing compared to the cost of the syscall itself. The libc calls
wraps the syscall, it can't be faster (vDSO aside).

~~~
Immortalin
Ah! That makes sense now. I thought it would be impossible for LibC to be
faster than a syscall short of it cannibalizing the kernel.

------
cdoxsey
> Basically, the Go folks want to minimize external dependencies and the web
> of failure that can lead to. Fixing that is a goal I heartily agree with.
> However, we cannot eliminate our dependency on the platform. And using
> system calls directly is actually worse, because it moves our dependency
> from something that is stable and defined by standards bodies, to an
> interface that is undocumented, not portable, and may change at any time.

It's also for performance reasons. Calling a C function from Go is actually
quite complicated and can involve copying a lot of data. Using a syscall
directly avoids that cost.

~~~
gok
That has got to be a total drop in the bucket compared the cost of the syscall
itself.

~~~
valarauca1
Kernel interrupt handling is incredibly quick.

Tasking switching an the related MMU updates is slower. As you have to perform
a kernel interrupt handling action just to start initializing the task switch.

~~~
majewsky
Interrupt handling is quick, paging isn't.

~~~
monocasa
The KPTI Meltdown fixes mean that interrupt handling _is_ paging on a lot of
chips out there.

------
coldtea
> _How did we wind up in this ugly situation? The problem I believe stems from
> some misconceptions, and some historical precedents in the Go community.
> First the Go community has long touted static linking as one of its
> significant advantages. However, I believe this has been taken too far._

How about people just go out to solve their problems, in their own platforms,
and don't care to support all platforms?

It's not like most of those Go projects are big in the first place, and one or
a couple of contributors don't have the means to test other platforms much, or
the time to write it platform-agnostically.

~~~
gok
If the goal was "Go is a language for Linux", fine. But that wasn't the goal.
From the first release it was targeted to macOS, Windows and other platforms,
but implemented in a way that didn't make any sense on those platforms.

~~~
pjmlp
Actually Go was implemented as OS X and Linux language initially.

They left up to the community to build up Windows support.

Certain packages are still not available on Windows, like plugins for example.

Easy to find that out searching early gonuts posts.

~~~
gok
Ok I stand corrected; they only botched it on 50% of their initial targets :)

------
lelf
Not to mention systems without syscalls [as concept] at all.

Simple example: GNU/Hurd’s glibc works _quite_ differently.

------
twic
Is there an official documented rationale for why the Go standard library
doesn't go use libc, and instead does all this direct syscall stuff?

I've heard various stories about it over the years, so i would appreciate an
authoritative source.

~~~
valarauca1

         why the Go standard library doesn't go use libc
    

They do you use a `libc` they use `musl-libc` [1] as apposed to `gnu-libc`
(gblic) [2]. There are some differences [3], the largest (without getting into
various API incompatibilities) is licensing. `musl-libc` is BSD licensed,
while `gnu-libc` (glibc) is GPL licensed.

The parent post does explain, about as well as any member of the go-team has
to date for their usage of `musl-libc` over `gnu-libc` (glibc). Overall `musl-
libc` does focus on correctness a lot more then `glibc`, and static linking is
a large benefit.

Static linking isn't an issue when you expect applications to be short lived
transient items. Where system images only exist for days, or hours before
being redeployed by either patches, or CI-Managered triggered updates. I think
this is the largest disconnect. Go expects the development pipeline to be
quick so nobody expects multi-year lifespan binaries, which is directly
contradictory to how many expect executable binaries to behave.

No that I'm authority on this, just stating a common disconnect I've
experienced working with ex-Googlers.

[1] [https://www.musl-libc.org/](https://www.musl-libc.org/)

[2] [https://www.gnu.org/software/libc/](https://www.gnu.org/software/libc/)

[3] [https://wiki.musl-libc.org/functional-differences-from-
glibc...](https://wiki.musl-libc.org/functional-differences-from-glibc.html)

[4]
[https://github.com/golang/go/issues/9627](https://github.com/golang/go/issues/9627)

~~~
masklinn
> They do you use a `libc` they use `musl-libc` [1] as apposed to `gnu-libc`
> (gblic) [2]

No. Historically they don't use a libc at all if you don't use the DNS
subsystem. The latest version (1.11) finally started using libSystem on OSX
(where performing raw syscalls has never ever been supported, and Go broke
several time because they refused to acknowledge that).

~~~
valarauca1
My Go v1.11 compiler still emits symbols from `musl-libc` for static builds on
linux. I had to dig through on object dump just on friday.

~~~
TheDong
Are you running on a linux distro which uses musl, such as alpine?

Are you running the build inside a docker container which uses musl, such as
alpine?

Those are the cases where this might happen.

On a normal linux distro, this will not happen.

