3

これは、自己変更コードで発生する可能性のある命令キャッシュ同期の問題に関連していますか? 昔、質問したことがあります。受け入れられた解決策で関連する問題が解決されたにもかかわらず、機能がオンに戻った後に CPU がジャンク アドレスにジャンプしようとする新しい断続的な障害モードに遭遇しました。しかし、事後の逆アセンブリ (コア ダンプを使用) では、call 命令の正しいアドレスが示されます。

いくつかの gdb 分析が続きます。

Program terminated with signal 11, Segmentation fault.
#0  0x00000000014010d0 in ?? ()
(gdb) bt
#0  0x00000000014010d0 in ?? ()
#1  0x0000000000492e01 in FastPelY_14 ()
#2  0x000000000045d85d in SubPelBlockMotionSearch ()
#3  0x0000000000467a23 in BlockMotionSearch ()
#4  0x0000000000469c99 in PartitionMotionSearch ()
#5  0x0000000000487bf7 in encode_one_macroblock ()
#6  0x0000000000496ccd in encode_one_slice ()
#7  0x0000000000426081 in code_a_picture ()
#8  0x000000000042766f in frame_picture ()
#9  0x000000000042664b in encode_one_frame ()
#10 0x0000000000430a23 in main ()

(gdb) disas /r 0x0000000000492e01
   0x0000000000492dfc <+38>:    e8 cf e2 f6 ff  callq  0x4010d0 
=> 0x0000000000492e01 <+43>:    8b 45 e4    mov    -0x1c(%rbp),%eax

ここで注目すべき興味深い点は、正しいアドレスは 0x4010d0 ですが、失敗した場合のジャンク アドレスは常に0x14010d0であるということです。これは、バックトレースで次の命令を指すように命令ポインターが示されているにもかかわらず、何らかの形で失敗した呼び出し命令だと思います。(それが gdb での適切な動作である可能性があります。よくわかりません)。

その場合、CPU がe8 cf e2 f6 ffではなくe8 cf e2 f6 00を呼び出そうとしたようです。0x0000000000492dfc から始まる呼び出しサイトに最初に存在した 5 バイトのシーケンスは、0x0F1F440000 の 5 バイトの NOP (上部にリンクされた質問で与えられた提案による) です。

ここで何が起こっているのですか?さらにコンテキストが必要な場合はお知らせください。ところで、私は Intel(R) Xeon(R) CPU E5-2670 を使用していますが、動作は私が試した他のいくつかのマシンでも一貫しているようです。

編集:コードは、-O2 最適化レベルで次の追加オプションを使用してコンパイルされています。

-fno-optimize-sibling-calls -finstrument-functions

4

0 に答える 0