自R2012b(8.0)以来,已知的MATLAB的bug并非961964。MATLAB动态加载带有静态TLS(线程本地存储,例如,参见gcc编译器标志-ftls-model)的某些库。加载太多这样的库=>没有空间了。
到目前为止,数学工作的唯一解决方法是先及早使用重要的(!)库(建议将“ ones(10)* ones(10);”放在startup.m中)。我最好不要对此“解决方案策略”发表评论。
从R2013b(8.2.0.701)和Linux x86_64开始,我的经验是:不要使用“ doc”(图形帮助系统)!我认为此doc-utility(libxul等)正在使用大量静态TLS内存。
这是更新(2013/12/31)
以下所有测试均使用Fedora 20(带有glibc-2.18-11.fc20)和Matlab 8.3.0.73043(R2014a预发行版)进行。
有关TLS的详细信息,请参阅Ulrich Drepper,《 ELF处理线程本地存储》,版本0.21,2013,当前可在Akkadia和Redhat上获得。
到底会发生什么?
MATLAB动态(使用dlopen)加载了一些需要tls初始化的库。所有这些库都需要在dtv(动态线程向量)中添加一个插槽。由于MATLAB在编译/链接时会在运行时动态加载其中一些库,因此链接器(在MathWorks上)没有机会计算所需的插槽(这是重要的部分)。现在,动态库加载器的任务是在运行时处理这种情况。但这并不容易。引用dl-open.c:
对于静态TLS,我们必须在此处和现在分配内存。这包括在DTV中分配内存。但是我们不能改变自己以外的任何数字电视。因此,如果我们不能保证DTV中有空间,我们甚至不会尝试并导致负载失败。
glibc的动态lib加载程序中有一个编译时间常数(称为DTV_SURPLUS,请参见glibc-source / sysdeps / generic / ldsodefs.h),用于为此类混乱情况保留许多其他插槽(在多线程中动态加载具有静态TLS的libs)程序)。在Fedora 20的glibc版本中,该值为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随附的二进制文件的任何部分。我只调试了MATLAB用于动态加载库的Fedora 20的免费开放glibc二进制文件。
有什么办法可以解决这个问题?
有3个选项:
(a)重建MATLAB,不要动态加载这些库(使用initial-exec tls模型),而是链接到它们(然后,链接器可以计算所需的插槽!)
(b)重建这些库,并确保它们未使用initial-exec tls模型。
(c)重建glibc并在glibc / sysdeps / generic / ldsodefs.h中增加DTV_SURPLUS
显然,选项(a)和(b)只能由mathworks完成。
对于选项(c),不需要MATLAB源,因此无需mathworks就可以完成。
mathworks的状态如何?
我确实试图向“ MathWorks技术支持部门”进行解释。但是我的印象是:他们不了解我。他们关闭了我的支持票,并建议在2014年1月与技术支持经理进行电话交谈。
我会尽力解释这一点,但是老实说:我不是很自信。
更新(2014/01/10):当前mathworks正在尝试选项(b)。
更新(2014/03/19):对于文件libiomp5.so,您可以在mathworks上下载新编译的版本(无静态TLS),错误报告961964。还有其他的库?那里没有改善。因此,不要惊讶地使用“ doc”获取“ dlopen:无法使用静态TLS加载更多对象”,例如,参见错误报告1003952。