如何将 Go 程序打包成自包含的形式?

huangapple go评论93阅读模式
英文:

How do I package a Go program so that it is self sufficient?

问题

我有一个Go程序,我想在交换机上运行它。由于无法在交换机本身上安装Go,我只是复制可执行文件并尝试运行。但是我遇到了以下错误。

runtime: panic before malloc heap initialized
fatal error: runtime: cannot reserve arena virtual address space

runtime stack:
runtime.throw(0x8149b8b)
        /usr/local/go/src/pkg/runtime/panic.c:520 +0x71
runtime.mallocinit()
        /usr/local/go/src/pkg/runtime/malloc.goc:552 +0xf2
runtime.schedinit()
        /usr/local/go/src/pkg/runtime/proc.c:150 +0x3a
_rt0_go()
        /usr/local/go/src/pkg/runtime/asm_386.s:95 +0xf6`

我该如何将Go可执行文件与其所有依赖项打包在一起?

编辑1: 这是ulimit -a的输出。

core file size          (blocks, -c) unlimited
data seg size           (kbytes, -d) unlimited
scheduling priority             (-e) 0
file size               (blocks, -f) unlimited
pending signals                 (-i) 40960
max locked memory       (kbytes, -l) 32
max memory size         (kbytes, -m) unlimited
open files                      (-n) 1024
pipe size            (512 bytes, -p) 8
POSIX message queues     (bytes, -q) 819200
real-time priority              (-r) 0
stack size              (kbytes, -s) 8192
cpu time               (seconds, -t) unlimited
max user processes              (-u) 1024
virtual memory          (kbytes, -v) 395067
file locks                      (-x) unlimited
英文:

I have a Go Program and I want to run it on a switch. Since I cannot install Go on the switch itself, I just copy the executable and try to run. But I get the following error.

runtime: panic before malloc heap initialized
fatal error: runtime: cannot reserve arena virtual address space

runtime stack:
runtime.throw(0x8149b8b)
        /usr/local/go/src/pkg/runtime/panic.c:520 +0x71
runtime.mallocinit()
        /usr/local/go/src/pkg/runtime/malloc.goc:552 +0xf2
runtime.schedinit()
        /usr/local/go/src/pkg/runtime/proc.c:150 +0x3a
_rt0_go()
        /usr/local/go/src/pkg/runtime/asm_386.s:95 +0xf6`

How do I package the Go executable with all it's dependencies?

EDIT 1: Here is the ulimit -a dump.

core file size          (blocks, -c) unlimited
data seg size           (kbytes, -d) unlimited
scheduling priority             (-e) 0
file size               (blocks, -f) unlimited
pending signals                 (-i) 40960
max locked memory       (kbytes, -l) 32
max memory size         (kbytes, -m) unlimited
open files                      (-n) 1024
pipe size            (512 bytes, -p) 8
POSIX message queues     (bytes, -q) 819200
real-time priority              (-r) 0
stack size              (kbytes, -s) 8192
cpu time               (seconds, -t) unlimited
max user processes              (-u) 1024
virtual memory          (kbytes, -v) 395067
file locks                      (-x) unlimited

答案1

得分: 22

TL;DR

您的Go应用程序无法分配虚拟内存来运行。我以前从未为Switch开发过,但如果它运行的是Linux或Unix变体,请检查组/用户权限和ulimit值,以查看该用户是否有任何限制。也许这个问题可能会有所帮助。

更详细的版本

所以,您在这里的问题不是Go无法在没有Go开发环境的情况下运行,因为您实际上并不需要它。Go以生成静态二进制文件而闻名,根据定义,这些文件是自包含的,不依赖于其他库来运行。

如果您仔细查看错误消息,您会注意到它说:

"无法保留竞技场虚拟地址空间"

您可能会问自己"这个竞技场是什么?"

快速查看malloc的源代码给了我们一个提示:

> 设置分配竞技场,一个连续的内存区域,其中分配的数据将被找到。竞技场以足够大的位图开始,以容纳每个分配字的4位。

如果您查看该源代码,您会在这里附近找到您的错误消息。

runtime·SysReserve C函数实际上是尝试为竞技场保留虚拟地址空间的函数。如果无法分配,它将抛出该错误。

您可以在此处找到其Linux实现的代码。

由于Go通常会尝试避免大型分配,因为它们可能会立即失败,如果您的用户无法分配64K这么小的东西,这意味着您的用户有严格的限制。由于我不知道您的Switch运行的是哪个操作系统,并且没有为其开发经验,所以我无法进一步处理。

如果您可以提供更多信息,我可以尝试相应地更新这个答案。

英文:

TL;DR

Your Go app is not being able to allocate virtual memory to run. I've never developed for a switch before but if it's running linux or a unix variant, check group/user permissions and ulimit values to check if that user has any kind of restriction. Maybe this question might be of help

Longer version

So, your problem here is not go not being able to run without the go development environment because you really don't need it. Go is known for generating static binaries that by definition are self contained and don't depend on other libraries to run.

If you take a better look at your error message, you'll notice that it says:

"cannot reserve arena virtual address space"

You might be asking yourself "what is this arena?"

I quick look at malloc's source code gives us a hint:

> Set up the allocation arena, a contiguous area of memory where
> allocated data will be found. The arena begins with a bitmap large
> enough to hold 4 bits per allocated word.

If you go through that source code you'll find your error message around here.

The runtime·SysReserve C function is the one that actually tries to reserve the virtual address space for the arena. If it can't allocate that, it will throw that error.

You can find code for the Linux implementation of it here.

As go normally tries to avoid big allocations as the might fail right away, if your user can't allocate something as small as 64K, it means your user has tight restrictions. As I have no idea which OS your switch is running and have no experience developing for them I can't go any further than this.

If you can provide more information, I can try to update this answer accordingly.

huangapple
  • 本文由 发表于 2014年12月9日 12:40:50
  • 转载请务必保留本文链接:https://go.coder-hub.com/27371545.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定