ようやく涼しくなってきたと思った瞬間に晩秋になってしまい、秋がなかったなぁ、としみじみと感じてしまいました。
第三回は、Cross Compileできたものの、上手く動かない、というときに役立つデバッグについて書きます。
Cross Compileしたバイナリの難しさ
Linux上でクロスコンパイルしたバイナリですが、実際にこのバイナリを動かしてみると、問題が発生(Segfaultとか)することがあります。
特に最初はWineで動かすと思いますが、エラーの内容がメモリアドレスくらいしか無く、結構色々と辛いです。Windows上で実行してみるのも中々にしんどいです。普通にそのまま実行時エラーで落ちるので。
Visual Studioとかで動かしてみる、というのも手段だと思いますが、ここではあくまでLinux上で解決してみます。
gdbserverとgdb
gdbには、remoteのgdbと繋げてローカルで実行できる gdbserver
というツールが存在しています。
Debianであれば、まず以下でmingw向けのgdbserverと、mingwでコンパイルされたtargetをデバッグできるgdbをインストールします。
apt install mingw32-w64-gdbserver mingw32-w64-gdb-target
これを使うと、以下のようにしてdebugを行えます。
wine /usr/share/win64/gdbserver :3000 sample.exe
x86_64-w64-mingw32-gdb sample.exe
# ここからGDB内
> remote target localhost:3000
# つながると普通の(若干コマンドが成約されていますが)gdbとして使えます。
> continue
Program received signal SIGSEGV, Segmentation fault.
0x0000000000a19d1c in lwt_unix_not_available (feature=<optimized out>) at lwt_unix_stubs.c:107
107 lwt_unix_stubs.c: No such file or directory.
(gdb) bt
#0 0x0000000000a19d1c in lwt_unix_not_available (feature=<optimized out>) at lwt_unix_stubs.c:107
#1 0x0000000000a1b400 in lwt_unix_iov_max (a1=<optimized out>) at windows_not_available.c:16
#2 0x00000000008611ed in camlLwt_unix__entry ()
#3 0x0000000000000001 in ?? ()
上記のように、Windows向けにビルドしたバイナリを、Linux上でデバッグできます。OCamlでビルドしたものであれば、上記のようにcaml系統のデバッグシンボルも見えるので、デバッグがはかどります。
今回は短かったですが、この情報が中々見つからず、苦労してしまったので、どこかの誰かのお役に立てばと思います。