タイトル/名前 | 更新者 | 更新日 |
---|---|---|
技術/Linux/uClibc/01, "make install_headers" 関連PATCH(uClibc-0.9.31) | msakamoto-sf | 2011-04-11 17:45:04 |
技術/vim/メモ3, ctags | msakamoto-sf | 2011-04-11 10:48:17 |
日記/2011/04/10/uClibcを動的リンク出来ない・・・。x86(32bit)。 | msakamoto-sf | 2011-04-10 20:07:37 |
日記/2011/04/09/就職活動ナウ。 | msakamoto-sf | 2011-04-09 10:33:26 |
技術/Linux/"make mrproper" の "mrproper" って何のこと? | msakamoto-sf | 2011-04-07 12:10:25 |
Python/WinDBG拡張機能その2:pykdを使ってみる | msakamoto-sf | 2011-04-04 22:43:44 |
Python/Boost.Pythonメモ | msakamoto-sf | 2011-04-04 12:31:39 |
日記/2011/04/02/"%"で囲まれた環境変数を展開する時のメモ(ExpandEnvironmentStrings) | msakamoto-sf | 2011-04-02 19:10:58 |
日記/2011/04/02/ロシア語はさすがに読めないなぁ・・・。 | msakamoto-sf | 2011-04-02 16:25:39 |
読書メモ/"Advanced Windows Debugging" | msakamoto-sf | 2011-04-02 16:21:32 |
uClibc-0.9.31をソースツリーの外でビルドしたとき、"include/bits", "include/sys" が "install_headers"ターゲットのmakeでコピーされない問題がある。
例:
$ tar jxf uClibc-0.9.31.tar.bz2 $ cd uClibc-0.9.31 $ make O=`pwd`/../build defconfig $ make O=`pwd`/../build all $ make O=`pwd`/../build PREFIX=`pwd`/../dev install_headers
この状態では
`pwd`/../dev/usr/(...)/include
以下に "bits", "sys" ディレクトリとその配下のヘッダーファイルがコピーされないため、uClibcのヘッダーファイルをincludeするアプリをコンパイルするときにエラーになる。
原因はソースツリーの "extra/scripts/install_headers.sh" にある。
O="..." オプションを使わない場合は、バイナリのビルド時にソースツリー内部の"include"以下に "bits", "sys" が適切にコピーされるため問題とならない。
O="..." オプションを使う場合は、"bits", "sys" はビルドディレクトリの "include" 以下にシンボリックリンクとして作成されるが、install_headers.sh はこのディレクトリを無視している。
下記patchはこの問題を解決する。Makefile.in内では "install_headers" ターゲットで
top_builddir=(ビルドディレクトリ) \ ./extra/scripts/install_headers.sh include (インストール先ディレクトリ)
の形でinstall_headers.sh を実行する。下記patchではtop_builddirのincludeもチェックし、もしソースツリーの外部にある場合はそちらもコピーするよう修正する。
参考
注意点:tagsファイルの位置とか開くファイルの位置とかが相対パスだとややこしくなってトラブルになりやすいので、いっそ全部フルパス指定した方が分かりやすい。
$ ctags -R ./src
よりは
$ ctags -R /home/foo/bar/src
→ tags ファイルの中のファイル名がフルパスになるので、vim側で混乱しないで済む。
:set tags=../tags
よりは
:set tags=/home/foo/bar/tags
→相対パスでtagsを読み込ませると、カレントバッファのファイルのパスに引きづられちゃう。フルパスでかっちり指定したほうがvim側で混乱しないで済む。
CentOS5.5, x86(32bit), VMware上でここ数日、ず~っとはまってるのが uClibc で動的リンクに失敗する問題。
ret1.c:
int main(void) { return 1; }
たったこれだけ。つまり、uClibcのローダとスタートアップルーチンしか使わない最小のプログラム。
が、どうにも動かない。デバッグ有効でLD_DEBUGもONにしたところ、こんな出力が:
$ LD_DEBUG=y ./ret1_dyn argc=1 argv=0xbfb37034 envp=0xbfb3703c ELF header=0x363000 First Dynamic section entry=0x36aeec Scanning DYNAMIC section Done scanning DYNAMIC section About to do library loader relocations Done relocating ldso; we can now use globals and make function calls! _dl_get_ready_to_run:317: Cool, ldso survived making function calls _dl_malloc:194: mmapping more memory _dl_get_ready_to_run:501: Lib Loader: (0x363000) /home/msakamoto/reduced.linux/uclibc_test/runtime/lib/ld-uClibc.so.0 _dl_get_ready_to_run:440: calling mprotect on the application program _dl_get_ready_to_run:786: file='libc.so.0'; needed by './ret1_dyn' _dl_load_shared_library:212: find library='libc.so.0'; searching _dl_load_shared_library:289: searching ldso dir='/home/msakamoto/reduced.linux/uclibc_test/runtime/lib' _dl_load_elf_shared_library:803: file='/home/msakamoto/reduced.linux/uclibc_test/runtime/lib/libc.so.0'; generating link map _dl_load_elf_shared_library:804: dynamic: 0xb7f26ed8 base: 0xb7ede000 _dl_load_elf_shared_library:806: entry: 0xb7ee5490 phdr: 0xb7ede034 phnum: 0x8 _dl_get_ready_to_run:808: Loading: (0xb7ede000) /home/msakamoto/reduced.linux/uclibc_test/runtime/lib/libc.so.0 INIT/FINI order and dependencies: lib: /home/msakamoto/reduced.linux/uclibc_test/runtime/lib/libc.so.0 has deps: _dl_get_ready_to_run:948: Beginning relocation fixups _dl_fixup:828: relocation processing: /home/msakamoto/reduced.linux/uclibc_test/runtime/lib/libc.so.0 ./ret1_dyn: symbol 'stdout': can't resolve symbol in lib '/home/msakamoto/reduced.linux/uclibc_test/runtime/lib/libc.so.0'.
どうしても "symbol 'stdout': can't resolve symbol in lib ..." になってしまう。
ローダの ld-uClibc-0.9.31.so は動いているらしい。でないと上記メッセージの出力まで到達しない。
で、
/uClibc-0.9.31/ldso/elfinterp.c
の
static int _dl_parse(...)
の中の
res = reloc_fnc(tpnt, scope, rpnt, symtab, strtab);
これが 0 より 大きい場合に上記メッセージが出力される。0だと正常ルート、マイナス値だと "can't handle reloc type..."みたいなメッセージになる(筈)。
でreloc_fnc()とゆーのは _dl_parse() にコールバックとして渡された関数ポインタ。この中がおかしい・・・というか、まぁ自分のコンパイルオプションだのインストール先がおかしいだのでエラーになっちゃったのかも。
素直にBuildroot使えって?
Buildroot使ってみたけれど、なんでtoolchainビルドするのにLinuxKernel落としてくるんだよ、ソレくらい自前で用意したの使えるようにしとけよ、というか全般的にあそこまでお仕着せになってしまうと、気持ち悪くて使いたくない。全部中身を理解した上でのショートカットとしてなら使えるけど、今回試しているのはまさに、中身を全部分解した上で、必要な部分だけ手動でつなぎあわせていく作業なのだから、せっかくの楽しみを奪うなよコンチキショーってところ。
ってか、Buildroot使わずに全部手動でuClibc, BusyBox使ってユーザーランド構築する記事もWeb上ではちらほらあるんだけど、Kernel-2.4.x時代の内容ばかりで、2011年4月時点の最新stableバージョンのuclibc, busyboxでは適用できない。
さらに言うと、色々原因を追い詰めていくにも、「今のmsakamoto-sfだからこそ」なんとか追い詰められないでもない程度で、というのはつまるところ、ELFのローダーであるとかELFファイルのフォーマットであるとかgccって結局binutilsのドライバだよね、でもどのcrtX.oをリンクするのかを知ってるのはgccになっちゃうから、だから面倒でもBuildrootはtoolchainでgccをビルドしなくちゃイカンよなぁ、いや単にCrossCompilerで必要だからというだけじゃなくてね、とか、gccのインクルードパスとかオプションとか調べるにも"-v"とか"--verbose"とか"--save-temps"とか知ってないと中身を分解できないし、そもそもMakefile.inとかそこら辺の周辺技術もひと通り頭に入れていないとそもそもビルドするときなにやってるのかが分からないよな、とかとか。
よーするにソースがオープンだということと、じゃぁそのソースの内容を理解して、Makefileによるビルドが何をどうコピーしてコンパイルしてリンクして移動したりinstallしてるのか、とか、さらにじゃぁビルドしたバイナリはどういうもので、Kernelによりどうやってメモリ上にロードされるのか、とか、トラブったときにobjdumpとかreadelfでELFファイルの中身を解析したり、gdbでマシン語レベルでデバッグしてCのソースと人力で対応付けられるのかとか、その辺のもろもろの胡乱な下準備なしに、トラブったときにその原因を調べられるわけねーだろ、的な感じなのですよ奥様!!
ってゆーかld-uClibcのローダ、どうやってデバッグしてるんだ?ld-linux.soの場合は単体で実行できるからそこからgdbでデバッグできそうだが、ld-uClibcはstandaloneでの起動が出来ないからそのテクニックもおそらく使えない・・・。
やべ、詰まった・・・?
glibcの動的リンクローダー:
$ LD_DEBUG=all /lib/ld-linux.so.2 /bin/ls -l /lib/ld-linux.so.2 ... 6130: binding file /bin/ls [0] to /lib/libc.so.6 [0]: ... lrwxrwxrwx 1 root root 9 4月 2 18:18 /lib/ld-linux.so.2 -> ld-2.5.so 6130: symbol=exit; lookup in file=/bin/ls [0] ...
uClibcの動的リンクローダー:
$ LD_DEBUG=all ./ld-uClibc-0.9.31.so ../../ret1_dyn argc=2 argv=0xbfb3bea4 envp=0xbfb3beb0 ELF header=0x6f5000 First Dynamic section entry=0x6fceec Scanning DYNAMIC section Done scanning DYNAMIC section About to do library loader relocations Done relocating ldso; we can now use globals and make function calls! _dl_get_ready_to_run:317: Cool, ldso survived making function calls Standalone execution is not supported yet
→ Oooops!!!
個人活動も一段落したので、エージェントや個人の伝手経由で就職活動ナウ。
実家の事情で、月にMAX4日ほど、平日、実家で祖父母の世話をする可能性がある。
・・・という事情を組んでくれる会社をエージェントに探してもらってます。
交渉次第で応じてくれる会社も探せばあるそうです。
IT系の良いところはそのへんの融通が効く会社も探せば出てくる、という点だと思います。
エージェントに話を聞いていると、やはり社風や風土との相性が重要とのこと。
前の会社も、仕事の進め方や取り組み方がその前とがらりと変わったのに適応しきれなかった部分があったり、チームリーダーとの人間関係でつまづいたりしたので、やはりその辺は注意する必要がある。
田舎の実家で高齢の祖父母や両親の面倒を見つつ、在宅で働く、という方法を将来的には見つけたい。
Linux KernelのMakefileターゲットで、
make clean
はオブジェクトファイルを削除、
make mrproper
だと設定ファイル関連も全て削除、という二つがあります。
で、"clean"は分かるが "mrproper" って何のこと?と前からうっすら気になってましたが、この度めでたく判明しました。
より:
トーバルス氏が、欧州で知られているMr.Properというクリーニング
製品の名前にちなんで付けたとのこと。
へぇ~x3
他、参照:
pykdはC言語で書かれたPython拡張で、WinDBG拡張機能の一部をPython経由で呼び出せます。
以前 Python/WinDBG拡張機能でデバッガを作ってみる で紹介したPyDbgEngと異なる点は、DbgEngのCOMコンポーネントをC++で隠蔽し、独自のインターフェイスでラップしてPython側に公開している点です。さらにWinDBG拡張機能としても使えるようになっていて、WinDBGやCDBのプロンプトから
!py foobar.py
みたいにしてPythonスクリプトを実行できます。このPythonスクリプト内からpykdが公開しているインターフェイスを通じてDbgEngを使うことが出来ます。つまりImmunity DebuggerみたいにPythonスクリプトを使って色々弄れちゃいます。
pykdはオープンソースとして codeplex で公開されています。2011年4月現時点で 0.0.16 のアルファ版、生まれたばかりです。
boost/pythonをフル活用してたり、64bit対応が強く意識されていたりとかなり気合が入っているのですが、弱点があります。
英語ドキュメントが無い!
上のURL見てみれば分かりますが、トップページが既にキリル文字・・・つまり、ロシア語です。
ということで、Googleの翻訳機能を使うかソースを読んで自分で使い方を学ぶしかありません。まぁ若いプロジェクトですから、これからのドキュメントの充実に期待したいところです。
本記事ではpykdを自分の環境に合わせてビルドする方法と、pykdのソースに付属するサンプルをいくつか紹介してみます。
本当は「オリジナルのデバッガを作ってみる!」とかやってみたいんですけど、上述の通り英語ドキュメントが無くて手探り状態に加え、ソースを読むのにも前提となる知識が C++, Python拡張の作り方、boost/python, WinDBG拡張機能とかなりヘヴィで正直そこまで潜れませんでした(´Д⊂グスン。
Boost.Pythonのメモ。
参考:
id:moriyoshi が紹介しているサンプルを、setup.pyでビルドしてみます。
環境:
Windows7 SP1 (x86_32) Python 2.7 VC++2008 Express Edition Boost 1.46.1
ポイントとしては "include_dirs", "library_dirs" を指定するところと、VC++2008の場合は"/EHsc"をextra_compile_argsで指定するところです。
from distutils.core import setup, Extension BOOST_ROOT = "C:\\Program Files\\boost\\boost_1_46_1" EXTRA_COMPILE_ARGS = [ "/EHsc" ] setup(name='t_pyext3', version='1.0', ext_modules=[ Extension('basic', ['basic.cpp'], include_dirs=[BOOST_ROOT], library_dirs=[BOOST_ROOT + "\\lib"], extra_compile_args=EXTRA_COMPILE_ARGS ), ], )
以上、setup.pyでBoost.Python使ったPython拡張をビルドするときの参考メモでした。
参考:
カーネルデバッグモードのWinDBGからPythonスクリプトを呼び出せる(らしい)、pykdというソフトをcodeplexで見つけたんだけど、ドキュメントがキリル文字で書かれてる。ロシア語っぽい。
面白そうなんだけどなぁ・・・。
Google翻訳使ってみてみようかどうしようか迷い中。まだアルファ段階なんだけど、結構気合入れて作ってる感じで、PyDbgEngよりは将来性が有りそう。
Amazonや公式サポートHPへのリンクは下記エントリを参照:
Windows SDK や Windows Driver Kit (WDK) にもれなく付いてくる"Debugging Tools for Windows"を中心に、MS社謹製の各種デバッグ・解析支援ツールを駆使したWindowsアプリのデバッグ方法を詳しく解説してくれている。
主な構成:
Windows用のデバッガは他にもOllyDbgやImmunityDebugger, IDA Proなどあるが、MS社謹製である点、Windowsカーネルに特化したショートカットコマンドが充実している点、さらに64bitにも対応している点から、"Debugging Tools for Windows"は是非とも道具箱に入れておきたい。
しかしWindowsカーネルすらデバッグできるツールである以上、公式ヘルプドキュメントの量は詳細にして膨大であり、コマンドも多すぎる。その都度Web上で検索して使い方を学んでいこうとすると、どうしても継ぎ接ぎや付け焼刃の知識になり不安が残る。
"Advanced Windows Debugging"はWinDBGや各種ツールを効率的に活用していくための、体系的かつ「王道」なテクニック・ノウハウが詰め込まれているので、一読に値する内容となっている。ひと通り体に染み込ませた後なら、ヘルプドキュメントを開いてその分量に圧倒されること無く、目的の機能を調べることが出来るようになっているだろう。
なお、Windows XP SP2公開 - Windows Vista 発売位迄を対象としているため、WinXP SP3での変更点やWindows7まではフォローしきれていない点に注意が必要。またPart1, Part2ともに32bitOSでの解説となっている点も留意しておくべき。