なぜ Segumentation Fault は SIGSEG'V' と表現するの?


こんにちは。久々のブログ投稿です。たまたま Cloudflare のブログ記事を読んでいたら、確かに言われてみればどうして? と思ったタイトルの記事「Why is there a “V” in SIGSEGV Segmentation Fault?」という記事がありました。なるほどなぁと思ったのでかるく翻訳したものを紹介します。(ガバ翻訳なので間違っていたりする場合は、原文をお読みください)

ちなみに Segmentation Fault はよくC言語やC++言語などでコードを書いているとよくでてくるやつで、コンソールではこんな感じででてきますよね?

$ clang skynet.c -o skynet
$ ./skynet.out 
Segmentation fault (core dumped)

よくある例だと、`確保したメモリ領域以上にアクセスしたときに発生します。プログラムはSIGSEGVシグナルを受信して、「Segmentation fault」と出力して死んでしまいます。さて、「Segmentation fault」はなぜSIGSEGVと表すのでしょうか? Linux開発者が間違えたのでしょうか? それとも読み方を間違えていて、本当は「Segmentation Valut」なのでしょうか。

Segmentation Violetion の略だった

初めに考えられる可能性として、「Segmentation Violation」 を表していたものが、そのまま使われているのでないか? というものです。

遥か昔、コンピュータにおけるメモリ管理は、セグメント方式が使われていました。 この仕組みでは各メモリセグメントが、事前に定めたサイズの領域を持っておりそれを Segmentation Limit と呼んでいました。 この制限を超えてデータにアクセスしようとすると、プロセッサ違反が引き起こされます。このエラーコードはページング方式を利用した新しいシステムにも引き継がれました。つまり今でもこの違反がトリガーされると、SIGSEGVシグナルとしてユーザー空間に報告され、コンソール上に表示されている、という仕組みです。

SIGSEG が時を経て SIGSEGV になった

別の可能性としては、古い第6版のUNIXドキュメントにおける「シグナル」の章に答えがありました。これは1978年頃のものです。

sigsegv

よくみてみると、SIGSEGVはなく、シグナルナンバー11 (Segmentation Violation を表している) は、SIGSEG になっています。

UNIXツリーのユーザー空間部分 (/usr/include/signal.h など) は、かなり早い段階でSIGSEGVに切り替えられたようです。しかしカーネル空間では長い間、SIGSEGと言う名前が利用され続けました。

PDP11 1 のトラップベクターには、「Segmentation Violation」と言う単語が使われていました。これは、UNIXヒストリーリポジトリの Research V4エディションにありますが、V4で導入されたと表しているわけではありません。というのも、V4が現存する最初のバージョン 2 なのです。このトラップは、SIGSEGという名前に trap.c 内で書き換えられていました。

Research V7 のツリーでは、 /usr/include/signal.h に SIGSEGV という名前 があります。しかしカーネルでは、SIGSEG という名前が利用されています。カーネルでは、BSD-4のときにSIGSEGVに改名されました。

つまり、元々はこのシグナルは、SIGSEGと呼ばれていましたが、時を経つにつれ、SIGSEGVに改名され、1980年代以降はSIGSEGVがユーザー空間でもカーネル空間でも利用されてきた、というわけです。

OS timelines (UNIXのリリース変遷)

まとめ

おそらくどちらも、Cloudflareのエンジニアたちの推測にすぎないのですが、どちらも説得力のある理由だな、と思います。 とくにUNIXのコードツリーはヒストリリポジトリとしてGitHubに残されていたのですね。それは知らなかったです。


  1. PDP11 とは何ぞや? と思い調べたところ、1970年代にあった16ビットのミニコンピューターだそうです。 ↩︎

  2. このリポジトリの作成者の論文 によれば、Research-V1 から存在しており、GitHubにも公開されているのでもしかするとさらに古いコードにその変遷が隠されているのかもしれません。筆者はリポジトリをクローンしましたが、1.3GBと大きすぎて調べるのを諦めました。 ↩︎