1

Moaiのソース コードを読んでいて、なぜこれがクラッシュを引き起こすのか (またはそうでないのか...) に興味を持ちました。

私はそのスニペットを本当に理解していません。

ファイル A:

#define UNUSED(p) (( void )p)

ファイル B:

//----------------------------------------------------------------//
/** @name   crash
    @text   Crashes Moai with a null pointer dereference.

    @out    nil
*/
int MOAISim::_crash ( lua_State* L ) {
    UNUSED(L);

    int *p = NULL;
    (*p) = 0;

    return 0;
}

編集:

私が理解していなかったのは、「敬意」の意味だと思います。だから、あなたの答えにそれを入れたら、それは素晴らしいことです.

4

3 に答える 3

13

クラッシュは、null ポインターの逆参照が原因で発生します。

(*p) = 0; // <--- Crash

また、コメントで指摘されているように、UNUSED マクロは、ほとんどのコンパイラが与える「未使用のパラメーター」警告を抑制するためだけに存在します。

通常、次のように変数名を指定しないだけで、警告を回避することもできます。

int MOAISim::_crash ( lua_State* ) 
{
    int *p = NULL;
    (*p) = 0;

    return 0;
}

上記は保証されたクラッシュではないことにも注意してください。32 ビット コンソールの 1 つで、ヌル ポインターを逆参照すると、実際には数値 "3" が発生しました。これにより、null の逆参照を見つけるのが非常に難しくなりましたが、通常、レジスタに 3 が置かれているのを見れば、何が問題なのかを推測することができます。

逆参照とは、基本的に、特定のポインターに格納されている値を要求することです。ポインタが有効でない場合 (つまり、プロセスが所有していないメモリ位置を指している場合)、クラッシュが発生します。Windows では、これはアクセス違反 (0xC0000005) と呼ばれます。Linux では、これはセグメンテーション違反、SIGSEGV です。

こちらもご覧ください

于 2012-12-05T12:45:46.843 に答える
3

マクロはコードで置き換えられるため、コンパイラの関数は次のようになります。

int MOAISim::_crash ( lua_State* L ) {
    (( void )L);

    int *p = NULL;
    (*p) = 0;

    return 0;
}

行は結果を(( void )L)評価Lして破棄します。ただし、クラッシュはその行によるものではなく、NULLアドレスへの割り当てによるもの(*p) = 0です。

于 2012-12-05T12:47:20.107 に答える
1
int *p = NULL;
(*p) = 0;

2 行目は未定義の動作です (nullptr ポインターの逆参照)。プラットフォーム上でアプリケーションがクラッシュするという事実は、未定義の動作の 1 つの形式にすぎません (私の意見では、バグをより早く発見できるので良いと思います)。

于 2012-12-05T13:11:46.237 に答える