0

glibc で奇妙な動作が見られます。コードには、ランダムなポインタをfclose()に渡すというバグがありました。この時点でクラッシュすると予想していましたが、代わりにpthread_once()でハングし、以下のバックトレースが発生します。プログラムはスレッドを使用しません。

#0  0x000000318180ca38 in pthread_once () from /lib64/libpthread.so.0
#1  0x0000003181109d1c in backtrace () from /lib64/libc.so.6
#2  0x0000003181075d34 in __libc_message () from /lib64/libc.so.6
#3  0x000000318107c6fc in malloc_consolidate () from /lib64/libc.so.6
#4  0x000000318107d719 in _int_malloc () from /lib64/libc.so.6
#5  0x0000003181080a4a in calloc () from /lib64/libc.so.6
#6  0x0000003180c0b0df in _dl_new_object () from /lib64/ld-linux-x86-64.so.2
#7  0x0000003180c061ac in _dl_map_object_from_fd () from /lib64/ld-linux-x86-64.so.2
#8  0x0000003180c08563 in _dl_map_object () from /lib64/ld-linux-x86-64.so.2
#9  0x0000003180c13861 in dl_open_worker () from /lib64/ld-linux-x86-64.so.2
#10 0x0000003180c0f304 in _dl_catch_error () from /lib64/ld-linux-x86-64.so.2
#11 0x0000003180c131eb in _dl_open () from /lib64/ld-linux-x86-64.so.2
#12 0x00000031811305d2 in do_dlopen () from /lib64/libc.so.6
#13 0x0000003180c0f304 in _dl_catch_error () from /lib64/ld-linux-x86-64.so.2
#14 0x0000003181130692 in __libc_dlopen_mode () from /lib64/libc.so.6
#15 0x0000003181109c05 in init () from /lib64/libc.so.6
#16 0x000000318180ca40 in pthread_once () from /lib64/libpthread.so.0
#17 0x0000003181109d1c in backtrace () from /lib64/libc.so.6
#18 0x0000003181075d34 in __libc_message () from /lib64/libc.so.6
#19 0x000000318107d0b8 in _int_free () from /lib64/libc.so.6
#20 0x000000318106ba6d in fclose@@GLIBC_2.2.5 () from /lib64/libc.so.6

これはglibc-2.17-20.fc19.x86_64を使用する Fedora 19 であり、プログラムは を使用して systemd から開始されるため、 __libc_message()がエラー メッセージを出力するStandardError=null場所がありません。

コードを修正しましたが、これは glibc のバグによるものですか?

4

2 に答える 2

3

もちろん、これは glibc のバグではありません。ルールに違反しているため、発生した動作が発生する可能性があります。マニュアルページには次のように書かれています:

どちらの場合でもfclose()、ストリームへのさらなるアクセス ( への別の呼び出しを含む) は、未定義の動作を引き起こします。

未定義の動作をトリガーしたときに何が起こるかについて、何らかの形で期待することは正式には間違っています。振る舞いはundefinedです。つまり、何が「正しく」何が「間違っている」か誰も言えません。

正確な理由については、基本的に glibc の実装者のみが関心を持っています。とはいえ、この回答は説明を示唆しています。スレッドセーフであるため、ミューテックスが含まれてfclose()いることが期待されます。FILE割り当て解除された構造体を渡しているため、ライブラリがランダムながらくたデータをミューテックスとして使用し、ロックアップします。かなり合理的です。

于 2014-07-04T09:43:37.150 に答える
1

最近、同様のバックトレースをチェックしていますが、これは glibc のバグであり、Ubuntu 8.04 から少なくとも 7 年間存在していると思います。

基本的に、これはメモリ破損が発生した後に発生し、残念ながら、__libc_message 自体がメモリを割り当てます。ヒープが破損しているため、再度バックトレースを試みます。最後に、pthread_once() でデッドロックが発生します。

=EDITED= この問題のトラッカーを見つけましたが、マスター ブランチでのみ修正されているようです。 https://sourceware.org/bugzilla/show_bug.cgi?id=16159

于 2015-07-20T02:35:55.007 に答える