多くの低レベルのソケット作業を行う iOS アプリがあり、最近 IPv6 サポートを追加した後、アプリの実行時にカーネル パニックが時々発生することに気付きました。デバイス全体が再起動し、多くの不可解な情報 (アプリからのスタック フレームがないことを含む) を含むパニック ファイルを取得しますが、ここに示すようにいくつかの重要な情報が含まれています。
panic(cpu 0 caller 0xffffff800f15fba0): assertion failed: se->se_flags & SEF_ATTACHED, file: /SourceCache/xnu/xnu-2784.30.7/bsd/kern/uipc_socket.c, line: 6228
Debugger message: panic
幸いなことに、このモジュールはオープン ソースであり、近いバージョンのコードを見つけました: http://opensource.apple.com//source/xnu/xnu-2782.1.97/bsd/kern/uipc_socket.c
エラーはこの関数と一致しているようです:
void
sockaddrlist_remove(struct sockaddr_list *sl, struct sockaddr_entry *se)
{
VERIFY(se->se_flags & SEF_ATTACHED);
se->se_flags &= ~SEF_ATTACHED;
VERIFY(sl->sl_cnt != 0);
sl->sl_cnt--;
TAILQ_REMOVE(&sl->sl_head, se, se_link);
}
基本的にアサートである最初の VERIFY() が失敗していると確信しています。
ただし、これは、このコードが実行される前に、一部のメモリがプログラムによって破損した可能性があることを示しています。そのため、ほとんどのメモリ破損と同様に、原因を突き止めるのは非常に困難です。
ログに基づいて、これは、socket()、connect()、read()、write() などのネットワーク呼び出しの後に発生することがわかりますが、ここでコードを示すことは現実的ではありません。
別の情報として、これは IPv6 でのみ発生します。IPv4 では、すべて問題なく動作します。しかし、私は IPv6 コードをスクラブしましたが、明らかに間違っているものは見つかりませんでした。また、ユーザー空間でのメモリ破損の問題がどのようにカーネルを失敗させるのか混乱しています。これがどのように発生するかを理解すると、問題を追跡するのに役立つかもしれません。
ほとんどの人が言う次のステップは、guard malloc を試すことですが、残念ながらそれをオンにしようとすると別の問題が発生するので、今のところ、guard malloc を使用できないと仮定します。
また、実行中にライブでプログラムにアタッチしてクラッシュさせようとしましたが、デバッガーで停止せず、デバイス全体 (iPad) を再起動するだけです。
このトリッキーなバグのトリアージのアイデアがある場合は、お知らせください。
編集:
回答の 1 つからのフィードバックに基づいて、関連するソケット API 呼び出しのすべての長さを確認しましたが、それらは正しいようです。したがって、ここには別の問題があり、おそらくメモリが上書きされているようです。
「Malloc Guard Edges」を使用してみることができましたが、問題が発生しなくなりました。「Guard Malloc」はシミュレーターでしか動作しないため使用できません。また、ハードウェアとのやり取りが原因で、アプリがシミュレーターでうまく動作しません。
誰かもっとアイデアがあれば、私に知らせてください。