Sunil Kittur(deleted)
|
Re: M7 + gcc4.2.1: Panic on shm_unlink
|
Sunil Kittur(deleted)
06/19/2008 1:41 PM
post9442
|
Re: M7 + gcc4.2.1: Panic on shm_unlink
Yes - this is a bug.
The failing case creates a 1MB mapping, which gets turned into a 1MB section
mapping by the variable page size code. This code was added post-6.3.2
The crash is in cpu_pte_split() where the 1MB section is being split back to
4K page mapping in preparation for clearing the page table entries in the
cpu_pte_manipulate() function.
This operation is being done from a system context when cleaning up the shared
memory object (the shm_unlink removes the last reference to the object), so
data->adp is NULL. The code doesn't check this so it crashes with a null pointer
de-reference.
Sunil.
Andrew Pierson wrote:
> When investigating http://community.qnx.com/sf/discussion/do/listPosts/projects.core_os/discussion.newcode.topc3140 we
created the attached test application. When allocating more than 0xFF000 (1,044,480) bytes of shared memory, the
kernel panics when doing shm_unlink(). This does not occur in QNX630.
>
> Are we missing something, or is this a new kernel bug?
>
> Thanks,
> Andy
>
> _______________________________________________
> OSTech
> http://community.qnx.com/sf/go/post9441
>
>
> ------------------------------------------------------------------------
>
> #include <fcntl.h>
> #include <sys/mman.h>
> #include <stdio.h>
> #include <errno.h>
> #include <string.h>
> #include <stdlib.h>
> #include <unistd.h>
> #include <sys/neutrino.h>
>
> #define MAP_FAILED ((void *)-1)
>
> // This is the size of the map we need to allocate
> static const int mapSize = 28 * 1024 * 1024; // Crashes kernel with SEGV
>
> // This is the smallest size that crashes the kernel
> /*static const int mapSize = (1 * 1024 * 1024) - (4 * 1024) + \
> * 512 - 256 - 128 - 64 - 32 - 16 - \
> * 8 - 4 - 2 - 1; // Crashes kernel ... 0xFF001
> */
>
> // This is the largest size that doesn't crash the kernel; anything smaller
> // works
> //static const int mapSize = (1 * 1024 * 1024) - (4 * 1024); // Works ... 0xFF000
>
>
> static const char * testPath = "/dev/shmem/test";
>
> int main( int argc, char *argv[] )
> {
> int fd;
> unsigned int i;
> unsigned char* addr = MAP_FAILED;
>
> fprintf( stderr, "Attaching to shared map \"%s\" of size %d (0x%x) bytes.\n",
> testPath, mapSize, mapSize );
>
> // Failing to do this will cause an immediate Memory Fault
> if (ThreadCtl(_NTO_TCTL_IO, 0) != EOK)
> {
> perror( "ThreadCtl" );
> return EXIT_FAILURE;
> }
> fprintf( stderr, "ThreadCtl ok\n" );
>
> if( unlink( testPath ))
> {
> // It's fine if the file doesn't exist
> if( errno != ENOENT )
> {
> perror( "unlink" );
> }
> }
> fprintf( stderr, "unlink ok\n" );
>
> fd = shm_open( testPath, O_RDWR | O_CREAT, 0777);
> if( fd == -1 )
> {
> perror( "shm_open" );
> return EXIT_FAILURE;
> }
> fprintf( stderr, "shm_open ok\n" );
>
> if( -1 == shm_ctl( fd,
> SHMCTL_ANON | SHMCTL_PRIV | SHMCTL_GLOBAL,
> (_uint64) 0,
> (_uint64) mapSize ))
> {
> if( ENOSYS == errno )
> {
> // ENOSYS is telling us that we already did a shm_ctl, and it can only
> // be done once.
> fprintf( stderr, "shm_ctl already run (ok if current size fits)\n" );
> }
> else
> {
> perror( "shm_ctl" );
> close(fd);
> return EXIT_FAILURE;
> }
> }
> fprintf( stderr, "shm_ctl ok\n" );
>...
View Full Message
|
|
|