Beispiel #1
0
/**
 * @internal
 *
 * FUNCTION:      pcsl_end_memory()
 * TYPE:          private operation
 * OVERVIEW:      Finalize the PCSL memory pool
 * INTERFACE:
 *   parameters:  count   address to store memory leak count
 *                size    address to store totol bytes of memory leaked
 *   returns:     the number of memory leaks detected
 *                
 */
static int
pcsl_end_memory(int* count, int* size) {
    _PcslMemHdrPtr pcslMemoryHdr;
    char*          pcslMemoryPtr;

    *count = 0;
    *size  = 0;

    for (pcslMemoryPtr = PcslMemoryStart; 
         pcslMemoryPtr < PcslMemoryEnd;
         pcslMemoryPtr += pcslMemoryHdr->size + sizeof(_PcslMemHdr)) {

        pcslMemoryHdr = (_PcslMemHdrPtr)pcslMemoryPtr;

        if (pcslMemoryHdr->magic != MAGIC) {
            REPORT1("ERROR: Corrupted start of memory header: 0x%p\n", 
                    pcslMemoryPtr);
            return -1;
        }
#ifdef PCSL_DEBUG
        if (pcslMemoryHdr->guard != GUARD_WORD) {
            report("ERROR: Corrupted end of memory header: 0x%p\n",
                   pcslMemoryPtr);
            return -1;
        }

        /* The memory block header is valid, now check the guard data */
        if (verify_tail_guard_data(pcslMemoryHdr)) {
            report("ERROR: Memory overrun: 0x%p\n",
                   pcslMemoryPtr);
            print_alloc("allocated", 
                        pcslMemoryHdr->filename, 
                        pcslMemoryHdr->lineno);
        }
#endif 

        if (pcslMemoryHdr->free != 1) {

#ifdef PCSL_DEBUG
            report("WARNING: memory leak: size= %d  address= 0x%p\n",
                   pcslMemoryHdr->size,
                   (void*)((char*)pcslMemoryHdr + sizeof(_PcslMemHdr)));
            print_alloc("allocated", 
                        pcslMemoryHdr->filename, pcslMemoryHdr->lineno);
#endif
            pcsl_mem_free((void*)((char*)pcslMemoryHdr + sizeof(_PcslMemHdr)));
            *count += 1;
            *size  += pcslMemoryHdr->size;
        }
    }
    return *count;
}
Beispiel #2
0
void
pcsl_mem_free_impl0(void *ptr, char *filename, int lineno) {
    _PcslMemHdrPtr pcslMemoryHdr;

    if (ptr == NULL) {
        report("WARNING: Attempt to free NULL pointer\n");
        print_alloc("freed", filename, lineno);
    } else if (((char*)ptr > PcslMemoryEnd) || 
               ((char*)ptr < PcslMemoryStart)) {
        report("ERROR: Attempt to free memory out of scope: 0x%p\n", ptr);
        print_alloc("freed", filename, lineno);
    } else {
        pcslMemoryHdr = (_PcslMemHdrPtr)((char*)ptr -sizeof(_PcslMemHdr));
        if (pcslMemoryHdr->magic != MAGIC) {
            report("ERROR: Attempt to free corrupted memory: 0x%p\n", ptr);
            print_alloc("freed", filename, lineno);
        } else if (pcslMemoryHdr->free != 0) {
            report("ERROR: Attempt to free memory twice: 0x%p\n", ptr);
            print_alloc("freed", filename, lineno);
        } else {
            PcslMemoryAllocated -= pcslMemoryHdr->size;
            /* The memory block header is valid, now check the guard data */
            if (pcslMemoryHdr->guard != GUARD_WORD) {
                report("ERROR: Possible memory underrun: 0x%p\n", ptr);
                print_alloc("allocated", 
                            pcslMemoryHdr->filename, 
                            pcslMemoryHdr->lineno);
                print_alloc("freed", filename, lineno);
            } else if (verify_tail_guard_data(pcslMemoryHdr)) {
                report("ERROR: Possible memory overrun: 0x%p\n", ptr);
                print_alloc("allocated", 
                            pcslMemoryHdr->filename, 
                            pcslMemoryHdr->lineno);
                print_alloc("freed", filename, lineno);
            }

            report("DEBUG: free %d bytes: 0x%p\n", pcslMemoryHdr->size, ptr);
            print_alloc("allocated", 
                        pcslMemoryHdr->filename, pcslMemoryHdr->lineno);
            print_alloc("freed", filename, lineno);
            pcslMemoryHdr->free = 1;
        }
    } /* end of else */
}
Beispiel #3
0
/* Set countMemoryLeaksOnly = 0 in order to get more verbose information */
int pcsl_mem_malloc_dump_impl0(int countMemoryLeaksOnly)
{
    char *localpcslMallocMemPtr = NULL;
    char *localpcslMallocMemStart = PcslMemoryStart;
    char *localpcslMallocMemEnd = PcslMemoryEnd;
    _PcslMemHdrPtr localpcslMallocMemHdr = NULL;

    int numberOfAllocatedBlocks = 0;

    REPORT3("PcslMemory=0x%p PcslMemoryStart=0x%p PcslMemoryEnd=0x%p\n", 
            PcslMemory, PcslMemoryStart, PcslMemoryEnd);

    for (localpcslMallocMemPtr = localpcslMallocMemStart; 
        localpcslMallocMemPtr < localpcslMallocMemEnd;
        localpcslMallocMemPtr += localpcslMallocMemHdr->size + sizeof(_PcslMemHdr)) {

        localpcslMallocMemHdr = (_PcslMemHdrPtr) localpcslMallocMemPtr;
        if (localpcslMallocMemHdr->magic != MAGIC) {
            REPORT1("ERROR: memory corruption at 0x%p\n", 
                    localpcslMallocMemPtr);
            return -1;
        } else {

            if (countMemoryLeaksOnly == 0) {
                REPORT4("hdr 0x%p free=%d size=%d address=0x%p\n",
                        localpcslMallocMemHdr, 
                        localpcslMallocMemHdr->free, 
                        localpcslMallocMemHdr->size,
                        (void *)(((char *)localpcslMallocMemHdr) + 
                                 sizeof(_PcslMemHdr)));
            }

            if (localpcslMallocMemHdr->free != 1) {
                numberOfAllocatedBlocks += 1;
#ifdef PCSL_DEBUG
                report("WARNING: memory leak: size=%d  address=0x%p\n",
                       localpcslMallocMemHdr->size, 
                       (void*)((char*)localpcslMallocMemHdr + 
                               sizeof(_PcslMemHdr)));
                print_alloc("allocated", 
                            localpcslMallocMemHdr->filename, 
                            localpcslMallocMemHdr->lineno);
#endif
            }
        }
    }
    return numberOfAllocatedBlocks;
}
Beispiel #4
0
/**
 * FUNCTION:      pcsl_mem_get_free_heap_impl0()
 * TYPE:          public operation
 * OVERVIEW:      Get the current amount of unused heap
 * INTERFACE:
 *   parameters:  <none>
 *   returns:     The current amount of unused heap
 *                
 */
