如何诊断为啥在 MATLAB 中执行 .mex 文件时无法加载 .so 文件?

Posted

技术标签:

【中文标题】如何诊断为啥在 MATLAB 中执行 .mex 文件时无法加载 .so 文件?【英文标题】:How do I diagnose why a .so file won't load when executing a .mex file in MATLAB?如何诊断为什么在 MATLAB 中执行 .mex 文件时无法加载 .so 文件? 【发布时间】:2010-07-29 18:59:49 【问题描述】:

我正在尝试将名为 VideoIO 的视频库与 MATLAB 一起用于机器学习项目。当我尝试在 MATLAB 中调用该库时,我收到一条错误消息,指出它找不到 libavutil.so.50,这是 VideoIO 所依赖的 ffmpeg 库之一。我检查了一些不同的东西,但除了它没有运行之外,找不到任何看起来错误的东西。谁能建议其他检查以帮助我调试?

这是错误:

error while loading shared libraries: libavutil.so.50: cannot open shared object file: No such file or directory 
??? Error using ==> videoReader_ffmpegPopen2 EOF found while trying to read the communication tag.
The server process probably died.
String so far: "" Function: int VideoIO::readMessageHeader(FILE*)
File : pipecomm.h Line : 306
Error in ==> videoReader.videoReader at 152 vr.handle = feval(vr.plugin, 'open',vr.handle, ...

试图找出问题所在,我发现vr 分配在哪里:

 vr = struct('plugin',pvtVideoIO_mexName(mfilename, plugin), ... 'handle',int32(-1));

我打印出mfilename,然后在它指向的文件上运行ldd

$ ldd videoReader_ffmpegPopen2Server
linux-vdso.so.1 => (0x00007fff41dff000)
libavutil.so.50 => /u/goodfeli/ffmpeg/libavutil/libavutil.so.50 (0x00007fd5f2895000)
libavdevice.so.52 => /u/goodfeli/ffmpeg/libavdevice/libavdevice.so.52 (0x00007fd5f268c000)
libavformat.so.52 => /u/goodfeli/ffmpeg/libavformat/libavformat.so.52 (0x00007fd5f23bf000)
libavcodec.so.52 => /u/goodfeli/ffmpeg/libavcodec/libavcodec.so.52 (0x00007fd5f1792000)
libavfilter.so.1 => /u/goodfeli/ffmpeg/libavfilter/libavfilter.so.1 (0x00007fd5f1584000)
libswscale.so.0 => /u/goodfeli/ffmpeg/libswscale/libswscale.so.0 (0x00007fd5f1351000)
libstdc++.so.6 => /usr/lib64/libstdc++.so.6 (0x000000378ea00000)
libm.so.6 => /lib64/libm.so.6 (0x0000003788a00000)
libgcc_s.so.1 => /lib64/libgcc_s.so.1 (0x000000378c600000)
libc.so.6 => /lib64/libc.so.6 (0x0000003788600000)
libpthread.so.0 => /lib64/libpthread.so.0 (0x0000003789200000)
libasound.so.2 => /lib64/libasound.so.2 (0x000000379a200000)
libbz2.so.1 => /lib64/libbz2.so.1 (0x0000003b0b400000)
libz.so.1 => /lib64/libz.so.1 (0x0000003789600000)
/lib64/ld-linux-x86-64.so.2 (0x0000003787400000)
libdl.so.2 => /lib64/libdl.so.2 (0x0000003788e00000)
librt.so.1 => /lib64/librt.so.1 (0x000000378b200000)

现在,通过复制粘贴 libavutil 的路径,我验证它是否正确:

$ ls /u/goodfeli/ffmpeg/libavutil/libavutil.so.50
/u/goodfeli/ffmpeg/libavutil/libavutil.so.50

所以该文件存在。现在在 MATLAB 中,我检查了 MATLAB 的 LD_LIBRARY_PATH 变量:

 >> getenv('LD_LIBRARY_PATH')
ans = /soft/diro/share/matlabr2009b/sys/os/glnxa64:/soft/diro/share/matlabr2009b/bin/glnxa64:/soft/diro/share/matlabr2009b/extern/lib/glnxa64:/soft/diro/share/matlabr2009b/runtime/glnxa64:/soft/diro/share/matlabr2009b/sys/java/jre/glnxa64/jre/lib/amd64/native_threads:/soft/diro/share/matlabr2009b/sys/java/jre/glnxa64/jre/lib/amd64/server:/soft/diro/share/matlabr2009b/sys/java/jre/glnxa64/jre/lib/amd64:/u/goodfeli/ffmpeg/libavfilter:/u/goodfeli/ffmpeg/libswscale:/u/goodfeli/ffmpeg/libavdevice:/u/goodfeli/ffmpeg/libavformat:/u/goodfeli/ffmpeg/libavcodec:/u/goodfeli/ffmpeg/libavutil:/opt/lisa/os/cuda/lib64:/opt/lisa/os/cuda/lib:/opt/lisa/byhost/lib:/opt/lisa/os/lib/vtk:/opt/lisa/os/lib/intelmkl/lib/32:/opt/lisa/os/lib:/opt/lisa/os/lib64:/usr/local/lib:/usr/lib64/atlas/::/opt/lisa/os/panda/lib:/opt/lisa/os/lib32:/opt/lisa/byhost/lib32

这似乎是正确的,它包括/u/goodfeli/ffmpeg/libavutil/,通过复制粘贴我可以验证没有错字:

 $ ls /u/goodfeli/ffmpeg/libavutil/ | grep "\.so"

对接下来要检查的内容有什么建议吗?提前致谢。

【问题讨论】:

【参考方案1】:

在调用 Matlab 之前设置 export LD_DEBUG=libs 可能会提供线索。

【讨论】:

谢谢,原来在 makefile 中存在问题,它将完整的文件路径而不是子目录作为 rpath 的参数。我会投票给你,但我需要 15 声望才能投票。

以上是关于如何诊断为啥在 MATLAB 中执行 .mex 文件时无法加载 .so 文件?的主要内容,如果未能解决你的问题,请参考以下文章

为啥这段代码(在 Matlab 的 MEX 文件中使用 OpenMP)给出不同的结果?

为啥 MEX 代码比 matlab 代码慢得多?

Mex 文件执行中的错误,Matlab 窗口

mex 文件未在 MATLAB 7.5.0 (R2007b) 中执行

如何在从 Matlab 调用的 mex 函数中使用 Matlab 引擎

多线程 (pthreads) MATLAB mex 函数导致 MATLAB 在退出后崩溃