1

複数のスレッドを持つ C++ で記述された Windows 7 で実行されているサーバー プロセスがあります。そして、単純な割り当てでランダムなクラッシュが発生しました。次の手順を参照してください。

--- some function without the source:
0136E0F0  mov         eax,dword ptr [esp+8]
0136E0F4  mov         edx,dword ptr [esp+0Ch] 
0136E0F8  push        esi  
0136E0F9  mov         esi,dword ptr [ecx+10h]          << read a member variable to esi
0136E0FC  add         dword ptr [ecx+esi*8+30h],eax    << access violation here!
...
...

奇妙なことに、クラッシュが発生したとき、[ecx+10h] の値は 0 ですが、ESI はゼロ以外の無効な値です! そして、最後の命令が無効なメモリに書き込もうとしています! (クラッシュダンプファイルから確認しました)。つまり、ecx のオブジェクトは有効ですが、レジスタが壊れています!!! たぶん私が間違っているかもしれませんが、スレッドを切り替えるときにOSはすべてのレジスタを保持しますよね?

だから私の質問は、ここで実際に何が起こったのか、そしてそれを修正する方法は?

どうもありがとう。

4

2 に答える 2

1

ecx+10h のデータをいじっている他のコードは何ですか?

メモリから esi への移動と、その後の esi の使用の間には、メモリが変更されたという十分な範囲があります。その場合、esi は適切な値を持つべきであるかのように見えます。

その場所から 0(?) が読み取られた後、別のスレッドまたは割り込みが ecx+10h に有効なものを配置することを想像してみてください。

于 2012-11-08T18:19:33.753 に答える
0

これらの「不可能な」エラーには、かなり一般的な原因があります: ハードウェアの障害。CPU が故障しているか、過熱している可能性があります。

これは、人々が考えているよりも頻繁に発生します。ハードウェアが機能していないか、機能していません。1e10 の機会に 1 つのケースを除いて、ほとんど機能する可能性があります。

于 2012-06-07T12:49:21.303 に答える