Skip to content

Instantly share code, notes, and snippets.

@kosaki
Created January 4, 2013 17:57
Show Gist options
  • Save kosaki/4454576 to your computer and use it in GitHub Desktop.
Save kosaki/4454576 to your computer and use it in GitHub Desktop.
glibcでrealloc(ptr, 0)とわたしたときに、mtraceのログがおかしいというバグがあってその議論が面白かったのでご紹介。
<a href="http://sourceware.org/bugzilla/show_bug.cgi?id=14981" target="_blank" title="http://sourceware.org/bugzilla/show_bug.cgi?id=14981">http://sourceware.org/bugzilla/show_bug.cgi?id=14981</a>
reallocという関数がある。まあ、みなさんよくご存知のように realloc(ptr, size)とわたしたときにptrをsizeの大きさに拡張(縮小)してくれる関数である。
malloc(0)がNULLを返しても非NULLを返してもいいように、realloc(ptr, 0)も挙動に実装の自由度がある
1.realloc(ptr, 1) と同等(mallocが非NULLを返すケースではこれが普通)
2.ptrは解放され、NULLが返る(mallocがNULLを返すケースでは常識的な挙動)
3.ptrは解放されず、NULLが返る(mallocがNULLを返すケースでは同じくらい常識的な挙動、malloc(0)をエラーとみなす哲学だと関数の最初に引数チェックをするのは理解できる)
The Austin Group Defect Report #400
<a href="http://www.open-std.org/jtc1/sc22/wg14/www/docs/dr_400.htm" target="_blank" title="http://www.open-std.org/jtc1/sc22/wg14/www/docs/dr_400.htm">http://www.open-std.org/jtc1/sc22/wg14/www/docs/dr_400.htm</a>
によると、AIXとglibcが2、BSD系が3のようである。ところでPOSIXはテキストの書き方がわるくて3しか認めないような文章になってるから規格を直さないといけないんじゃないかな。という議論をしている
で、glibcに戻るとglibc 2.17までの挙動は
・malloc(0)は非NULLを返す(環境によるけど malloc(16)と同じになると思う)
・しかしなぜか realloc(ptr, 0) は free(ptr) と同じ挙動をし、NULLを返す(0サイズのメモリをアロケートしてはくれない)
・そしてmtraceのrealloc hookではrealloc(ptr, 0) で 非NULL が返ってくることを期待していてNULLは全部エラーとして扱っている
という不整合があり、正しくログがとれていなかった。
で、いつものようにみんなで規格書パース合戦を繰り広げた後、Roland McGrath が仲裁にはいって、ログと実際の挙動が違っているのは明らかにバグだから2.18ではmtraceを返る。realloc(ptr, 0)の挙動を変えるかどうかは規格解釈をglibc MLで議論するのがそもそも間違っていて、Austinで議論してから、必要なら変える。このコーナーケース
について変えてはいけないとは思わないが、規格に対する推測をもとに変更はしない。という結論になった。
まあ、順当なところかな。malloc(0)とrealloc(ptr, 0)の挙動が一貫してないのは気持ち悪いけど。
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment