Home > android > Mac OSXのAndroid m5-rc14でNativeファイルがSegmentation faultになる

Mac OSXのAndroid m5-rc14でNativeファイルがSegmentation faultになる

AndroidでC言語で書いたネイティブアプリを動かしてみる」というエントリを思い出し、AndroidでNative Cを実行しようと思ったのですが失敗しています。どこで失敗したかをメモ。

環境
Mac OSX

Mac環境はこうなっています。

  • Mac OSX version: 10.5.2
  • CPU: 2GHz Intel Core Duo
  • Mem: 2GB
Android

Androidの環境はこうなっています。

  • Version: Android-SDK m5-rc14
$ adb shell
# cat /proc/cpuinfo
Processor : ARM926EJ-S rev 5 (v5l)
BogoMIPS : 271.15
Features : swp half thumb fastmult vfp edsp java
CPU implementer : 0×41
CPU architecture: 5TEJ
CPU variant : 0×0
CPU part : 0×926
CPU revision : 5
Cache type : write-through
Cache clean : not required
Cache lockdown : not supported
Cache format : Harvard
I size : 4096
I assoc : 4
I line length : 32
I sets : 32
D size : 65536
D assoc : 4
D line length : 32
D sets : 512
Hardware : Goldfish
Revision : 0000
Serial : 0000000000000000
Cソースコード

とりあえずHello, world。

hello.c

#include <stdio.h>
 
int main() {
  printf("Hello, world!\n");
  return 0;
}

普通のGCCでコンパイルして実行してみる。

$ gcc –version
i686-apple-darwin9-gcc-4.0.1 (GCC) 4.0.1 (Apple Inc. build 5465)
$ gcc -o hello hello.c
$ ./hello
Hello, world!

当たり前ですが、ファイルに問題なし。
arm用にクロスコンパイル。

$ arm-elf-gcc –version
arm-elf-gcc (GCC) 3.3.2
$ arm-elf-gcc -static -o hello hello.c
$ file hello
hello: ELF 32-bit LSB executable, ARM, version 1 (ARM), statically linked, not stripped

うまくできている気がする。

Androidでネイティブファイル実行

クロスコンパイルしたファイルをAndroidに持っていって実行してみる。

$ adb push hello /tmp
862 KB/s (308832 bytes in 0.349s)
$ adb shell
# cd /tmp
# ./hello
[1] Segmentation fault ./hello

ここでセグフォ。

逆アセンブルしてみる

Mac OSX上で実行ファイルを逆アセンブルしてみる。

