Armadilloフォーラム

Armdillo-410でvalgrind

tetsuya.ooka

2015年4月30日 19時00分

お世話になっております。ロームの大岡と申します。

自作アプリのメモリリークを調査するためにArmadillo-410でvalgrindを動かしたいのですがなかなかうまく行かずに困っています。少しでも助言を頂けないでしょうか。

環境は以下のものを使用しています。
ATDE: atde4-qt-amd64-20130131
atmark-dist: atmark-dist-qt-20121105
カーネル: linux-2.6.26-at18

まずvalgrind-3.6.0をクロスコンパイルしてArmadillo-410に配置して起動するところまで確認しました。

[root@armadillo440 (ttyp0) /]# valgrind --version
valgrind-3.6.0

ですが実際にメモリリークを調査しようすると以下のエラーが発生して動作しません。

[root@armadillo440 (ttyp0) /]# valgrind ./my_app
==6065== Memcheck, a memory error detector
==6065== Copyright (C) 2002-2010, and GNU GPL'd, by Julian Seward et al.
==6065== Using Valgrind-3.6.0 and LibVEX; rerun with -h for copyright info
==6065== Command: ./my_app
==6065==
 
valgrind:  Fatal error at startup: a function redirection
valgrind:  which is mandatory for this platform-tool combination
valgrind:  cannot be set up.  Details of the redirection are:
valgrind:
valgrind:  A must-be-redirected function
valgrind:  whose name matches the pattern:      memcpy
valgrind:  in an object with soname matching:   ld-linux.so.3
valgrind:  was not found whilst processing
valgrind:  symbols from the object with soname: ld-linux.so.3
valgrind:
valgrind:  Possible fixes: (1, short term): install glibc's debuginfo
valgrind:  package on this machine.  (2, longer term): ask the packagers
valgrind:  for your Linux distribution to please in future ship a non-
valgrind:  stripped ld.so (or whatever the dynamic linker .so is called)
valgrind:  that exports the above-named function using the standard
valgrind:  calling conventions for this platform.
valgrind:
valgrind:  Cannot continue -- exiting now.  Sorry.

エラーの内容からすると、glibcのデバッグ情報か、stripされていないglibcが必要なようです。
atde4-qt-amd64-20130131のデフォルトのglibcはlibc6-armel-crossパッケージに入っているらしいのはわかったのですが、デバッグ情報やstripされていないものはどこで手に入るのでしょうか?
debian lenny用のlibc6-dbg(armel)を使ってみたのですがうまく行きませんでした。

コメント

at_takashi.sasayama

2015年5月1日 20時35分

笹山です。

> atde4-qt-amd64-20130131のデフォルトのglibcはlibc6-armel-crossパッケージに入っているらしいのはわかったのですが、デバッグ情報やstripされていないものはどこで手に入るのでしょうか?

atde4-qt-amd64-20130131 には libc6-armel-cross 2.11.3-4 がインストールされています。
デバッグ情報が strip さていないものは、以下からダウンロードできます。

Download Page for libc6-dbg_2.11.3-4_armel.deb on EABI ARM machines
https://packages.debian.org/squeeze/armel/libc6-dbg/download

注意点としまして、atmark-dist では、ユーザーランドイメージサイズを小さくする為に、
soファイル等のデバッグ情報を strip しています。

デバッグ情報が付加された libc6 を使用する方法の一例としては、
以下の手順があります。

