1

次のコードを使用します。

typedef struct
{
    char    fileName[ 1024];
    time_t  deleteTime; 
} file_item_t;

....
....

setEntry(char *fileName)
{
    file_item_t     file;

    memset( &file, 0x00, sizeof( file_item_t ));

    memcpy( file.fileName, 
         fileName, 
         sizeof( file.fileName ) - 1 );
...
...

関数が呼び出されると、SPARCマシンでは正常に実行されますが、Solaris10を実行しているi386でのsegfaultsは fileName約30文字のヌル文字で終了します。fileName使用範囲を超えて読み取ろうとすると、memcpy()一部のシステムでセグメンテーション違反が発生するようです。

これはレガシーコードであり、簡単に修正できます。しかし、私が知りたいのは、これが失敗するかどうかにつながる可能性のある根本的な特性についてです。スタックの読み取り違反に関連していますか?いくつかの境界交差?これはメモリセグメンテーションに関連しており、失敗するかどうかは偶然です(メモリセグメンテーション/ページングがメモリ管理とOSによってどのように行われるかによって異なります)。

4

3 に答える 3

5

あなたはすでに頭に釘を打ちました:

memcpyで、ファイル名の長さを超えて読んでいます。

また、ファイル名の背後にあるメモリが読み取り可能である場合によく機能するダーティ。ほとんどの場合はそうですが、たとえば文字列リテラルを引数として渡し、リンカーが文字列をデータセクションの最後のキロバイトに配置すると、CPUがメモリから読み取ろうとするため、セグメンテーション違反が発生します。プロセスのアドレス空間にマップされていない場所。

明らかな修正は、strcpyまたはstrncpyを使用することです。

于 2008-10-10T10:33:57.297 に答える
1

が指す文字列fileNameの長さが実際には1024バイトであることを確認しますか?どういうわけか、memcpyの代わりにstrcpyを使用する必要があると感じています。

fileNameが短い場合、memcpyは実際の文字列データの背後にあるバイトをコピーし、おそらくそのメモリを読み取るアクセス違反を引き起こします。

于 2008-10-10T10:31:01.263 に答える
1

char *filename与えられた情報では、引数がどこを指しているのかわかりません- スタック、ヒープ、データセクション、またはその他...

スタック上にある場合は、SPARC のデフォルトのスタック サイズが x86 よりもはるかに大きく、さらに大きくなることが原因である可能性があります。SPARC ABI により、スタック フレームには常に 16 個のレジスタすべてをバックアップするためのスペースがあり、さらに関数が必要とする場合は 6 つのパラメーター用のスペースがあります (必要なパラメーターが少なくても)。したがって、SPARC は関数呼び出しごとに少なくとも 64 または 92 バイトのスタックを消費しますが、x86 は関数呼び出しごとにわずか 8 または 4 バイトで済みます。

ヒープ上またはデータ セクション内にある場合は、ランタイム (ヒープ) またはコンパイラ (データ) がたまたま x86 のページの末尾近くに文字列を配置する可能性があるため、末尾から実行すると読み取り不良になる可能性があります。メモリー。

于 2008-10-10T14:54:27.803 に答える