Вопрос

Я работаю над реализацией файловой системы на основе журнала для файла в качестве класса. У меня есть хорошее количество его работы на моем 64-битной OS X ноутбуке, но когда я пытаюсь запустить код на 32-битных машинах отдела CS 32-битных Linux, я получаю ошибку SEG.

API, которым мы предоставляем, позволяет написать байты Disk_sector_size (512) одновременно. Наша запись журнала состоит из 512 байтов, которые пользователь хочет написать, а также некоторые метаданные (каким сектором он хочет написать, типом эксплуатации и т. Д.).

В целом размер объекта «Record» составляет 528 байт, что означает, что каждый журнал записи охватывает 2 сектора на диске.

Первая запись пишет 0-512 на сектор 0, а 0-15 по сектору 1. Вторая запись записывает 16-512 на сектор 1, а 0-31 на секторе 2. Третья запись записывает 32-512 на сектор 2, а также 0-47 на сектор 3. И т. Д.

Итак, что я делаю, это прочитать два сектора, я буду изменять на 2 свежевыделенных буфера, скопируйте, начиная с записи в Buf1 + рассчитанное смещение для 512-офсетных байтов. Это работает правильно на обеих машинах.

Однако вторая мемкпи не удается. В частности, «Record + Disk_sector_size-offset» в следующем коду SegFaults, но только на машине Linux. Запуск каких-либо случайных тестов, становится все более любопытно. Машина Linux отчеты SIZEOF (запись), чтобы быть 528. Следовательно, если я попробовал meMcpy из записи + 500 в Buf для 1 байта, у него не должно быть проблемой.

На самом деле, самое большое смещение, которое я могу получить от записи, составляет 254. То есть memcpy (Buf1, запись + 254, 1) работает, но memcpy (BUF1, запись + 255, 1) Segfaults.

Кто-нибудь знает, чего мне не хватает?

Record *record = malloc(sizeof(Record));
record->tid = tid;
record->opType = OP_WRITE;
record->opArg = sector;
int i;
for (i = 0; i < DISK_SECTOR_SIZE; i++) {
  record->data[i] = buf[i]; // *buf is passed into this function
}

char* buf1 = malloc(DISK_SECTOR_SIZE);
char* buf2 = malloc(DISK_SECTOR_SIZE);

d_read(ad->disk, ad->curLogSector, buf1);  // API to read a specified sector into a buffer
d_read(ad->disk, ad->curLogSector+1, buf2);

memcpy(buf1+offset, record, DISK_SECTOR_SIZE-offset);
memcpy(buf2, record+DISK_SECTOR_SIZE-offset, offset+sizeof(Record)-sizeof(record->data));
Это было полезно?

Решение

Когда вы добавляете 1 к указателю P, вы не добавляете 1 байт, вы добавляете BYTES SIZEOF (P).

Так что в этом случае вам нужно бросить record к А. char* перед добавлением к нему. Прямо сейчас record+500 на самом деле очки 500 * 528 = 264 000 байтов вдали от record.

Конечно, это не объясняет, почему memcpy(buf, record+254, 1) не SegFault. Просто «повезло», я думаю.

Другие советы

record+BLAH Средства, когда переведено в машинный код: Добавить BLAH*sizeof(Record) по адресу в record.

Так record+500 не 500 байт от record; Это 500 * 528 = 264000 байтов от record.

Попробуйте запускать свой код Linux под valgrind - это должно поднять вас прямо к исчезновению проблемы.

Запись + disk_sector_size-offset - ваша проблема. Запись + 1 не дает и адрес записи + 1.

Это дает вам и адрес записи + 1 * SizeOf (запись). (Когда вы увеличиваете или уменьшите указатель, который он работает в нескольких шагах данных, введите ваше использование. Просто типографское указатель записи, как так: (байт *) Запись + disk_sector_size-offet. Это объяснило бы ошибку сегментации, поскольку запись не менее Disk_sector_size Отказ

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top