SkyEye(TOPPERS版)とGDBデバッグ可能な環境の準備(CodeSourceryを使わずに)
SkyEye 向けにRTOSをポーティングしたくて,環境を整えていたのでメモ.
開発ツールとして CodeSourcery が使われることが多いが,どうしても使いたくないので別のツール(たとえばGCC ARM Embedded in Launchpadとか)を使ってコンパイル,デバッグまで出来ないかどうかを試してみる.
ちなみに,SkyEyeは TOPPERSプロジェクト/TOPPERSカーネル向けシミュレーション環境 の skyeye_devm_package-1.0.5.zip を使用する.もっと新しいの(たとえばSkyEye download | SourceForge.netとかには1.3.5とかがある)でもよいのだけれど,動作実績のある組み合わせで試したかったのでこちらを使うことにした.
コンパイラは先に挙げた LanchPad の ARM向けGCC 4.9を利用.
シェルは Cygwin を使用.ホスト向けコンパイラとかその辺はインストール済み.
サンプルとしてはこちらを試してみた.
そのままではビルドできなかったのでちょっと修正.
これでビルドは出来たので,skyeye(TOPPERS版) で実行してみる.
$ skyeye.exe -c skyeye.conf -e timerirq_hello big_endian is false. arch : arm cpu info: armv3, arm7tdmi, 41007700, fff8ff00, 0 mach info: name at91, mach_init addr 0x41d650 uart_mod:0, desc_in:, desc_out:, converter: SKYEYE: use arm7100 mmu ops exec file "timerirq_hello"'s format is elf32-little. load section .text: addr = 0x00000000 size = 0x0000011c. load section .rodata.str1.4: addr = 0x0000011c size = 0x00000010. load section .data: addr = 0x00002000 size = 0x00001c00. not load section .comment: addr = 0x00000000 size = 0x00000070 . not load section .ARM.attributes: addr = 0x00000000 size = 0x00000025 . not load section .debug_abbrev: addr = 0x00000000 size = 0x000000fe . not load section .debug_info: addr = 0x00000000 size = 0x00000148 . not load section .debug_line: addr = 0x00000000 size = 0x000000ca . not load section .debug_aranges: addr = 0x00000000 size = 0x00000040 . not load section .debug_loc: addr = 0x00000000 size = 0x0000004d . not load section .debug_str: addr = 0x00000000 size = 0x000000c3 . not load section .debug_frame: addr = 0x00000000 size = 0x00000030 . call ARMul_InitSymTable,kernel filename is timerirq_hello. hello world! hello world! hello world! hello world! hello world! hello world! hello world! hello world! hello world! hello world!
あっさり動く.
Cygwinのウィンドウを2つ用意し,片方で skyeye を gdb のリモートサーバとして起動.
$ skyeye.exe -c skyeye.conf -d **************************** WARNING ********************************** If you want to run ELF image, you should use -e option to indicate your elf-format image filename. Or you only want to run binary image, you need to set the filename of the image and its entry in skyeye.conf. *********************************************************************** big_endian is false. arch : arm cpu info: armv3, arm7tdmi, 41007700, fff8ff00, 0 mach info: name at91, mach_init addr 0x41d650 uart_mod:0, desc_in:, desc_out:, converter: SKYEYE: use arm7100 mmu ops debugmode= 1, filename = skyeye.conf, server TCP port:12345
もう一方で gdb を起動.
$ arm-none-eabi-gdb timerirq_hello GNU gdb (GNU Tools for ARM Embedded Processors) 7.8.0.20150304-cvs Copyright (C) 2014 Free Software Foundation, Inc. License GPLv3+: GNU GPL version 3 or later <http://gnu.org/licenses/gpl.html> This is free software: you are free to change and redistribute it. There is NO WARRANTY, to the extent permitted by law. Type "show copying" and "show warranty" for details. This GDB was configured as "--host=i686-w64-mingw32 --target=arm-none-eabi". Type "show configuration" for configuration details. For bug reporting instructions, please see: <http://www.gnu.org/software/gdb/bugs/>. Find the GDB manual and other documentation resources online at: <http://www.gnu.org/software/gdb/documentation/>. For help, type "help". Type "apropos word" to search for commands related to "word"... Reading symbols from timerirq_hello...done. (gdb) target remote localhost:12345 Remote debugging using localhost:12345 Reply contains invalid hex digit 117 (gdb)
接続に失敗する.ちなみにリモートサーバの方も接続に失敗の表示が出てる.
Remote debugging using port:12345 readchar: Got EOF Remote side has terminated connection. GDBserver will reopen the connection.
少しググったところでは,自分の使用していた arm-none-eabi-gdb (version7.8)が新しいために target remote で接続に失敗しているらしい.
hiro99ma blog: [os]SkyEyeとGDBで接続できんのはSkyEyeバグらしいのでGDBバージョンを落とした
SkyEye / Bugs / #68 sth. wrong about remote-gdb
新しい SkyEye を使ってうまくいく自信がないので先に gdb-7.1 のビルドを試すことにした.
http://ftp.gnu.org/gnu/gdb/ から gdb-7.1a.tar.gz をダウンロード
ファイルを展開,移動
tar xvf gdb-7.1a.tar.gz cd gdb-7.1
適当な名称でディレクトリ作成して移動
mkdir build cd build
ビルド
../configure --target=arm-none-eabi --prefix=/home/saito/tool/gdb-7.1 --enable-interwork --enable-multilib make all make install
途中でビルドエラーになった(libncurces-devが無かったり,-Werrorに引っかかったりした)が,その辺は省略(簡単に対処できると思うので).
それで,作った GDB-7.1 でサーバに接続して実行開始してみる.
$ ~/tool/gdb-7.1/bin/arm-none-eabi-gdb timerirq_hello GNU gdb (GDB) 7.1 Copyright (C) 2010 Free Software Foundation, Inc. License GPLv3+: GNU GPL version 3 or later <http://gnu.org/licenses/gpl.html> This is free software: you are free to change and redistribute it. There is NO WARRANTY, to the extent permitted by law. Type "show copying" and "show warranty" for details. This GDB was configured as "--host=i686-pc-cygwin --target=arm-none-eabi". For bug reporting instructions, please see: <http://www.gnu.org/software/gdb/bugs/>... Reading symbols from /home/saito/work/timerirq/timerirq_hello...Dwarf Error: wrong version in compilation unit header (is 4, should be 2) [in module /home/saito/work/timerirq/timerirq_hello] (gdb) target remote localhost:12345 Remote debugging using localhost:12345 0x00000000 in ?? () (gdb) load Loading section .text, size 0x11c lma 0x0 Loading section .rodata.str1.4, size 0x10 lma 0x11c Loading section .data, size 0x1c00 lma 0x2000 Start address 0x0, load size 7468 Transfer rate: 911 KB/sec, 155 bytes/write. (gdb) c Continuing. Can't send signals to this remote system. SIGHUP not sent.
そうするとサーバはちゃんと動いている.
Remote debugging using port:12345 hello world! hello world! hello world! hello world! hello world! hello world! hello world! hello world! hello world! hello world! hello world! hello world! hello world! hello world! hello world! hello world!
と,いうわけでとりあえず実行ファイルさえ作ってしまえばデバッグは出来そうだということは確認できた.
しかし,よく見ると
Reading symbols from /home/saito/work/timerirq/timerirq_hello...Dwarf Error: wrong version in compilation unit header (is 4, should be 2) [in module /home/saito/work/timerirq/timerirq_hello]
などというメッセージが出ているのが気になる.ステップ実行を試みても
(gdb) s Cannot find bounds of current function
となって出来ない.
要するに,デバッグ情報の格納に使うフォーマット(DWARF)のバージョンが合ってないということらしい.GDBの方が古いので,それが解釈できるようなバージョンにしてやる必要があるらしい.
ということで Debugging Options - Using the GNU Compiler Collection (GCC) を見ても大量にあってよくわからないが,もう少しググってみたら次の情報を見つけた.
c++ - How to change the version of a compilation unit? - Stack Overflow
つまり -gdwarf-2 -gstrict-dwarf とかを -g に追加すればいいんじゃね?ということのようなので再度ビルドしてGDBに読み込ませてみた.
$ ~/tool/gdb-7.1/bin/arm-none-eabi-gdb timerirq_hello GNU gdb (GDB) 7.1 (snip...) Reading symbols from /home/saito/work/timerirq/timerirq_hello...done.
読み込み時のエラーが消えた.
さらに,接続してプログラムリストも表示させてみた.
(gdb) target remote localhost:12345 Remote debugging using localhost:12345 begin () at timerirq.S:26 26 B reset /* 0x00 Reset handler */ (gdb) l 21 .text 22 .align 4 23 .global begin 24 .type begin, function 25 begin: 26 B reset /* 0x00 Reset handler */ 27 undefvec: 28 B . /* 0x04 Undefined Instruction */ 29 swivec: 30 B softirq /* 0x08 Software Interrupt */ (gdb)
表示もできる.ついでもステップ実行も出来た.というわけで,なんとかデバッグできる環境は準備できた.