LoginSignup
1
0

More than 3 years have passed since last update.

MKL taints symbol table (PLT / procedure linkage table)

Last updated at Posted at 2020-10-26

はじめに

https://qiita.com/cielavenir/items/93d2b5b057bfe1383670 の関連。

A.soとB.soがあって、Aはlibmkl_rt、Bはlibblasに静的リンクしているとする。このとき、本来であれば、A.soおよびB.soを動的リンクするなら1、Aはlibmkl_rt、 BはlibblasをBLAS実装に使うはず。
ところが、実際には、AがMKLのBLAS関数を呼んだ後にBをロードすると、BもMKLをBLAS実装に使うようになってしまう。もし(そうそうないことだが)BがMKL以外のBLAS実装の挙動に依存する2なら、これは問題となりうる。が、今回は回避策はなさそうに思える…。

デモ

scipy/spatial/qhull.soのバイナリパッケージはlibopenblasにリンクしているが、LD_DEBUG="libs symbols" 環境で以下を実行すると、(libopenblasでなく)MKLのdgetrf/dgetrs/dgeconがロードされることが観測される。import scipyではscipy/spatial/qhull.soのロードに至らないことに注意。

#!/usr/bin/python
import numpy
import scipy  # this does not guarantee scipy.spatial safety.
print(numpy.dot([[1,2]],[[3],[4]]))
points = numpy.random.rand(30, 2)  # 30 random points in 2-D

import ctypes
n=ctypes.c_int(3)
alpha=ctypes.c_double(3)
beta=ctypes.c_double(-2)
A=(ctypes.c_double*9)(1,2,9,8,10,-5,3,8,-1)
B=(ctypes.c_double*9)(9,3,-8,8,11,6,3,2.3,1)
C=(ctypes.c_double*9)(3,8,6,3,4,1,1.2,8,-2)
# this CDLL loads so using RTLD_LOCAL
ctypes.CDLL("libmkl_rt.so").cblas_dgemm(102,111,111,n,n,n,alpha,A,n,B,n,beta,C,n)
print(list(C))

print '=== check dgetrf/dgetrs/dgecon below ==='
from scipy.spatial import ConvexHull
hull = ConvexHull(points)

おわりに

思うところがあって、先のデモでも複数個のモジュールを使うパターンを追加したところ、再現できた(あちらは(constructor attributeを使っているので)関数を呼ばずともロードしただけで再現する)。挙動を観測するに、libmkl_rtはあのdlopenし直すやつをやっているだけではないだろうか…?

新しいglibcの対策(および別解)

angel様いわく、.aを使った上で-pie -rdynamicを指定することで回避可能とのこと。

が、このようにして生成したライブラリはglibc 2.30以降では標準ではロードできないmkexeloadableをバイナリに対して用いることでロード可能になる。

ところで、このプログラムで操作しているのはELFタグ6ffffffbであるが、これを検索するとLLVMで-Bsymbolicをサポートしようとするパッチが見つかる。つまり、-Wl,-Bsymbolicを指定すれば良い。ただし、これも.aを使う必要がある。さらに、-sharedを使う以上は.aが-fPICでコンパイルされている必要がある。

以上のことは https://github.com/cielavenir/angel_pietest には反映している。

さて、Debian busterは、/usr/lib/x86_64-linux/gnu/blas/libblas.aが-fPICでコンパイルされているが、bullseyeはそうでない。3.8.0-5以降のパッケージは-fPICでなくなった旨の更新履歴がある。lapackのソースパッケージをコンパイルし、lapack-3.9.0/pic32/libcblas_pic.a lapack-3.9.0/pic32/librefblas_pic.a lapack-3.9.0/pic32/libcblas_pic.a3にリンクすればよいが、実用的ではない。

…普通にmkexeloadable使ったほうが良さそうです^^;;;でもこれのおかげで6ffffffbというキーワードがわかったので感謝。


  1. RTLD_LOCAL 

  2. openrave(またですね)4 

  3. libcblas_pic.aを2回指定していますがリンクの都合です、誤植ではありません 

  4. MKLを最初から使う分には大丈夫、キャッシュが生成された後の切り替えがこわい 

1
0
3

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
1
0