int
pcsl_mem_get_free_heap_impl0() {
    _PcslMemHdrPtr pcslMemoryHdr;
    char*          pcslMemoryPtr;
    int            size = 0;

    for (pcslMemoryPtr = PcslMemoryStart; 
         pcslMemoryPtr < PcslMemoryEnd;
         pcslMemoryPtr += pcslMemoryHdr->size + sizeof(_PcslMemHdr)) {

        pcslMemoryHdr = (_PcslMemHdrPtr)pcslMemoryPtr;

#ifdef PCSL_DEBUG
        if (pcslMemoryHdr->magic != MAGIC) {
            report("ERROR: Corrupted start of memory header: 0x%p\n", 
                   pcslMemoryPtr);
            return -1;
        }
        
        if (pcslMemoryHdr->guard != GUARD_WORD) {
            report("ERROR: Corrupted end of memory header: 0x%p\n",
                   pcslMemoryPtr);
            return -1;
        }

        /* The memory block header is valid, now check the guard data */
        if (verify_tail_guard_data(pcslMemoryHdr)) {
            report("ERROR: Memory overrun: 0x%p\n", pcslMemoryPtr);
            print_alloc("allocated", 
                        pcslMemoryHdr->filename, 
                        pcslMemoryHdr->lineno);
        }
#endif

        if (pcslMemoryHdr->free != 1) {
            size += pcslMemoryHdr->size;
        }
    }
    return (pcsl_mem_get_total_heap_impl0() - size);
}
Beispiel #5
0
void*
pcsl_mem_malloc_impl0(unsigned int size, char* filename, int lineno) {
#else
void*
pcsl_mem_malloc_impl0(unsigned int size) {
#endif
    unsigned int   numBytesToAllocate = size;
    void*          loc     = NULL;
    _PcslMemHdrPtr tempHdr = NULL;
    char*          temp    = NULL;
    char*          pcslMemoryPtr;
    _PcslMemHdrPtr pcslMemoryHdr;

#ifdef PCSL_DEBUG
    int   guardSize = 0;
    void* guardPos = NULL;
    int   i = 0;
    numBytesToAllocate += GUARD_SIZE;
#endif

    while ( (numBytesToAllocate & ALIGNMENT) != 0 ) {
        numBytesToAllocate++;
    }

    /* find a free slot */
    for (pcslMemoryPtr = PcslMemoryStart;
         pcslMemoryPtr < PcslMemoryEnd;
         pcslMemoryPtr += pcslMemoryHdr->size + sizeof(_PcslMemHdr)) {
        
        pcslMemoryHdr = (_PcslMemHdrPtr)pcslMemoryPtr;
        if (pcslMemoryHdr->magic != MAGIC) {
            REPORT1("ERROR: Memory corruption at 0x%p\n", pcslMemoryPtr); 
            return((void *) 0);
        } else {
            while ( 1 ) {
                /* coalescing */
                if (pcslMemoryHdr->free == 1) {
                    /* if current block is free */
                    temp = (char*)pcslMemoryHdr;
                    temp += pcslMemoryHdr->size + sizeof(_PcslMemHdr);
                    tempHdr = (_PcslMemHdrPtr)temp;

                    if ((temp < PcslMemoryEnd) && 
                        (tempHdr->free == 1) && (tempHdr->magic == MAGIC)) {
                        /* and the next block is free too */
                        /* then coalesce */
                        pcslMemoryHdr->size += tempHdr->size
                            + sizeof(_PcslMemHdr);
#ifdef PCSL_DEBUG
                        pcslMemoryHdr->guardSize = 0;
#endif
                        REPORT2("DEBUG: Coalescing blocks 0x%p and 0x%p\n",
                                pcslMemoryHdr, tempHdr);

                    } else {
                        break;
                    }
                } else {
                    break;
                }
            } /* while */

            /* allocating */
            if ((pcslMemoryHdr->free == 1) && 
                (pcslMemoryHdr->size >= numBytesToAllocate)) {
                if (pcslMemoryHdr->size > (numBytesToAllocate 
                                              + sizeof(_PcslMemHdr) + 4)) {
                    /* split block */
                    _PcslMemHdrPtr nextHdr;
                    nextHdr = (_PcslMemHdrPtr)((char *)pcslMemoryPtr
                                               + numBytesToAllocate
                                               + sizeof(_PcslMemHdr));
                    nextHdr->magic = MAGIC;
                    nextHdr->free = 1;
                    nextHdr->size = pcslMemoryHdr->size 
                                    - numBytesToAllocate 
                                    - sizeof(_PcslMemHdr);
#ifdef PCSL_DEBUG
                    nextHdr->guard    = GUARD_WORD;
                    nextHdr->guardSize = 0;
#endif
                    pcslMemoryHdr->size     = numBytesToAllocate;
                }
                pcslMemoryHdr->free     = 0;
                loc = (void*)((char*)pcslMemoryHdr + sizeof(_PcslMemHdr));

#ifdef PCSL_DEBUG
                pcslMemoryHdr->guard    = GUARD_WORD;      /* Add head guard */
                pcslMemoryHdr->filename = filename;
                pcslMemoryHdr->lineno   = lineno;

                /* Add tail guard */
                guardSize = pcslMemoryHdr->size - size;

                pcslMemoryHdr->guardSize = guardSize;
                guardPos = (void*)((char*)loc + pcslMemoryHdr->size 
                                   - guardSize);
                for(i=0; i<guardSize; i++) {
                    ((unsigned char*)guardPos)[i] = GUARD_BYTE;
                }
                
                PcslMemoryAllocated += numBytesToAllocate;
                if (PcslMemoryAllocated > PcslMemoryHighWaterMark) {
                    PcslMemoryHighWaterMark = PcslMemoryAllocated;
                }

                report("DEBUG: Requested %d provided %d at 0x%p\n",
                       numBytesToAllocate, pcslMemoryHdr->size, loc);
                print_alloc("allocated", filename, lineno);
#endif
                return(loc);
            } /* end of allocating */
        } /* end of else */
    } /* end of for */
    REPORT1("DEBUG: Unable to allocate %d bytes\n", numBytesToAllocate);
    return((void *)0);
}
Beispiel #6
0
/* Register allocation */
static int
_x86_allocate_registers( EventSetInfo_t * ESI )
{
	int i, j, natNum;
	hwd_reg_alloc_t event_list[MAX_COUNTERS];
	hwd_register_t *ptr;

	/* Initialize the local structure needed
	   for counter allocation and optimization. */
	natNum = ESI->NativeCount;

	if ( is_pentium4() )
		SUBDBG( "native event count: %d\n", natNum );

	for ( i = 0; i < natNum; i++ ) {
		/* retrieve the mapping information about this native event */
		_papi_libpfm_ntv_code_to_bits( ( unsigned int ) ESI->NativeInfoArray[i].
							   ni_event, &event_list[i].ra_bits );

		if ( is_pentium4() ) {
			/* combine counter bit masks for both esc registers into selector */
			event_list[i].ra_selector =
				event_list[i].ra_bits.counter[0] | event_list[i].ra_bits.
				counter[1];
		} else {
			/* make sure register allocator only looks at legal registers */
			event_list[i].ra_selector =
				event_list[i].ra_bits.selector & ALLCNTRS;
#ifdef PERFCTR_X86_INTEL_CORE2
			if ( _papi_hwi_system_info.hw_info.model ==
				 PERFCTR_X86_INTEL_CORE2 )
				event_list[i].ra_selector |=
					( ( event_list[i].ra_bits.
						selector >> 16 ) << 2 ) & ALLCNTRS;
#endif
		}
		/* calculate native event rank, which is no. of counters it can live on */
		event_list[i].ra_rank = 0;
		for ( j = 0; j < MAX_COUNTERS; j++ ) {
			if ( event_list[i].ra_selector & ( 1 << j ) ) {
				event_list[i].ra_rank++;
			}
		}

		if ( is_pentium4() ) {
			event_list[i].ra_escr[0] = event_list[i].ra_bits.escr[0];
			event_list[i].ra_escr[1] = event_list[i].ra_bits.escr[1];
#ifdef DEBUG
			SUBDBG( "i: %d\n", i );
			print_alloc( &event_list[i] );
#endif
		}
	}
	if ( _papi_hwi_bipartite_alloc( event_list, natNum, ESI->CmpIdx ) ) {	/* successfully mapped */
		for ( i = 0; i < natNum; i++ ) {
#ifdef PERFCTR_X86_INTEL_CORE2
			if ( _papi_hwi_system_info.hw_info.model ==
				 PERFCTR_X86_INTEL_CORE2 )
				event_list[i].ra_bits.selector = event_list[i].ra_selector;
#endif
#ifdef DEBUG
			if ( is_pentium4() ) {
				SUBDBG( "i: %d\n", i );
				print_alloc( &event_list[i] );
			}
#endif
			/* Copy all info about this native event to the NativeInfo struct */
			ptr = ESI->NativeInfoArray[i].ni_bits;
			*ptr = event_list[i].ra_bits;

			if ( is_pentium4() ) {
				/* The selector contains the counter bit position. Turn it into a number
				   and store it in the first counter value, zeroing the second. */
				ptr->counter[0] = ffs( event_list[i].ra_selector ) - 1;
				ptr->counter[1] = 0;
			}

			/* Array order on perfctr is event ADD order, not counter #... */
			ESI->NativeInfoArray[i].ni_position = i;
		}
		return 1;
	} else
		return 0;
}
Beispiel #7
0
/* This function removes shared resources available to the src event
    from the resources available to the dst event,
    and reduces the rank of the dst event accordingly. Typically,
    the src event will be exclusive, but the code shouldn't assume it.
    Returns nothing.  */
static void
_x86_bpt_map_preempt( hwd_reg_alloc_t * dst, hwd_reg_alloc_t * src )
{
	int i;
	unsigned shared;

	if ( is_pentium4() ) {
#ifdef DEBUG
		SUBDBG( "src, dst\n" );
		print_alloc( src );
		print_alloc( dst );
#endif

		/* check for a pebs conflict */
		/* pebs enables must both be non-zero */
		i = ( ( ( dst->ra_bits.pebs_enable && src->ra_bits.pebs_enable ) &&
				/* and not equal to each other */
				( dst->ra_bits.pebs_enable != src->ra_bits.pebs_enable ) ) ||
			  /* same for pebs_matrix_vert */
			  ( ( dst->ra_bits.pebs_matrix_vert &&
				  src->ra_bits.pebs_matrix_vert )
				&& ( dst->ra_bits.pebs_matrix_vert !=
					 src->ra_bits.pebs_matrix_vert ) ) );
		if ( i ) {
			SUBDBG( "pebs conflict! clearing selector\n" );
			dst->ra_selector = 0;
			return;
		} else {
			/* remove counters referenced by any shared escrs */
			if ( ( dst->ra_escr[0] == src->ra_escr[0] ) &&
				 ( ( int ) dst->ra_escr[0] != -1 ) ) {
				dst->ra_selector &= ~dst->ra_bits.counter[0];
				dst->ra_escr[0] = -1;
			}
			if ( ( dst->ra_escr[1] == src->ra_escr[1] ) &&
				 ( ( int ) dst->ra_escr[1] != -1 ) ) {
				dst->ra_selector &= ~dst->ra_bits.counter[1];
				dst->ra_escr[1] = -1;
			}

			/* remove any remaining shared counters */
			shared = ( dst->ra_selector & src->ra_selector );
			if ( shared )
				dst->ra_selector ^= shared;
		}
		/* recompute rank */
		for ( i = 0, dst->ra_rank = 0; i < MAX_COUNTERS; i++ )
			if ( dst->ra_selector & ( 1 << i ) )
				dst->ra_rank++;
#ifdef DEBUG
		SUBDBG( "new dst\n" );
		print_alloc( dst );
#endif
	} else {
		shared = dst->ra_selector & src->ra_selector;
		if ( shared )
			dst->ra_selector ^= shared;
		for ( i = 0, dst->ra_rank = 0; i < MAX_COUNTERS; i++ )
			if ( dst->ra_selector & ( 1 << i ) )
				dst->ra_rank++;
	}
}
Beispiel #8
0
int
main(
	int	argc, 
	char	**argv)
{
	dm_sessid_t	 sid = DM_NO_SESSION;
	dm_off_t 	startoff = 0;		/* starting offset */
	u_int		nelem = 100;
	char		*pathname;
	void		*hanp;
	size_t	 	 hlen;
	dm_stat_t	sbuf;
	char		*name;
	int		opt;

	if (Progname = strrchr(argv[0], '/')) {
		Progname++;
	} else {
		Progname = argv[0];
	}

	/* Crack and validate the command line options. */

	while ((opt = getopt(argc, argv, "Dn:o:s:")) != EOF) {
		switch(opt) {
		case 'D':
			Dflag++;
			break;
		case 'n':
			nelem = atol(optarg);
			break;
		case 'o':
			startoff = atoll(optarg);
			break;
		case 's':
			sid = atol(optarg);
			break;
		case '?':
			usage();
		}
	}
	if (optind + 1 != argc)
		usage();
	pathname = argv[optind];

	if (dm_init_service(&name)) {
		fprintf(stderr, "dm_init_service failed, %s\n",
			strerror(errno));
		exit(1);
	}

	if (sid == DM_NO_SESSION)
		find_test_session(&sid);

	/* Get the file's handle and verify that it is a regular file. */

	if (dm_path_to_handle(pathname, &hanp, &hlen)) {
		fprintf(stderr, "can't get handle for %s\n", pathname);
		exit(1);
	}
	if (dm_get_fileattr(sid, hanp, hlen, DM_NO_TOKEN, DM_AT_STAT, &sbuf)) {
		fprintf(stderr, "dm_get_fileattr failed\n");
		exit(1);
	}
	if (!S_ISREG(sbuf.dt_mode)) {
		fprintf(stderr, "%s is not a regular file\n", pathname);
		exit(1);
	}

	/* Print the allocation. */

	if (print_alloc(sid, hanp, hlen, pathname, startoff, nelem))
		exit(1);

	dm_handle_free(hanp, hlen);
	exit(0);
}