atmark-dist の make 完了後に以下の手順を行ってみてください。
[ATDE4]$ mkdir libc6-dbg-armel
[ATDE4]$ dpkg-deb -x libc6-dbg_2.11.3-4_armel.deb ./libc6-dbg-armel
[ATDE4]$ cp libc6-dbg-armel/usr/lib/debug/lib/* ~/atmark-dist/romfs/usr/lib
[ATDE4]$ cd ~/atmark-dist
[ATDE4]$ make image

上記手順で作成されたイメージで valgrind を実行すると正常に動作しないでしょうか?

tetsuya.ooka

2015年5月7日 13時57分

笹山様。ありがとうございます。

教えて頂いた方法を試してみましたが残念ながらうまくいきませんでした。
以下にいろいろ試した結果を書いています。何か他にいい方法はありませんでしょうか。

1. デバッグ情報入りのライブラリを/usr/lib以下に配置(教えて頂いた方法)
valgrindを実行するとやはり最初と同じエラーが発生して起動できませんでした。

2. デバッグ情報入りのライブラリを/lib以下に配置
valgrindは/usr/libではなくて/libを見ているのではないかと思い、/lib以下にデバッグ情報入りのライブラリを配置したイメージを作成しましたが、カーネルパニックを起こしてlinux自体が起動しませんでした。(起動ログを添付しています)

3. デバッグ情報入りのファイルを/usr/lib/debug以下に配置
libc6-dbg_2.11.3-4_armel.debのパッケージ情報を見るとファイルのインストール先は/usr/lib/debug以下になっているので、それに合わせてファイルを配置したイメージで、LD_LIBRARY_PATHに/usr/lib/debug/libと/usr/lib/debug/usr/libを追加してvalgrindを実行しましたが、1.と同じ結果になりました。

ちなみにlibc6-dbg_2.11.3-4_armel.deb内のバイナリファイル(ldconfigなど)をArmadillo上で実行するとsegmentation faultが発生したり起動できなかったりするのですが、ライブラリの依存関係か何かがおかしいのでしょうか?
linux起動後に/lib/ld-2.11.3.soをデバッグ情報入りのものに無理やり差し替えると、それ移行はすべての実行ファイルがsegmentation faultを起こしてしまい実行できなくなります。

以上です。よろしくお願いします。

ファイル ファイルの説明
起動ログ(lib以下にデバッグ情報).txt

at_takashi.sasayama

2015年5月11日 15時25分

笹山です。

> 1.デバッグ情報入りのライブラリを/usr/lib以下に配置(教えて頂いた方法)
> valgrindを実行するとやはり最初と同じエラーが発生して起動できませんでした。

こちらでも valgrind 3.6.0 で同様の現象が発生することを確認しました。
何故かデバッグ情報のCRC値が一致せずエラーとなっているようです。

[root@armadillo420-0 (ttymxc1) ~]# valgrind --verbose ls
 : 一部省略
--1336-- Valgrind library directory: /usr/lib/valgrind
--1336-- Reading syms from /bin/busybox (0x8000)
--1336--    object doesn't have a symbol table
--1336-- Reading syms from /lib/ld-2.11.3.so (0x4000000)
--1336--   Considering /lib/ld-2.11.3.so ..
--1336--   .. CRC mismatch (computed e610fdd3 wanted 000088e8)
--1336--   Considering /usr/lib/debug/lib/ld-2.11.3.so ..
--1336--   .. CRC mismatch (computed 785b88e8 wanted 000088e8) # CRC不一致(xxxx88e8 は一致?)
--1336--    object doesn't have a symbol table

エラーの原因は特定できていないのですが、
valgrind は armv7 以降のみをサポートしている為、
armv5 である Armadillo-400シリーズでは正常に動作しないようです。

> 2. デバッグ情報入りのライブラリを/lib以下に配置
> valgrindは/usr/libではなくて/libを見ているのではないかと思い、
> /lib以下にデバッグ情報入りのライブラリを配置したイメージを作成しましたが、
> カーネルパニックを起こしてlinux自体が起動しませんでした。(起動ログを添付しています)

大変失礼しました。
先の回答で、*-dbg パッケージは デバッグ情報が strip されていないものと記載していたのですが、これは誤りでした。
正しくは *-dbg パッケージは strip されたデバッグ情報のみですね。
libc6 + libc6-dbg で デバッグ情報が strip されていないもの相当になります。

その為、上記の手順でlibc6関連のライブラリを、libc6-dbg に置き換えると
カーネルパニックが発生します。

> 3. デバッグ情報入りのファイルを/usr/lib/debug以下に配置
> libc6-dbg_2.11.3-4_armel.debのパッケージ情報を見るとファイルのインストール先は/usr/lib/debug以下になっているので、
> それに合わせてファイルを配置したイメージで、LD_LIBRARY_PATHに/usr/lib/debug/libと/usr/lib/debug/usr/libを追加して
> valgrindを実行しましたが、1.と同じ結果になりました。

/usr/lib/debug 以下に *-dbg パッケージを配置すると、valgrind は自動で参照してくれます。
その為 valgrind では LD_LIBRARY_PATH の設定は不要です。

> 教えて頂いた方法を試してみましたが残念ながらうまくいきませんでした。
> 以下にいろいろ試した結果を書いています。何か他にいい方法はありませんでしょうか。

参考までに valgrind 以外でメモリリークをチェックできる mtrace の動作確認方法を以下に記載します。

■ mtrace 動作確認方法

valgrind と違いチェック対象のアプリに改造が必要ですが、
Armadillo-400シリーズで動作確認が行えています。

まずアプリケーションでリークチェックを行う範囲を mtrace(), muntrace() 関数で指定します。

サンプルコード: mtrace-test.c

#include <stdlib.h>
#include <mcheck.h> /* mtrace, muntrace用 */
 
int main(int argc, char* argv[]) {
        char* buf;
        mtrace(); /* チェック開始 */
        buf = (char*)malloc(10);
        muntrace(); /* チェック終了 */
        return 0;
}

アプリにデバッグ情報を付加してコンパイルします。

[ATDE4]$ arm-linux-gnueabi-gcc mtrace-test.c -o mtrace-test -g

armadillo 上で MALLOC_TRACE に mtrace の結果ログを格納するパスを指定し、 mtrace-test を実行します。

armadillo# MALLOC_TRACE=./log ./mtrace-test

log ファイルが作成されますので、ATDE4 上の mtrace コマンドでログを解析します。
解析結果から mtrace-test.c 6行目の malloc した領域が free されていないことがわかります。

atmark@atde4:~/mtrace$ mtrace mtrace-test log
 
Memory not freed:
-----------------
           Address     Size     Caller
0x0000000000011380      0xa  at /home/atmark/mtrace/mtrace-test.c:6

注意点としまして、C++ の new / delete によるメモリリークも mtrace でチェックができますが、
チェックでひっかかるアドレスが libstdc++.so になる関係上、
コード内の、どのインスタンスが delete されていないかまでは判別ができません。

tetsuya.ooka

2015年5月12日 10時26分

大岡です。笹山様ありがとうございます。

> エラーの原因は特定できていないのですが、
> valgrind は armv7 以降のみをサポートしている為、
> armv5 である Armadillo-400シリーズでは正常に動作しないようです。
そうだったんですか。サポート対象かどうかを先に調べるべきでした。すみません。

教えて頂いたmtraceを試してみようと思います。ありがとうございました。