uchan note

プログラミングや電子工作の話題を書きます

ccコマンドが無いとIntel Pinが実行できない

新規にインストールした Ubuntu 20.04 上で Intel Pin 3.13 (March 25, 2020) が上手く動かなかったので原因究明したメモです。 make と g++ パッケージのみを導入した状態では /usr/bin/cc が存在せず,それが原因で Intel Pin ツールのビルドが上手くいっていない問題に遭遇しました。

問題の説明

サンプルプログラムをビルドします。

$ cd pin-3.13-98189-g60a6ef199-gcc-linux/source/tools/ManualExamples
$ make obj-intel64/inscount0.so
mkdir -p obj-intel64/
g++ -Wall -Werror -Wno-unknown-pragmas -D__PIN__=1 -DPIN_CRT=1 -DTARGET_IA32E -DHOST_IA32E -fPIC -DTARGET_LINUX -fabi-version=2 -faligned-new  -I../../../source/include/pin -I../../../source/include/pin/gen -isystem /home/uchan/workspace/pin-3.13-98189-g60a6ef199-gcc-linux/extras/stlport/include -isystem /home/uchan/workspace/pin-3.13-98189-g60a6ef199-gcc-linux/extras/libstdc++/include -isystem /home/uchan/workspace/pin-3.13-98189-g60a6ef199-gcc-linux/extras/crt/include -isystem /home/uchan/workspace/pin-3.13-98189-g60a6ef199-gcc-linux/extras/crt/include/arch-x86_64 -isystem /home/uchan/workspace/pin-3.13-98189-g60a6ef199-gcc-linux/extras/crt/include/kernel/uapi -isystem /home/uchan/workspace/pin-3.13-98189-g60a6ef199-gcc-linux/extras/crt/include/kernel/uapi/asm-x86 -I../../../extras/components/include -I../../../extras/xed-intel64/include/xed -I../../../source/tools/Utils -I../../../source/tools/InstLib -O3 -fomit-frame-pointer -fno-strict-aliasing   -c -o obj-intel64/inscount0.o inscount0.cpp
g++ -shared ../../../intel64/runtime/pincrt/crtbeginS.o -Wl,-Bsymbolic -Wl,--version-script=../../../source/include/pin/pintool.ver -fabi-version=2    -o obj-intel64/inscount0.so obj-intel64/inscount0.o  -L../../../intel64/runtime/pincrt -L../../../intel64/lib -L../../../intel64/lib-ext -L../../../extras/xed-intel64/lib -lpin -lxed ../../../intel64/runtime/pincrt/crtendS.o -lpin3dwarf  -ldl-dynamic -nostdlib -lstlport-dynamic -lm-dynamic -lc-dynamic -lunwind-dynamic

ビルドしたサンプルプログラムを使って,/bin/echo の命令数を数えます。

$ ../../../pin -t obj-intel64/inscount0.so -- /bin/echo
E: Unable to load /home/uchan/workspace/pin-3.13-98189-g60a6ef199-gcc-linux/source/tools/ManualExamples/obj-intel64/inscount0.so: dlopen failed: empty/missing DT_HASH in "/home/uchan/workspace/pin-3.13-98189-g60a6ef199-gcc-linux/source/tools/ManualExamples/obj-intel64/inscount0.so" (built with --hash-style=gnu?)

エラーメッセージが出ず,静かにツールが終了するのが期待結果です。しかし現実は上記のようにエラーメッセージが出ます。

原因と解決策

原因究明した結果,cc コマンドが無い( which cc しても何も表示されない )のが原因でした。

今回,私は update-alternatives で cc を設定しました。gcc パッケージを導入する,などでも解決可能かもしれません。とにかく cc コマンドが機能する状態になれば OK だと思います。

$ sudo update-alternatives --install /usr/bin/cc cc /usr/bin/gcc 10

この後 make -B obj-intel64/inscount0.so し直すと正常にビルド可能です。 make の -B オプションは必要なファイルをすべてビルドしなおすためのものです。これを付けないと「何もビルドする必要がないよ」と make に言われてしまいます。

真の原因

Intel Pin は,ツールをビルドする際に使うコンパイラオプションを決めるために source/tools/Config/makefile.unix.config の中で次のようなロジックを使っています。

CCPATH ?= $(shell which $(CC) 2> /dev/null)
CXXPATH ?= $(shell which $(CXX) 2> /dev/null)
export CCPATH
export CXXPATH

# This allows us to acquire information about the compiler
ifneq ($(CCPATH),)
    HELPOUT := $(shell $(CC) -v --help 2>&1)
endif

…

ifneq ($(findstring -fno-rtti,$(HELPOUT))$(findstring -frtti,$(HELPOUT)),)
    TOOL_CXXFLAGS_NOOPT += -fno-rtti
endif

…

環境変数 CC に設定されたコンパイラ-v --help というオプションを渡し,その出力を HELPOUT 変数に保持します。 HELPOUT の中に -fno-rtti または -frtti があれば,Pin ツールをビルドする際のコンパイラオプション(TOOL_CXXFLAGS_NOOPT)に -fno-rtti を追加します。

cc コマンドがない場合に HELPOUT が正常に取得できないため,本来追加されるべきオプション群が追加されない,というのが真の原因でした。 cc コマンドを作ってから make -B obj-intel64/inscount0.so し直すと,次のように -fno-rtti 等のオプションが付与されることが分かります。

g++ -Wall -Werror -Wno-unknown-pragmas -D__PIN__=1 -DPIN_CRT=1 -fno-stack-protector -fno-exceptions -funwind-tables -fasynchronous-unwind-tables -fno-rtti -DTARGET_IA32E …