3

[この問題は解決しました。以下の最後のコメントをご覧ください。]

私のアプリケーションでは、Doug Lea の dlmalloc に基づいて、独自の特別な malloc を使用する必要があります。(mmap を使用して) 匿名ファイルをマップし、マップされたファイルの一部から mspace を作成し、mspace を mspace_malloc に渡します。mspace_malloc が返すアドレスの一部が、マップされたファイルの境界内にないことがわかりました。ただし、私が知る限り、プロセスは malloc されたメモリに正常に読み書きできます。この動作が発生するのはなぜですか? また、mspace_malloc が mspace の範囲内のアドレスを返すように強制するにはどうすればよいですか?

/* Inside dl_malloc.c */

#define ONLY_MSPACES 1
#define MSPACES 1

void * heap;
off_t heap_length;
mspace ms;

void init(size_t size) {
  heap = mmap(NULL, size, PROT_READ | PROT_WRITE, MAP_PRIVATE | MAP_ANONYMOUS, -1, 0);
  if (heap == MAP_FAILED) {
    perror("init: mmap");
    exit(EXIT_FAILURE);
  }
  heap_length = size;
  ms = create_mspace(heap, size, 0);
  mspace_track_large_chunks(ms, 1);
}

void * my_malloc(size_t bytes) {
  return mspace_malloc(heap, bytes);
}
/************************/


/* In application */
#include <stdio.h>
#include <stdlib.h>
#define HEAP_SIZE 0x10000  // 32 pages
#define ROWS 2
#define COLS 4096

extern void init(void);
extern void * my_malloc(size_t bytes);

extern void * heap;
extern off_t heap_length;

int main(void) {
  init(HEAP_SIZE);
  int ** matrix = (int **)my_malloc(sizeof(int *) * ROWS);
  int i;
  for (i = 0; i < ROWS; ++i)
    matrix[i] = (int *)my_malloc(sizeof(int) * COLS);

  printf("Heap bounds: %lx to %lx\n",
    (off_t)heap, (off_t)heap + heap_length);
  printf("Matrix: %p  ", matrix;
  for (i = 0; i < ROWS; ++i)
    printf("Matrix[%d]: %p  ", i, matrix[i]");
  printf("\n");

  return EXIT_SUCCESS;
}

このプログラムを実行すると (上記は単純化されたものですが、大したことではありません)、matrix に割り当てられたアドレスはヒープに対して出力された境界内にあることがわかりますが、2 つの行の 2 つのアドレスははるかににあります。下限 -- 0x100000000 を超えています! それでも、マトリックスの読み取りと書き込みができるようです。この最後のポイントは不可解で理解したいと思っていますが、より緊急の問題は、my_malloc が返すすべてのアドレスがヒープ境界内にあることを確認するために何かをする必要があるということです。これは、アプリケーションの他の部分がこれを必要とするためです。

ところで、このプログラムでは 1 つのスレッドしか使用していないため、create_mspace への呼び出しをロックする必要がないことに注意してください。とにかく、この引数を 1 に設定してみましたが、結果に違いは見られませんでした。

ありがとう!

4

1 に答える 1

3

エウレカ(笑)!上記の単純化された例は、指定された定数を使用して正しく機能し、返されるアドレスは範囲内になります。ただし、元の mspace に比べて大きすぎるサイズで my_malloc を呼び出すと、malloc は mmap を呼び出します (これを明示的に無効にしない限り)。私が見たアドレスは、mmap への呼び出しの結果として返されたものにすぎません。したがって、この謎の解決策はかなり単純であることが判明しました。他の人がたまたまこの問題に遭遇し、malloc の mmap への呼び出しを忘れた場合に備えて、私はこれを投稿したままにします。

于 2011-12-17T23:57:47.613 に答える