非同期安全ではない信号ハンドラーから呼び出された関数
割り込み関数の呼び出しは未定義のプログラム動作を引き起こす
説明
この欠陥は、POSIX 標準によると非同期安全ではない関数を信号ハンドラーが呼び出した場合に発生します。非同期安全な関数は、実行中のどの時点でも割り込んで再度呼び出すことができ、不整合な状態を発生させません。また、不整合な状態の可能性があるグローバル データを正しく処理できます。
信号ハンドラーで、非同期安全ではない関数を呼び出す別の関数を呼び出す場合、その信号ハンドラーの関数呼び出しに欠陥が表示されます。欠陥のトレースバックには、信号ハンドラーから非同期安全ではない関数までの絶対パスが表示されます。
リスク
信号ハンドラーが呼び出されたときに、プログラムの実行が割り込まれます。ハンドラーが終了した後、割り込まれた箇所からプログラムの実行が再開します。関数が非同期安全ではない限り、割り込み時に関数が実行中の場合、信号ハンドラーからのその関数の呼び出しは未定義の動作です。
修正方法
POSIX 規格では、次の関数を非同期安全として定義しています。信号ハンドラーから次の関数を呼び出すことができます。
_exit() | getpgrp() | setsockopt() |
_Exit() | getpid() | setuid() |
abort() | getppid() | shutdown() |
accept() | getsockname() | sigaction() |
access() | getsockopt() | sigaddset() |
aio_error() | getuid() | sigdelset() |
aio_return() | kill() | sigemptyset() |
aio_suspend() | link() | sigfillset() |
alarm() | linkat() | sigismember() |
bind() | listen() | signal() |
cfgetispeed() | lseek() | sigpause() |
cfgetospeed() | lstat() | sigpending() |
cfsetispeed() | mkdir() | sigprocmask() |
cfsetospeed() | mkdirat() | sigqueue() |
chdir() | mkfifo() | sigset() |
chmod() | mkfifoat() | sigsuspend() |
chown() | mknod() | sleep() |
clock_gettime() | mknodat() | sockatmark() |
close() | open() | socket() |
connect() | openat() | socketpair() |
creat() | pathconf() | stat() |
dup() | pause() | symlink() |
dup2() | pipe() | symlinkat() |
execl() | poll() | sysconf() |
execle() | posix_trace_event() | tcdrain() |
execv() | pselect() | tcflow() |
execve() | pthread_kill() | tcflush() |
faccessat() | pthread_self() | tcgetattr() |
fchdir() | pthread_sigmask() | tcgetpgrp() |
fchmod() | quick_exit() | tcsendbreak() |
fchmodat() | raise() | tcsetattr() |
fchown() | read() | tcsetpgrp() |
fchownat() | readlink() | time() |
fcntl() | readlinkat() | timer_getoverrun() |
fdatasync() | recv() | timer_gettime() |
fexecve() | recvfrom() | timer_settime() |
fork() | recvmsg() | times() |
fpathconf() | rename() | umask() |
fstat() | renameat() | uname() |
fstatat() | rmdir() | unlink() |
fsync() | select() | unlinkat() |
ftruncate() | sem_post() | utime() |
futimens() | send() | utimensat() |
getegid() | sendmsg() | utimes() |
geteuid() | sendto() | wait() |
getgid() | setgid() | waitpid() |
getgroups() | setpgid() | write() |
getpeername() | setsid() |
上の表にない関数は非同期安全ではありません。信号ハンドラーから呼び出さないようにします。
例
結果情報
グループ: プログラミング |
言語: C | C++ |
既定値: オフ |
コマンド ライン構文: SIG_HANDLER_ASYNC_UNSAFE
|
影響度: Medium |
バージョン履歴
R2017b で導入