2017-08-11 155 views
1

试图运行吞和收到这个输出咕嘟咕嘟/节点:错误而载入共享库:不能在静态TLS分配内存块

$ gulp 
node: error while loading shared libraries: cannot allocate memory in static TLS block 

从我已经发现,这似乎涉及的gcc或g ++,不知道它如何与节点或吞咽有关。无论哪种方式,我似乎无法运行吞咽了。还应该提到,今天刚刚出现。昨天运行良好。

编辑:似乎它是所有节点命令。试着运行npm -v来获取版本号,它具有相同的输出。同样与节点-v

运行的CentOS 6.9

回答

1

GNU工具支持各种TLS的,并且将它们中的一个(initial-exec模型)涉及什么实质上是从线程控制块的固定偏移。在程序启动时,动态链接器会计算所有偏移量,并确保所有线程都有足够的空间用于所有需要的线程局部变量。

但是,对于dlopen,这通常不起作用,因为无法移动线程控制块以为更多线程局部变量腾出空间。当前的glibc动态链接器有一个启发式方法,它为将来的调用保留了一些空间,但是如果你加载了一些共享对象,每个都会使自己的线程局部变量枯萎,这还不够。

通常的解决方法是使用LD_DEBUG=files环境变量(或strace)找到装有dlopen(不幸的是,该错误你报不提供此信息的消息)相关的共享对象。之后,您可以使用LD_PRELOAD环境变量来告诉动态链接器尽早加载它们。 (对于共享对象执行此操作就足够了,因为它的相关性会自动处理。)这会产生副作用,即程序启动时的计算考虑到它们的TLS需求,并且在调用后发生调用时时间,不需要分配额外的TLS变量。但是,这种方法不适用于所有共享对象,因为它影响符号查找以及ELF构造函数的运行顺序。

在一般情况下,可能需要将某些共享对象切换到global-dynamic TLS模型(需要重新编译它们),或者使用glibc构建以增加TLS保留。不幸的是,保留区目前不能在运行时设置。

+0

感谢您的回答,但它有点复杂。我只是想跑一口气。作为最终用户,我应该在这里做什么? –

+0

作为纯粹的最终用户,您应该向那些向您提供node.js二进制文件的用户修复它们。这很可能解决这个问题。 –