目次: Zephyr
GDBとPython 3.9の組み合わせは、SEGVでクラッシュしました。調べてみると FedoraのBugzilla にドンピシャの情報が載っていました。Python 3.9とGDBの組み合わせが動かなかったこと、Red Hatの人がパッチを作ってくれて、5/28に修正されたこと、などが書いてあります。
Zephyr SDKのGDBは9.2(2020年5月23日リリース)で、上記のPython 3.9で動かすための修正は入っていません。残念。選択肢としては下記の2つが考えられます。
GDBのバージョンを変えると新たな厄災を招く恐れがあるため、今回は保守的に9.2 + パッチで行こうと思います。
Zephyr SDKは内部でCrosstool-NGというツールチェーンのビルドツールを利用しています。Zephyr SDKに突撃する前にCrosstool-NGの仕組みをおさらいし、9.2 + パッチでビルドする方法を試します。
Zephyr SDKのconfigs/ ディレクトリの下を見ると *.configファイルがたくさんあります。実はこれらはCrosstool-NGのコンフィグファイルです。このファイルをCrosstool-NGにコピーするとツールチェーンが作成できます。わかりやすいですね。
$ cd sdk-ng $ ls configs/ arc.config nios2.config xtensa_intel_byt_adsp.config arm.config riscv64.config xtensa_intel_s1000.config arm64.config sparc.config xtensa_nxp_imx8m_adsp.config i586.config x86_64-zephyr-elf.config xtensa_nxp_imx_adsp.config iamcu.config xtensa_intel_apl_adsp.config xtensa_sample_controller.config mips.config xtensa_intel_bdw_adsp.config
Crosstool-NGはツールチェーンの各モジュールにパッチを当てられます。例えばGDB 9.2ならばpackages/gdb/9.2/ の下にパッチファイルを置くと、若い番号から順番にパッチ適用してくれます。
$ ls packages/gdb/9.2/ 0000-musl_fix.patch 0004-allow-android.patch 0001-uclibc-no-gettimeofday-clobber.patch chksum 0002-xtensa-make-sure-ar_base-is-initialized.patch version.desc 0003-WIP-end-of-prologue-detection-hack.patch
このディレクトリに0005-xxxx.patchのような名前のパッチを追加すると、0004-allow-android.patchのあとにパッチを当ててくれます。便利ですね。パッチ当て処理の実装を見ましょう。
# crosstool-ng/scripts/functions
CT_DoExtractPatch()
{
...
CT_Pushd "${src_dir}/${basename}"
for d in "${patch_dirs[@]}"; do
CT_DoLog DEBUG "Looking for patches in '${d}'..."
if [ -n "${d}" -a -d "${d}" ]; then
for p in "${d}"/*.patch; do #★パッチファイルを列挙、パッチ当てる
if [ -f "${p}" ]; then
CT_DoExecLog ALL ${patch} --no-backup-if-mismatch -g0 -F1 -p1 -f -i "${p}"
fi
done
fi
done
...
ビルド後にできるログbuild.logをLooking for patchesで検索していくと、パッチを当てている箇所が確認できます。
... [DEBUG] Looking for patches in 'crosstool-ng/packages/gdb/9.2'... [DEBUG] ==> Executing: '/usr/bin/patch' '--no-backup-if-mismatch' '-g0' '-F1' '-p1' '-f' '-i' 'crosstool-ng/packages/gdb/9.2/0000-musl_fix.patch' [ALL ] patching file gdb/linux-nat.c [ALL ] patching file gdb/stopcode.h [DEBUG] ==> Return status 0 [DEBUG] ==> Executing: '/usr/bin/patch' '--no-backup-if-mismatch' '-g0' '-F1' '-p1' '-f' '-i' 'crosstool-ng/packages/gdb/9.2/0001-uclibc-no-gettimeofday-clobber.patch' [ALL ] patching file gnulib/configure [ALL ] patching file gnulib/import/m4/gettimeofday.m4 [DEBUG] ==> Return status 0 ...
Crosstool-NGがパッチを当てる順はシェルのファイル列挙順のため、ファイル名は必ずしも数字で始める必要はないです。しかし、前例に習ったほうが良いでしょう。パッチを0005-fix-python3.9.patchという名前で追加します。
$ git clone https://github.com/crosstool-ng/crosstool-ng $ cd crosstool-ng $ cat > packages/gdb/9.2/0005-fix-python3.9.patch (パッチをコピペする) $ ./bootstrap $ ./configure --enable-local $ make $ cp ../sdk-ng/configs/riscv64.config ./.config $ ./ct-ng menuconfig $ ./ct-ng build
ビルド後にできるログbuild.logを確認して、パッチが当たっていることを確かめます。
... [DEBUG] Looking for patches in 'crosstool-ng/packages/gdb/9.2'... [DEBUG] ==> Executing: '/usr/bin/patch' '--no-backup-if-mismatch' '-g0' '-F1' '-p1' '-f' '-i' 'crosstool-ng/packages/gdb/9.2/0000-musl_fix.patch' [ALL ] patching file gdb/linux-nat.c [ALL ] patching file gdb/stopcode.h [DEBUG] ==> Return status 0 [DEBUG] ==> Executing: '/usr/bin/patch' '--no-backup-if-mismatch' '-g0' '-F1' '-p1' '-f' '-i' 'crosstool-ng/packages/gdb/9.2/0001-uclibc-no-gettimeofday-clobber.patch' [ALL ] patching file gnulib/configure [ALL ] patching file gnulib/import/m4/gettimeofday.m4 [DEBUG] ==> Return status 0 ... [DEBUG] ==> Executing: '/usr/bin/patch' '--no-backup-if-mismatch' '-g0' '-F1' '-p1' '-f' '-i' 'crosstool-ng/packages/gdb/9.2/0005-python3.9.patch' [ALL ] patching file gdb/python/python.c [ALL ] Hunk #1 succeeded at 234 (offset -4 lines). [ALL ] Hunk #2 succeeded at 271 (offset -4 lines). [ALL ] Hunk #3 succeeded at 952 (offset -19 lines). [ALL ] Hunk #4 succeeded at 1552 (offset -68 lines). [ALL ] Hunk #5 succeeded at 1720 (offset -70 lines). [ALL ] patch unexpectedly ends in middle of line [DEBUG] ==> Return status 0
GDBの開発メールアーカイブから適当にコピペしてパッチを作ったので、Hunkがずれてるよって怒られましたが、パッチ当ては成功しています。あまり気にしなくても良いでしょう。ビルド後は動作確認しましょう。
$ cd ~/x-tools/riscv64-zephyr-elf/bin $ ./riscv64-zephyr-elf-gdb --version GNU gdb (crosstool-NG 1.24.0.254_fcf3233) 9.2 Copyright (C) 2020 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.
動きました。良かった良かった。
目次: RISC-V
たまにRISC-V向けのQEMUの動きを見たいときがあって、デバッグビルドをするのですが、やり方を忘れがちなのでメモしておきます。
$ mkdir build $ cd build $ ../configure --target-list=riscv32-softmmu,riscv32-linux-user,riscv64-softmmu,riscv64-linux-user \ --disable-docs --enable-debug ... qemu 5.2.50 Install prefix: /usr/local BIOS directory: share/qemu firmware path: /usr/local/share/qemu-firmware binary directory: bin library directory: lib module directory: lib/qemu libexec directory: libexec include directory: include config directory: /usr/local/etc local state directory: /usr/local/var Manual directory: share/man Doc directory: /usr/local/share/doc ... thread sanitizer: NO rng-none: NO Linux keyring: YES FUSE exports: NO FUSE lseek: NO Subprojects libvhost-user: YES Found ninja-1.10.1 at /usr/bin/ninja $ ninja
ビルドが成功するとbuildディレクトリ以下にqemu-system-riscv32やqemu-system-riscv64が生成されているはずです。
目次: Zephyr
開発用のマシンではDebian Testingを使っているのですが、久しぶりにdist-upgradeしたところPython 3.8が消えてしまいました。Python 3.9に移行したみたいです。
アップデート時は「そうなんだ、3.9になったんだな。」くらいの認識でスルーしまいたが、Zephyrを使おうとしたら異変に気づきました。なんとZephyr SDKのGDBが動きません。どうしてこうなった。
$ riscv64-zephyr-elf-gdb riscv64-zephyr-elf-gdb: error while loading shared libraries: libpython3.8.so.1.0: cannot open shared object file: No such file or directory
Debianは元々Zephyr SDKのサポート範囲に入っていない(Ubuntuのみ)ですし、Debian Testingなんてサポートされるはずがないので、自力で解決する必要があります。
Zephyr SDKのビルド手順は簡単ですが、Debian Testingだとうまくいきません。
$ git clone https://github.com/zephyrproject-rtos/sdk-ng $ cd sdk-ng $ ./go.sh riscv64 ./go.sh: 行17: python: コマンドが見つかりません
Pythonが見つからず怒られます。Debian Testingは /usr/bin/pythonがなくなったため、go.shのpythonをpython3に書き換えてあげると動きます。他にもPython 3.8を想定している箇所があるので、Python 3.9に直します。
diff --git a/configs/riscv64.config b/configs/riscv64.config
index 295f2c0..a9fc301 100644
--- a/configs/riscv64.config
+++ b/configs/riscv64.config
@@ -46,5 +46,5 @@ CT_CC_LANG_CXX=y
CT_CC_GCC_LIBSTDCXX_NANO=y
CT_DEBUG_GDB=y
CT_GDB_V_9_2=y
-CT_GDB_CROSS_PYTHON_BINARY="python3.8"
+CT_GDB_CROSS_PYTHON_BINARY="python3.9"
CT_GDB_CROSS_BUILD_NO_PYTHON=y
diff --git a/go.sh b/go.sh
index e5442fa..7a45fd8 100755
--- a/go.sh
+++ b/go.sh
@@ -14,7 +14,7 @@ fi
COMMIT="d7da3a9c7f0f3a90bb4c71b91aea6cbc2471a541"
GITDIR=${PWD}
-JOBS=$(python -c 'import multiprocessing as mp; print(mp.cpu_count())')
+JOBS=$(python3 -c 'import multiprocessing as mp; print(mp.cpu_count())')
unameOut="$(uname -s)"
unameMachine="$(uname -m)"
SDKはbuild/output以下に生成されます。RISC-V 64であればbuild/output/riscv64-zephyr-elfです。生成されたバイナリが動くか確かめましょう。
$ cd build/output/riscv64-zephyr-elf/bin $ ./riscv64-zephyr-elf-gdb Segmentation fault
SEGVで死にました。うーん、だめそうですね……。次回以降、直せないかトライします。
< | 2021 | > | ||||
<< | < | 01 | > | >> | ||
日 | 月 | 火 | 水 | 木 | 金 | 土 |
- | - | - | - | - | 1 | 2 |
3 | 4 | 5 | 6 | 7 | 8 | 9 |
10 | 11 | 12 | 13 | 14 | 15 | 16 |
17 | 18 | 19 | 20 | 21 | 22 | 23 |
24 | 25 | 26 | 27 | 28 | 29 | 30 |
31 | - | - | - | - | - | - |
合計:
本日: