2017-08-11 21 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二進制文件的用戶修復它們。這很可能解決這個問題。 –