O_CREAT を使用する sem_open が、時には EBADF で失敗するマルチスレッドプログラムがあります。これはNXPのARM Linux 4.9.88組み込みデバイスにあります。
再現するのは非常に難しいですが、ファイルを作成するときに2つのスレッドが同じファイル記述子を受け取るように見えるstrace状況を見つけました(1つはsem_open内のopenat()のものであり、もう1つはスレーブパイプライン2によって返された読み取り終わり)。ファイルとパイプラインが同時に存在します。
strace(pid 266はsem_openを呼び出すスレッド、pid 268はpopenを呼び出す別のスレッドです)は次のことを報告します。
[pid 266] openat(AT_FDCWD, "/dev/shm/pPC113", O_RDWR|O_CREAT|O_EXCL, 0777 <unfinished ...>
[pid 268] close(12) = 0
[pid 268] mq_timedreceive(10, "\0\0\0\0\1g\7\0", 8, NULL, NULL) = 8
[pid 266] <... openat resumed> ) = 12
[pid 268] pipe2([12, 13], O_CLOEXEC) = 0
openat()とパイプライン2()は異なる記述子を返す必要がありますが、記述子12を返します。
次に sem_open は記述子 12 への書き込みを試み、EBADF を受け取ります。それはおそらく記述子12が生成されたファイルではなく、パイプの読み取りの終わりだからです。
これは私にとって明らかなカーネルバグのようです。オープンとパイプラインの両方が同じファイル記述子を返します。これが既知のバグで、将来のバージョンのカーネルで修正されたかどうかを知っている人はいますか?