pointer to struct. Segmentation fault on read value of member
I’m trying to map some area of the physical memory and then put it in struct. Mapping is OK and the assignment is OK. ( I think so, because there is no segmentation fault.) The problem is when I try to read some value from the struct.
My struct is something like this:
struct some_struct { unsigned long a; unsigned long b; unsigned long c; unsigned long d; unsigned long e; unsigned long f; };
Then I map the memory:
void *pc = (void *) mmap(0, PageSize * 2, PROT_READ | PROT_WRITE, MAP_SHARED, fd, addr_start);
Don’t look too closely at the parameters. I’m 100% sure that this works fine. After that I do this:
struct some_struct *ptr = ((struct some_struct *)(pc + some_offset));
Then I try:
printf("DDR[%p] -> 0x%xn", &(ptr->a));
And I get the address of the member. It points at physical address in the memory. But the following gets me segmentation fault:
printf("DDR[%p] -> 0x%xn", &(ptr->a), ptr->a);
I’m not sure if I have to use physical of virtual address when I assign the struct. Or I’m missing something very obvious.
Answer
It’s not enough of your code to give a full help.
I can provide only possible problems, that you can have in your code:
From man mmap
:
1) If you want to read and write, you should have open("./file.txt", O_RDWR);
in your code.
The prot argument describes the desired memory protection of the mapping (and must not conflict with the open mode of the file).
2) You offset must
be k*sysconf(_SC_PAGE_SIZE)
.
On my system, for example, the page size is 4096
. So your addr_start
must be like 4*4096
, but not like 12
or an any arbitrary number.
offset must be a multiple of the page size as returned by sysconf(_SC_PAGE_SIZE)
3) Compile your code with all warnings enabled and see what compiler will write to you. If you use gcc
, than add -Wall
flag. You already have an undefined behavior in your printf
statement (this was already mentioned in the comments) and with -Wall
compiler will tell you about it.
4) If you still want compile without -Wall
flag, then ensure that you have all needed headers included to your program. I’ve included:
//mmap #include <sys/mman.h> //printf #include <stdio.h> //open #include <stdlib.h> #include <sys/types.h> #include <fcntl.h> //sysconf #include <unistd.h>
Hope this will help.
P.S. I’ve saw that you have solved your problem already just after I’ve wrote this post (but I still do not understand your problem). So I just leave this in case anyone other fill have similar behavior, but the different problem.