0

特定の行でセグメンテーション違反を起こしているプログラムがあります。

uint64_t small_num = *(uint64_t*)(smaller_base+index);

GDB は segfault を正常にキャッチし、問題をデバッグできるようにしました。ただし、GDB プロンプトから次の行を実行すると、メモリ アクセス違反は発生しません。

(gdb) p small_num = *(uint64_t*)(smaller_base+index)

この問題をデバッグする方法について誰か提案できますか? small_base+index のメモリが存在することを確認したため、言葉とアイデアが失われています。キャスティングで何とかなるの?

前もって感謝します。

EDIT:より多くのコードを提供しますが、それは本当に簡単です。索引付けのポイントを示すためにコードを大幅に編集しました。

uint64_t ** find_difference(unsigned char * larger_base,
                              uint64_t size,
                              unsigned char * smaller_base,
                              uint64_t tmap_size)
{
    uint64_t len = size < tmap_size?size:tmap_size;
    uint64_t index=0;
    while(index<len)
    {
            uint64_t larger_num = *(uint64_t*)(larger_base+index);
            uint64_t smaller_num = *(uint64_t*)(smaller_base+index);
            if(larger_num > smaller_num)
            {
                ... do stuff
            }
            index++;
    }

    ...
}

編集#2:私はそれについて考えているので、ポインターの逆参照がlenを超える可能性はありますか?x86 の数値は上位アドレスから下位アドレスの順に格納されるというのが私の理解でした。したがって、メモリでは、数値 0x01020304 は 0x04 0x03 0x02 0x01 として格納されます。これは正しいです?これが真でない場合、参照はバッファの終わりを超えてしまいます。ただし、GDB では、アドレスにアクセスできることを確認しました。

4

2 に答える 2

1

find_difference() 関数の使用方法と関数に渡されるパラメーターの値はわかりませんが、ポインター演算が間違っていると思われます。

large_base と small_base を 1 ずつインクリメントし、結果のアドレスを u64* としてキャストしています。サイズがバイト単位の場合は、large_base+index+8 < サイズであることを確認する必要があります。

于 2013-04-25T19:09:12.983 に答える
0

元のポインタ算術は、 (unsigned char *)にインデックスを追加してから、それをuint64_tにキャストし、整列していないメモリ ロードを引き起こしました。つまり、8 の倍数ではないアドレスから(uint64_t *)を逆参照しようとしました。これはデバッガで機能しますが、プログラムで SEGFAULT が発生します。

于 2013-04-28T21:03:33.963 に答える