Memcpy segmentation fault on linux but not os x

I am working on implementing a log based file system for a file as a class project. I have a lot of work on my OS X 64-bit laptop, but when I try to run code on 32-bit Linux machines in the CS department, I get a seg error.

The API provided allows you to write DISK_SECTOR_SIZE (512) bytes at a time. Our log entry consists of 512 bytes that the user wants to write, as well as some metadata (in which sector he wants to write, such as operation, etc.).

In total, the size of the โ€œrecordโ€ object is 528 bytes, which means that each journal entry covers 2 sectors on the disk.

The first record records 0-512 in sector 0 and 0-15 in sector 1. The second record records 16-512 in sector 1 and 0-31 in sector 2. The third record records 32-512 in sector 2 and 0-47 in sector 3 . ETC.

So, what I'm doing is reading two sectors, which I will change in 2 freshly defined buffers, copying from the write to buf1 + the calculated offset for bytes with 512 offsets. This works correctly on both machines.

However, the second memcpy fails. In particular, "record + DISK_SECTOR_SIZE-offset" in the segfaults scripts below, but only on the linux machine. Performing some random tests, becomes more curious. The linux machine reports sizeof (Record) as 528. Therefore, if I tried memcpy from writing + 500 to buf for 1 byte, it should not have a problem.

In fact, the largest offset that I can get from the record is 254. That is, memcpy (buf1, record + 254, 1) works, but memcpy (buf1, record + 255, 1) segfaults.

Does anyone know what I am missing?

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)); 
+4
source share
4 answers

When you add 1 to the pointer p, you are not adding 1 byte, you are adding sizeof (p) bytes.

So, in this case, before adding to it, you need to add a record to char* . Right now, record+500 actually points to 500 * 528 = 264,000 bytes away from record .

Of course, this does not explain why memcpy(buf, record+254, 1) not segfault. Just lucky, I think.

+10
source

record+BLAH means that when converting to machine code: add BLAH*sizeof(Record) to the address in record .

So record+500 not 500 bytes from record ; this is 500 * 528 = 264000 bytes from record .

+3
source

Try running Linux code under valgrind - this should lead you to the root cause of the problem.

+2
source

record + DISK_SECTOR_SIZE-offset is your problem. record + 1 does not give record address + 1.

It gives you the record address + 1 * sizeof (record). (when you increase or decrease the pointer, it performs the multiplicity of the data type you are using. Just enter the record pointer like this: (byte *) record + DISK_SECTOR_SIZE-offset. This will explain the segmentation error, since the record lasts at least DISK_SECTOR_SIZE.

0
source

Source: https://habr.com/ru/post/1306390/


All Articles