1

JNI ライブラリに次のコードがあります。これは、ARM アーキテクチャと x86 アーキテクチャの両方で、Linux (32 および 64 ビット) で期待どおりにコンパイルおよび動作します。簡潔にするために、一部のエラー チェックとその他のコードを削除しました。

  // Globals:
  //
  // uint8_t *g_assets (initialised to NULL)
  // uint32_t g_nextIndex (initialised to 0)
  //
  // Parameters:
  //
  // uint32_t size (number of extra bytes to allocate)

  // Try and reallocate the array to fit the new data
  uint8_t *pNew = (uint8_t *)realloc(g_assets, g_nextIndex + size);
  if(pNew==NULL)
    return -1;
  g_assets = pNew;

OS/X では、realloc() の呼び出しは成功しますが (NULL は返されません)、g_assets の内容にアクセスしようとすると、次のようなメッセージが表示されます。

Invalid memory access of location 0x72911f20 rip=0x7fff90b35fd7

ポインターの値を表示するためにいくつかの printf ステートメントを追加すると、ポインターは 32 ビット値として返されるか、最上位 32 ビットが設定された 64 ビット値として返されるように見えます (例: 0xffffffffcb41cc80)。

コードを次のように少し変更しました。

  void *pBuffer;
  if(g_assets==NULL)
    pBuffer = malloc(size);
  else
    pBuffer = realloc(g_assets, g_nextIndex + size);
  if(pBuffer==NULL)
    return -1;
  g_assets = pBuffer;

最初の呼び出しでは、malloc() 呼び出しは完全な 64 ビット ポインターを返します (また、メモリへの書き込みによって無効なメモリ アクセスがトリガーされることはありません) が、後続の realloc() を呼び出してバッファのサイズを拡張しようとすると、次のような同じ問題が発生します。前。テスト中に生成したサンプル デバッグ出力は次のとおりです。

// Add first item, 32 bytes long
addAsset: g_assets = 0x0, g_nextIndex = 0, size = 32
addAsset: pBuffer = 0x7f8372912260, g_assets = 0x7f8372912260, g_nextIndex = 0, size = 32
// Add second item, 450 bytes long
addAsset: g_assets = 0x7f8372912260, g_nextIndex = 32, size = 450
addAsset: pBuffer = 0x72911f00, g_assets = 0x72911f00, g_nextIndex = 32, size = 450

ご覧のとおり、 realloc() は何らかの理由でポインターを 32 ビットに切り捨てているようです。これは非常にイライラしているので、どんな助けもいただければ幸いです。

私の環境:

daphne:java shane$ gcc --version i686-apple-darwin11-llvm-gcc-4.2 (GCC) 4.2.1 (Apple Inc. ビルド 5658 に基づく) (LLVM ビルド 2336.9.00)

daphne:java shane$ java -version Java バージョン "1.6.0_51" Java(TM) SE ランタイム環境 (ビルド 1.6.0_51-b11-457-11M4509) Java HotSpot(TM) 64 ビット サーバー VM (ビルド 20.51-b01- 457、混合モード)

C コードは、autoconf/automake によってコンパイルされています。

4

1 に答える 1

0

この問題は、realloc()、malloc() などの正しいプロトタイプを取得するためにインクルードに失敗していました。それを追加すると、問題が解決しました。これを指摘してくれた Wiz と tristopia に感謝します。

なぜこの問題が OS/X でのみ発生したのかはまだはっきりしていません (そのため、もっと複雑な問題があるのではないかと思いました)。

于 2013-08-07T09:52:53.427 に答える