$ arm-elf-gdb hello
GNU gdb 6.0
(gdb) disassemble main
Dump of assembler code for function main:
0×00008224 : mov r12, sp
0×00008228 : stmdb sp!, {r11, r12, lr, pc}
0×0000822c : sub r11, r12, #4 ; 0×4
0×00008230 : ldr r0, [pc, #12] ; 0×8244
0×00008234 : bl 0×8ae4 0×00008238 : mov r3, #0 ; 0×0
0×0000823c : mov r0, r3
0×00008240 : ldmdb r11, {r11, sp, pc}
0×00008244 : streqh r0, [r1], -r0
End of assembler dump.

ARMのアセンブラが良くわかってないけど、変には見えない。(分かってないだけ?)
なんで動かないんだろう…。
ちなみにm3-rc37aでも動かない。
Mac版のクロスコンパイラが良くないのかな??

関連のありそうなエントリ

Comments:9

安藤恐竜 08-02-27 (水) 10:51

クロスコンパイラがおかしい気がする。-staticを外したらどーでしょ?リナザウ用にOpen Embeddedのコンパイラでクロスしたバイナリは元気良く動いてます。busyboxとかtarとか。下の2つも同様にビルドしたものなので、Macなエミュレータで動くはずですが。暇だったらpushしてみてください。

Android Zaurus: ncftp for Angstrom
http://androidzaurus.seesaa.net/article/78886916.html
http://androidzaurus.up.seesaa.net/image/ncftp-3.2.1-arm-linux.tar.gz

Android Zaurus: w3m for Angstrom
http://androidzaurus.seesaa.net/article/78485394.html
http://androidzaurus.up.seesaa.net/image/arm-w3m.tar.gz
http://androidzaurus.up.seesaa.net/image/arm-libgc.tar.gz

Native Appに関する考察はここが一番詳しい気がする。
motz diary
http://honeypod.blogspot.com/

MichaeL 08-02-27 (水) 11:58

ここを参考にEABIのオプションを変えてみてはどうでしょうか
http://jr0bak.homelinux.net/~imai/linux/arm_gcc_badknowhow/arm_gcc_badknowhow-8.html
GCC4.1以降にする必要があるようですが、
gcc -mabi=aapcs-linux
にすると動きそうな予感がします。

adamrocker 08-02-27 (水) 22:00

>安藤恐竜さん
w3mを試してみたんですが、どうもうまくいきません。

# ls w3m*
w3m
w3mbookmark
w3mhelperpanel
w3mimgdisplay
# ./w3m http://www.google.com
./w3m: not found

何か根本的におかしいのかも知れません(汗)

>MichaeLさん
これは知りませんでた。アライメントが4Bじゃなく1Bなんですね。プリフェッチの効率よりもメモリ効率という設計でしょうか?!
勉強になりました。ありがとうございます。
残念ながらMacでarm-gcc4.1をコンパイルできてません…orz

MichaeL 08-02-28 (木) 12:09

GCC4.1ではだめでした。
arm-linux-gcc -mabi=aapcs-linux hoge.c -static
のようにしましたが、”Illegal instruction”と出て起動できませんでした。
ここで紹介されているコンパイラを使ってコンパイルしてみたら起動できました。
http://honeypod.blogspot.com/2007/12/compile-android-kernel-from-source.html
Macだとソースからコンパイラをビルドする必要があるかもしれません。
こちらでダウンロードしたときは
・ARM GNU/Linux
・IA32 GNU/Linux
を選択しました。
・ARM EABI
ではコンパイルすら通りませんでした。
※クロス環境はVMWare上のdebianです。
以上、参考になれば幸いです。

adamrocker 08-02-28 (木) 14:39

>MichaeLさん
情報有難う御座います。

とりあえず現状メモ。
私はhttp://www.gnuarm.com/からMac用toolchainを手に入れやっていました。
結果は、このエントリの通りです。
次に上記サイトからGCC4.1のsrcを手に入れ、コンパイル。
Macでは失敗しましたが、Linuxでは成功。
しかし、Android上では”Illegal instruction”となり動きませんでした。

ちなみにstaticオプションを付けないと”./hello: not found”となるようです。
次はMichaeLさんが成功したという方法をまずはLinux上で試してみます。
本当はMacで全部やりたい・・・。
VMWareは購入を検討中です。

adamrocker 08-02-28 (木) 14:45

コメントと作業をパラでやっていましたら、作業が思いの他すぐに終わってしまったので報告。

結果は「成功」です。
バイナリをダウンロードしてきただけなので、この方法が一番簡単そうですね。IA32しかないところが悩ましいところですが…。
MichaeLさんとは異なりredhat系(CentOS4.3)でも実行できました。
そして、コンパイル時にstaticオプションを付けないと、やはり”./hello: not found”となってしまいました。staticはmustですね。

ファイル情報もついでに記載しておきます。

%./arm-none-linux-gnueabi-gcc -o hello hello.c -static
%file hello
hello: ELF 32-bit LSB executable, ARM, version 1 (SYSV), for GNU/Linux 2.6.14, statically linked, not stripped

ついでに逆アセンブルの結果も。

%./arm-none-linux-gnueabi-gdb hello
GNU gdb (CodeSourcery Sourcery G++ Lite 2007q3-51) 6.6.50.20070821-cvs
(gdb) disassemble main
Dump of assembler code for function main:
0×00008210
:    push    {r11, lr}
0×00008214
:    add     r11, sp, #4     ; 0×4
0×00008218
:    ldr     r0, [pc, #12]   ; 0×822c

0×0000821c
:   bl      0×9160

0×00008220
:   mov     r3, #0  ; 0×0
0×00008224
:   mov     r0, r3
0×00008228
:   pop     {r11, pc}
0×0000822c
:   strdeq  r2, [r6], -r4
End of assembler dump.
(gdb)
安藤恐竜 08-02-28 (木) 19:29

よかったよかった
Android向けバイナリを作成するWebサービスを作っといたら便利かもしれないですね。自分が使うだけにしても。

MichaeL 08-02-28 (木) 19:36

いいものがありました。
*Dynamically linked “Hello, world!” for Android
http://honeypod.blogspot.com/2007/12/dynamically-linked-hello-world-for.html

この方法でstaticでなくても実行できそうです。

adamrocker 08-02-29 (金) 13:46

情報有難う御座います。これはイイですね。
早速試して、上手くいきました。
一応メモを残しておきます。(後ほど、ちゃんとしたエントリで纏める予定です)
ファイルはこうです。

$ cat hello.c
int main(int argc, char **argv)
{
printf(”Hello, world!\n”);
return 0;
}

$cat start.c
#include
extern int main(int argc, char **argv);
void _start(int argc, char **argv)
{
exit( main(argc, argv) );
}

コンパイル。

./arm-none-linux-gnueabi-gcc -c hello.c
./arm-none-linux-gnueabi-gcc -c start.c
./arm-none-linux-gnueabi-ld –entry=_start –dynamic-linker /system/bin/linker -rpath /system/lib -lc -o hello-dynamic hello.o start.o

$file hello-dynamic
hello-dynamic: ELF 32-bit LSB executable, ARM, version 1 (SYSV), dynamically linked (uses shared libs), not stripped

ダイナミックリンカ(ローダ)を指定して、ライブラリパスを教えてあげるだけで基本OKみたいですね。

次にAndroidへファイルの移動と実行。

$ adb push hello-dynamic /tmp
$ adb shell
# cd /tmp
# chmod 755 hello-dynamic
# ./hello-dynamic
Hello, world!

ちなみに、staticリンクでコンパイルしたファイルとのファイルサイズ比較。

$ ./arm-none-linux-gnueabi-gcc -o hello-static hello.c -static
$ file hello-static
hello-static: ELF 32-bit LSB executable, ARM, version 1 (SYSV), for GNU/Linux 2.6.14, statically linked, not stripped
$ du -h hello-*
8.0K hello-dynamic
564K hello-static
$size hello-*
text data bss dec hex filename
340 188 0 528 210 hello-dynamic
450540 1952 6244 458736 6fff0 hello-static

良い感じですね^^

Comment Form
Remember personal info

*
To prove that you're not a bot, enter this code
Anti-Spam Image

Trackbacks:0

Trackback URL for this entry
http://www.adamrocker.com/blog/190/run_android_native_file_result_in_segmentation_fault_on_mac_osx.html/trackback/
Listed below are links to weblogs that reference
Mac OSXのAndroid m5-rc14でNativeファイルがSegmentation faultになる from throw Life

Home > android > Mac OSXのAndroid m5-rc14でNativeファイルがSegmentation faultになる

Search
Feeds
Meta

Return to page top