Process hangs system on exit

Discussion in 'Mac Programming' started by Demiurg, Mar 11, 2008.

  1. macrumors newbie

    Joined:
    Mar 11, 2008
    #1
    Hi All,

    I'm now working on porting our system to the Mac OS X. Everything works well except one strange thing on process's exit and I can't understand where we have gone worng.

    Application (which is multiprocess in nature) extensively uses shm_open/mmap/munmap system calls to share memory between processes. The problem is that on exit this application hangs (almost absolutely) whole system for a few seconds. Removing of some mmap/munmap calls solves this problem. I don't know what is going on at this moment. I want also to mention that this code works perfectly on FreeBSD/Linux/Windows.

    Are there any ideas?

    System is 10.4.11 PPC.
     
  2. macrumors 6502a

    yeroen

    Joined:
    Mar 8, 2007
    Location:
    Cambridge, MA
  3. macrumors 6502a

    Sayer

    Joined:
    Jan 4, 2002
    Location:
    Austin, TX
    #3
    Try attaching Shark to sample the process to see where its hanging up. If you are using Xcode on Tiger, I think there's an option to attach Shark in the Debug menu (in that version of Xcode).

    Otherwise Shark is in Developer > Applications > Performance Tools

    You can attach to any process and sample for a bit and see where the app is spending the time while it quits.
     
  4. thread starter macrumors newbie

    Joined:
    Mar 11, 2008
    #4
    Thanks for the answer.

    Below is the result of the sampling of the "everything" (I can't sample one process since Shark stops sampling before exit call):
    Note that 99.6% takes apprx. 2 seconds during which system absolutely hangs.

    99.6% 99.6% mach_kernel ----- hw_rem_map
    0.0% 99.6% mach_kernel ------- mapping_remove
    0.0% 99.6% mach_kernel --------- pmap_remove
    0.0% 99.6% mach_kernel ----------- vm_map_submap_pmap_clean
    0.0% 99.6% mach_kernel ------------- vm_map_remove
    0.0% 99.6% mach_kernel --------------- task_terminate_internal
    0.0% 99.6% mach_kernel ----------------- exit1
    0.0% 99.6% mach_kernel ------------------- exit
    0.0% 99.6% mach_kernel --------------------- unix_syscall
    0.0% 99.6% mach_kernel ----------------------- shandler
    0.0% 0.0% mach_kernel mapping_remove
    0.0% 0.0% mach_kernel pmap_remove
    0.0% 0.0% mach_kernel vm_map_submap_pmap_clean
     
  5. thread starter macrumors newbie

    Joined:
    Mar 11, 2008
    #5
    Here is complete and very simple "killing" application.
    And here (http://discussions.apple.com/thread.jspa?threadID=1436846&tstart=0) this "bug" was confirmed on the similar system.

    Firstly you should run this one (and DO NOT perform exit from it):

    =========================================================
    Code:
    #include <stdio.h>
    #include <sys/mman.h>
    #include <sys/stat.h>
    #include <string.h>
    #include <sys/types.h>
    #include <fcntl.h>
    
    #define SHM_NAME "/tmp/zeroSharedMemory" /* Shared memory name */
    #define SHM_SIZE 0x10000 /* Shared memory region size in bytes (64Kb) */
    
    /* Clean ups given shared memory object */
    static inline void destroy_shared_memory(int shm_fd, const char* shm_name)
    {
    	if(-1 == close(shm_fd))
    	{
    		perror("close");
    		exit(-1);
    	}
    	if (-1 == shm_unlink(shm_name))
    	{
    		perror("shm_unlink");
    		exit(-1);
    	}
    }
    
    /* Creates shared memory object, zeroing it and waiting any key to be inputted */
    int main (int argc, const char * argv[]) {
    	int shm_fd; //shared memory file descriptor
    	void* shm_addr; //shared memory attach address
    
    	/* Create new shared memory object on filesystem */
    	shm_fd = shm_open(SHM_NAME, O_CREAT | O_RDWR, S_IRUSR | S_IWUSR);
    	if(shm_fd == -1)
    	{
    		perror("shm_open");
    		return -1;
    	}
    
    	/* Truncate to the defined size */
    	if (ftruncate(shm_fd, (off_t) SHM_SIZE) == -1)
    	{
    		perror("ftruncate");
    		destroy_shared_memory(shm_fd, SHM_NAME);
    		return -1;
    	}
    
    	/* mmap shared memory object into virtual address space */
    	shm_addr = mmap(NULL,
    		(size_t)(SHM_SIZE),
    		PROT_READ | PROT_WRITE,
    		MAP_SHARED,
    		shm_fd,
    		(off_t)0);
    
    	if(shm_addr == MAP_FAILED)
    	{
    		perror("mmap");
    		destroy_shared_memory(shm_fd, SHM_NAME);
    		return -1;
    	}
    
    	/* Zeroing memory */
    	memset(shm_addr, 0, (size_t)SHM_SIZE);
    
    	/* Waiting until key pressed ... and perform cleanup */
    	printf("Press any key to perform cleanup and exit ...\n");
    	getchar();
    	destroy_shared_memory(shm_fd, SHM_NAME);
    	return 0;
    }
    =========================================================

    Now start this one:

    =========================================================
    Code:
    #include <stdio.h>
    #include <stdlib.h>
    #include <sys/mman.h>
    #include <sys/stat.h>
    #include <string.h>
    #include <sys/types.h>
    #include <fcntl.h>
    
    #define SHM_NAME "/tmp/zeroSharedMemory" /* Shared memory name */
    #define SHM_SIZE 0x10000 /* Shared memory region size in bytes (64Kb) */
    #define REGIONS_NUM 16000 /* mmap regions number */
    
    /* Close shared memory object descriptor */
    static inline void close_shared_memory(int shm_fd, const char* shm_name)
    {
    	if(-1 == close(shm_fd))
    	{
    		perror("close");
    		exit(-1);
    	}
    }
    
    /* Opens shared memory object, mmaps it REGIONS_NUM times, checks each header and exits */
    int main (int argc, const char * argv[]) {
    	int shm_fd; //shared memory file descriptor
    	void* shm_addr[REGIONS_NUM]; //shared memory attach address(es)
    	int i; //for iteration
    
    	/* Open shared memory object on filesystem */
    	shm_fd = shm_open(SHM_NAME, O_RDWR, 0);
    	if(shm_fd == -1)
    	{
    		perror("shm_open");
    		return -1;
    	}
    
    	/* mmap zero page of the shared memory object into virtual address space */
    	printf("Going to create initial mapping ...");
    	for(i = 0; i < REGIONS_NUM; i++)
    	{
    		shm_addr = mmap(NULL,
    			(size_t)SHM_SIZE,
    			PROT_READ | PROT_WRITE,
    			MAP_SHARED,
    			shm_fd,
    			(off_t) 0);
    
    		if(MAP_FAILED == shm_addr)
    		{
    			perror("mmap");
    			close_shared_memory(shm_fd, SHM_NAME);
    			return -1;
    		}
    	}
    	printf(" OK\n");
    
    	printf("Going to unmap ...");
    	/* unmap a number of blocks */
    	for(i = 0; i < REGIONS_NUM; i++)
    	{
    		// Check header of the block
    		if( ((char*)(shm_addr))[0] != '\0')
    		{
    			// Actually we don't perform this operation in this example application since header
    			// always contains zeroes ...
    			munmap(shm_addr, (size_t)SHM_SIZE);
    		}
    	}
    	printf(" OK\n");
    
    	/* Waiting until key pressed ... and perform cleanup */
    	printf("Press any key to perform clean up and exit ...\n");
    	getchar();
    	close_shared_memory(shm_fd, SHM_NAME);
    	return 0;
    }
    =========================================================

    My system (PPC, 10.4.11) hangs (only mouse pointer is alive) on exit from the second process for 3-4 seconds.
     
  6. macrumors 6502a

    yeroen

    Joined:
    Mar 8, 2007
    Location:
    Cambridge, MA
    #6
    Thanks for providing the source code.

    I've been puzzling over this topic for the last several days. Now I want to know why also.
     

Share This Page