1
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 3 years have passed since last update.

aarch64 linux で C/C++ 浮動小数点例外周りのメモ

Last updated at Posted at 2020-07-09

背景

  • レイトレや機械学習のコードで, どうも NaN とかが出ているようで, 計算結果(e.g. ピクセル値)がおかしい
  • 原因を突き止めるため, aarch64 C/C++ プログラムで, NaN とかが発生したら SIGFPE とか seg fault してほしい

結論

少なくとも, x86 のように例外が起きたらプログラムが自動で seg fault するとかシグナル出すのは, aarch64 では無理(大部分の(?) HW が未実装)なことがわかりました.
もしかしたら iOS(arm64) ではいけるかもしれません.

怪しいコードのところに明示的に FPU 例外ステータスチェックを入れての対応になります.
clang undefined behavior sanitizer で, ソフトウェア的に divide-by-zero と overflow は検出できます.

環境

  • aarch64 linux(Ubuntu 18.04 + Jetson) を想定する
  • glibc 環境
  • gcc 7.5.0(apt で入る)
  • clang 10.0(llvm.org などから手に入る prebuilt or apt パッケージ)

fenv.h は

/usr/include/fenv.h
/usr/include/aarch64-linux-gnu/bits/fenv.h

にあります.

sNaN

aarch64 + gcc/clang では, NaN(sNaN) のシグナル検出はデフォルトでは有効にならない.

gcc/clang では -fsignaling-nans で有効にする.
ただし, これらはコンパイラでの扱いを変えるだけで, FPU の動作自体には影響はない(コメントありがとうございます!)
(-fsignaling-nans を指定しても aarch64 では NaN で浮動小数点数例外トラップは発生しない)

以下, 参考まで.

__SUPPORT_SNAN__ が定義される.

/* NaN support.  */

# if (__GLIBC_USE (IEC_60559_BFP_EXT)    \
     && defined FE_INVALID      \
     && defined __SUPPORT_SNAN__)
# define FE_SNANS_ALWAYS_SIGNAL 1
# endif

FE_SNANS_ALWAYS_SIGNAL はそのままでは定義されない.

_GNU_SOURCE を定義することで有効になる.

# define _GNU_SOURCE
# include <fenv.h>

ソースコードで定義する場合は, 最初に _GNU_SOURCE を定義する必要がある.

// NG
# include <signal.h>
# define _GNU_SOURCE
# include <fenv.h>

などとするとうまくいかない.

feenableexcept

例外トラップ指定 feenableexcept は aarch64 では利用できない. -1 を返してしまう.

arm compiler でも aarch64 は例外トラップはサポートしないとあるので, aarch64 環境では浮動小数点例外トラップが使えないと考えてよいでしょう.

Clang undefined behavior sanitizer

ゼロ除算は -fsanitize=float-divide-by-zero で検出できる.

ただし, sqrtf(-1.0f) のように NaN が生成されるのは検出できない.

builtin

__builtin_aarch64_set_fpcr で FP control register 指定.

例外ビットは定義されているが, 設定しても反映されない(コメントありがとうございます).

手動検出

C/C++ コードで, 怪しそうなところを feclearexcept と ftestexcept で囲い, 例外ビットが立っているか検出し, 自前で SIGFPE なり発行するしかない.

gdb で NaN 検出

watch でいけるが, ただし変数の場所がわかっている必要がある.

参考文献

1
0
2

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
1
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?