MatLab 错误: 无法用静态 TLS 打开

自从几天以来,我不断收到同样的错误,而使用 MATLAB,这发生在某些时候与 dlopen。我对 MATLAB 很陌生,这就是为什么我不知道该怎么做。谷歌似乎也帮不了我。当我试图构造一个特征向量时,我得到了这个:

Error using eig
LAPACK loading error:
dlopen: cannot load any more object with static TLS

我在做乘法运算的时候也得到了这个结论:

Error using  *
BLAS loading error:
dlopen: cannot load any more object with static TLS

当然,我的确在寻找解决这个问题的办法,但我不太明白,也不知道该怎么办。这些是我找到的线索:

  1. 如何使用 MATLAB 提供的 BLAS 库
  2. Http://www.mathworks.de/de/help/matlab/matlab_external/calling-lapack-and-blas-functions-from-mex-files.html

有人能帮帮我吗?

演示此错误的函数调用示例

>> randn(3,3)


ans =


2.7694    0.7254   -0.2050
-1.3499   -0.0631   -0.1241
3.0349    0.7147    1.4897


>> eig(ans)


Error using eig
LAPACK loading error:
dlopen: cannot load any more object with static TLS
66994 次浏览

我也有同样的问题,我想我刚刚解决了。

在安装 matlab 时使用自定义安装(我第一次没有这样做)。选择在预定义文件夹(/usr/local/bin)中创建指向 matlab 脚本的符号链接。这招对我很管用!

这是从 R2012b (8.0)开始就知道的 MATLAB 的 编号961964。MATLAB 用静态 TLS (线程本地存储,例如参见 gcc 编译器标志 -ftls-model)动态加载一些库。加载太多这样的 lib = > 没有空间了。

到目前为止,数学工作的唯一解决办法是加载重要的(!)Libs 首先要尽早使用它们(他们建议在 startup.m 中放入“ ones (10) * ones (10) ;”)。我最好不要评论这个“解决方案策略”。

从 R2013b (8.2.0.701)和 Linux x86 _ 64开始,我的经验是: 不要使用“ doc”(图形帮助系统) !我认为这个文档实用程序(libxul 等)使用了大量的静态 TLS 内存。

以下是2013年12月31日的最新情况

以下所有测试均使用 Fedora 20(使用 glibc-2.18-11. fc20)和 Matlab 8.3.0.73043(R2014a Prerelease)完成。

有关 TLS 的更多信息,请参见 本地存储的 ELF 处理,版本0.21,2013, 目前在 阿卡迪亚红帽子有售。

到底发生了什么?

MATLAB 动态(使用 dlopen)加载几个需要 tls 初始化的库。所有这些库都需要在 dtv (动态线程向量)中有一个插槽。因为 MATLAB 在编译/链接时在运行时动态加载其中几个库,链接器(在 mathworks)没有机会计算所需的槽(这是重要的部分)。现在,动态库加载器的任务是在运行时处理这种情况。但这并不容易。引用 dl-open。丙:

对于静态 TLS,我们必须在这里分配内存 这包括在数字电视中分配内存。但是我们 除了我们自己的数字电视外,我们不能改变任何其他数字电视。所以,如果我们 我们不能保证数字电视有空间 甚至尝试它和失败的负载。

在 glibc 的动态库加载器中有一个编译时间常数(称为 DTV _ SUPLUS,参见 glibc-source/sysdeps/general/ldsodefs.h) ,用于为这种混乱保留一些额外的插槽(在多线程程序中用静态 TLS 动态加载库)。在 Fedora 20的 glibc-Version 中,这个值是14。

以下是在我的例子中第一个需要 dtv 插槽的库(运行 MATLAB) :

matlabroot/bin/glnxa64/libut.so
/lib64/libstdc++.so.6
/lib64/libpthread.so.0
matlabroot/bin/glnxa64/libunwind.so.8
/lib64/libuuid.so.1
matlabroot/sys/java/jre/glnxa64/jre/lib/amd64/server/libjvm.so
matlabroot/sys/java/jre/glnxa64/jre/lib/amd64/libfontmanager.so
matlabroot/sys/java/jre/glnxa64/jre/lib/amd64/libt2k.so
matlabroot/bin/glnxa64/mkl.so
matlabroot/sys/os/glnxa64/libiomp5.so
/lib64/libasound.so.2
matlabroot/sys/jxbrowser/glnxa64/xulrunner/xulrunner-linux-64/libxul.so
/lib64/libselinux.so.1
/lib64/libpixman-1.so.0
/lib64/libEGL.so.1
/lib64/libGL.so.1
/lib64/libglapi.so.0

是的,超过14 = > 太多 = > dtv 中没有剩余的插槽。这就是错误消息试图告诉我们的,特别是 mathworks。

记录: 为了不违反 MATLAB 的许可证,我没有调试,反编译或反汇编任何部分的二进制文件运行 MATLAB。我只调试了 Fedora 20的免费和开放的 glibc-二进制文件,MATLAB 使用它们来动态加载库。

要解决这个问题,我们能做些什么呢

有三种选择:

重新构建 MATLAB,不要动态加载这些库 (使用 first-exec tls 模型)而不是链接到它们(然后链接器 可以计算所需的插槽!)

重新构建这些库,并确保它们不使用 first-exec tls 模型。

重建 glibc 增加 DTV _ SurPLUS Glibc/sysdeps/general/ldsodefs.h

显然,选项(a)和选项(b)只能通过数学工具来实现。

对于选项(c) ,不需要 MATLAB 源代码,因此可以在没有数学工具的情况下完成。

Mathworks 的情况如何?

我真的试图向“数学工程技术支持部门”解释这一点。但我的印象是: 他们不理解我。他们关闭了我的支持票,并建议用电话(!)2014年1月与一名技术支持经理的对话。

我会尽力解释清楚,但说实话: 我不是很有信心。

更新(2014/01/10) : 目前 Mathworks 正在尝试(b)选项。

更新(2014/03/19) : 对于 libiop5.so 你可以在 mathworks 下载一个新编译的版本(没有静态 TLS) ,漏洞报告961964。其他的呢?没有改善。因此,不要惊讶地得到“ dlopen: can not load any more object with static TLS”with“ doc”,例如,请参阅 漏洞报告1003952

我遇到了同样的问题,并通过增加 Java 堆内存来解决它。转到 Preferences > General > Java-Heap Memory,并增加分配的内存。

重启 Matlab 为我解决了这个问题。

Http://www.mathworks.de/support/bugreports/961964 已于2014年1月30日更新。 有一个附带 libiop5.so 的 zip 文件 我用 Matlab R2013b 在 Mageia 4 x86 _ 64上测试过。 我现在可以使用 Matlab 文档打开一个演示没有任何问题。

Matlab 2013b 和 Matlab 2014a 都有同样的问题。Mathworks 为 libiop5.so 提供的修复程序只是解决了 LAPACK 无法工作的问题。然而,我不能使用正在使用 OpenMP 的外部库(例如 VL _ FEAT) : 我仍然得到错误 “ dlopen: 不能用静态 TLS 加载任何对象。”

唯一对我有用的就是降级到 Matlab 2012b。

我遇到这个问题后,“酒吧”(为酒吧图)与一个数组给我只有一个蓝色块,没有抛出错误。重新启动首先解决了这个问题。但是在出现内存错误(在处理一个非常大的文件之后)之后,我就是无法解决这个蓝色块问题。

在矩阵输入中使用“ hist”给我带来了“ BLAS 加载错误”的问题,并将我引向了这个线程。Mathwork 解决方案修复了历史和酒吧的问题。

只是想让大家认识到这种病毒的影响力。

在 R2013b/Ubuntu 12.04上,增加 Java 堆内存(至512mb)对我也有效。“ BLAS 加载错误”开始于我处理11GB 文件(16GB RAM)时,并且在增加 Java 堆内存和重新启动 matlab 后没有再次发生。

长话短说: 在你启动 matlab 的目录中创建一个文件 带有内容 ones(10)*ones(10);的 startup.m。重新启动 matlab,它将得到处理。

正如我所发现的,这是一个数学工作室尚未解决的古老问题。

这里是我的两分钱,这对我来说很有用(当我想要 IT + + 外部库,与 MEX)。


让您发现的导致问题的库成为“ libXYZ.so”,并且您知道它在系统中的位置。

解决方案是在 MATLAB 启动时尽早通知它加载特定的库。这个错误的原因显然是由于缺少这个 thread local storage又名 tls的目的插槽(由于他们已经被填满)。

由于最新的编译突然需要一个新的库,而这个库在启动之前没有加载,MATLAB 就抛出了这个错误。

遗憾的是,MATLAB 从来没有关心解决这个问题这么长时间。

幸运的是,解决方案是一个非常简单的终端命令。


Linux 机器上的典型步骤应该如下:

  1. 打开命令提示符(Ubuntu 中的 Ctrl+Alt+T)
  2. 发出以下命令

    导出 LD _ PRELOAD = < path-to-libxyz.so

例如: export LD_PRELOAD=/usr/local/lib/libitpp.so

  1. 从同一个终端启动 Matlab

    Matlab & amp

现在运行您的程序应该可以解决这个问题,就像我的情况一样。

祝你好运!


参考文献:

[1] http://au.mathworks.com/matlabcentral/answers/125117-openmp-mex-files-static-tls-problem