• C

mmap gives segmentation fault

hi,

i have a file that i am trying to mmap.
and i get the error in valgrind

 Invalid read of size 4
==31586==    at 0x8048F06: filec(char*) (test.c:65)
==31586==    by 0x80489D4: main (c1.c:33)
==31586==  Address 0xFFFFFFFF is not stack'd, malloc'd or (recently) free'd
==31586==
==31586== Process terminating with default action of signal 11 (SIGSEGV)
==31586==  General Protection Fault

the reason is because , i am trying to access a value on of the mapped file. it works fine if the file is so much smaller but it shoudl work with large files too..thanks.

zizi21Asked:
Who is Participating?
 
Kent OlsenData Warehouse Architect / DBACommented:
You need to test x, not the dereferenced pointer.

        x = (unsigned int*) mmap(NULL, s, PROT_WRITE|PROT_READ, MAP_SHARED, fp, 0);
        if((int)x == -1)
        {
                fprintf(stderr," No map");
                exit(1);
        }


Sorry -- I missed the casting the first time around.


Kent
0
 
evilrixSenior Software Engineer (Avast)Commented:
Please post the code that goes with this.
0
 
Kent OlsenData Warehouse Architect / DBACommented:
Hi zizi,

The error message indicates that you're trying to read address 0xFFFFFFFF.  Coincidentally, that is -1, the value returned my mmap when the mapping is unsuccessful.

After calling mmap, you should check that the mapping is successful.  ERRNO should contain the reason that the mapping failed.


Good Luck,
Kent
0
Creating Active Directory Users from a Text File

If your organization has a need to mass-create AD user accounts, watch this video to see how its done without the need for scripting or other unnecessary complexities.

 
zizi21Author Commented:
     this is the code

        struct stat sts;
        fp = open(f,0|O_RDWR);
        if(fp == -1)
        {
                fprintf(stderr," No open.");
                exit(1);
        }

        if(fstat (fp, &st) == -1)
        {
                fprintf(stderr, " No status.");
                exit(1);
        }
       
        s = sts.st_size;
        x = (unsigned int*) mmap(NULL, s, PROT_WRITE|PROT_READ, MAP_SHARED, fp, 0);
        if(x == 0)
        {
                fprintf(stderr," No map");
                exit(1);
        }
       
        j = s/sizeof(unsigned int);
       
        printf("x[0] %d\n",x[0]);

this is the code
0
 
Kent OlsenData Warehouse Architect / DBACommented:
I think that you want to test:

        x = (unsigned int*) mmap(NULL, s, PROT_WRITE|PROT_READ, MAP_SHARED, fp, 0);
        if(x == -1)
        {
                fprintf(stderr," No map");
                exit(1);
        }
0
 
zizi21Author Commented:
i tried testing that but i got this error

 error: ISO C++ forbids comparison between pointer and integer

and when i did
*x == -1,

i got segmentation fault.
0
 
zizi21Author Commented:
how do i check errno to find the reason ?
0
 
Kent OlsenData Warehouse Architect / DBACommented:

in the globals block (outside of any function) declare errno.

  extern int errno.


Then print the value of errno if the mapping fails.  The reason codes are in errno.h, which should be in your standard includes directory.


Kent
0
 
zizi21Author Commented:
i checked the errno and it says errno 12 Cannot allocate memory

0
 
zizi21Author Commented:
the mapping failed...how is this possible,...i mean,  i though with mmap , that i could mmap file bigger than the existing ram...
0
 
zizi21Author Commented:
thanks for all the help.
0
 
Kent OlsenData Warehouse Architect / DBACommented:
Is there enough swap space for it?

How big is the file?  It looks like you're trying to map all of it, so it might not hurt to print the key values (like length) as you debug this.


Kent

0
 
zizi21Author Commented:
when i tried printing the value for sts.size, i got a negative value.

but when i did ls -lh, the size of the file 3.2 gb
0
 
Kent OlsenData Warehouse Architect / DBACommented:

Ok.  When you store 3.2GB in an integer, all 32 bits are used.  This overflows into the sign bit so the value that you see printed is negative.

Display the value as an unsigned integer and it should display just fine.

You may be trying to allocate more virtual memory than you have defined.  


Kent
0
 
zizi21Author Commented:
i tried using %ld and i still got negative number
0
 
zizi21Author Commented:
i get the value of the size from struct stat sts.
0
 
Kent OlsenData Warehouse Architect / DBACommented:

%ld formats a long integer.  use %u.

0
 
zizi21Author Commented:
also, the size of the file is larger than the existing ram.
0
 
zizi21Author Commented:
yes, i got a positive number now with %u
0
 
Kent OlsenData Warehouse Architect / DBACommented:

How large is the swap file?
0
 
zizi21Author Commented:
its 1 gb
0
 
zizi21Author Commented:
thanks for all the help.
0
 
Kent OlsenData Warehouse Architect / DBACommented:
Hi zizi,

Did you get this resolved?

The swap file should probably be at least as large as RAM.


Kent
0
Question has a verified solution.

Are you are experiencing a similar issue? Get a personalized answer when you ask a related question.

Have a better answer? Share it in a comment.

All Courses

From novice to tech pro — start learning today.