2

ユーザー空間でプログラムをデバッグしていて、SIGSEGVfor と思われる for a ポインターを受け取っています0xffffffff

0xffffffff有効なポインタアドレスかどうか知りたい??

私はGDBを使用しました.以下はコードのリストです:

1414
1415        /* convert object handle */
1416        file = (PSLhandle_t*)hFile;
1417
1418        /* param check */
1419        if(file->hobject.fdesc == 0)   <----------------- it may be crashing here
1420            return INVALID_SET_FILE_POINTER;





----------------- during debugging---------------------------


1412        if((hFile == NULL) || (lpBuffer == NULL))
(gdb) s
1419        if(file->hobject.fdesc == 0)
(gdb) print file
No symbol "file" in current context.
(gdb) print hFile
$1 = (HANDLE) 0xffffffff
(gdb) s

Program received signal SIGSEGV, Segmentation fault.
WriteFile (hFile=0xffffffff, lpBuffer=0xb7f69294, nNumberOfBytesToWrite=65516, lpNumberOfBytesWritten=0xb3933238,
    lpOverlapped=0x0) at PSLWinWrapper.c:1419
1419        if(file->hobject.fdesc == 0)

Linux を使用しています。

[root@DellB アプリ]# uname -a Linux DellB 2.6.23.1-42.fc8 #1 SMP 2007 i686 i686 i386 GNU/Linux

については既に確認済みですNULL

/* param check */
if((hFile == NULL) || (lpBuffer == NULL)) <-------- CHECKED ALREADY FOR NULL
    return INVALID_SET_FILE_POINTER;

/* convert object handle */
file = (PSLhandle_t*)hFile;

/* param check */
if(file->hobject.fdesc == 0) <-------------- CRASH HERE
    return INVALID_SET_FILE_POINTER;

0xffffffff有効なポインタアドレスかどうか知りたいですか? ユーザー空間のLINUXでポインターが有効であることを検証できるAPIはありますか。

4

3 に答える 3

4

少なくとも32 ビット システムで0xffffffffは、.INVALID_HANDLE_VALUE

多くの Windows API 関数INVALID_HANDLE_VALUEは、エラーが発生したことを示すために戻ります。たとえば、CreateFileドキュメント ( source ) から:

戻り値

関数が成功した場合、戻り値は、指定されたファイル、デバイス、名前付きパイプ、またはメール スロットへの開いているハンドルです。

関数が失敗した場合、戻り値はINVALID_HANDLE_VALUEです。拡張エラー情報を取得するには、 を呼び出しますGetLastError

一般に、任意のポインター値NULL. しかし、多くのオペレーティング システムと言語ランタイムは、無効なページ用に 0 に近いスペースを予約しています。これは、プログラマーがNULL. このスペースは両方向に拡張でき、その場合は0xffffffff32 ビット システムに含まれます。また、C/C++ システムのオブジェクトは にアドレスを持つことはありませんNULL(したがって、 に何かがある場合はNULL、そのままにしておくのがおそらく最善です)。

2 番目の質問:はい、ポインタが Linux で有効なメモリを指しているかどうかを確認する方法があります (これは「有効なポインタ」とは少し異なる概念です)。ポインターを逆参照して、プログラムのセグメンテーション フォールトが発生するかどうかを確認します。シグナル ハンドラーをインストールして障害をキャッチし、ロング ジャンプを使用してシグナル ハンドラーから戻ります。

于 2012-05-07T04:14:28.817 に答える
2

NULL無効なポインタ値はこれだけではありません。
一般に、通常の方法 (変数のアドレスや の戻り値など) のいずれかで取得されなかったポインターへのアクセスは、malloc未定義の動作です。これは、アクセスするとクラッシュするという意味ではありませんが、クラッシュする可能性があることを意味します。

したがって、テストしNULLてもポインターが有効であることは保証されません。

具体的に0xffffffffは、ほぼすべての一般的なプラットフォームでは無効です。
それが有効で、メモリ内の最後のバイトを指している場合でも、次のバイトが address0にあるため、この 1 バイトしかアクセスできません。これは確かに無効です。

于 2012-05-07T06:18:31.860 に答える
0

具体的には、0xffffffff は 32 ビット符号付き整数 -1 の符号なし値です。この問題の原因として考えられるのは、hFile の値を返す関数が間違って -1 を返すことです。ほとんどの正常なプログラムは、戻り値の型がポインターの場合、エラー時に整数値 0 を持つ NULL を返します。この場合は例外かもしれません。hFile が最初に割り当てられた場所を示すことができますか?

于 2012-05-07T05:16:59.000 に答える