Skip to content
Snippets Groups Projects
Select Git revision
  • ad7d35e75b4240f64ef8f8686df280eedb23df6d
  • master default protected
  • 9.0
  • 8.0
  • nt-tools
  • 7.8
  • 7.6
  • 7.4
  • 7.2
  • 7.0
  • 0.6
  • rosuav/latex-markdown-renderer
  • rxnpatch/rxnpatch
  • marcus/gobject-introspection
  • rxnpatch/8.0
  • rosuav/pre-listening-ports
  • rosuav/async-annotations
  • rosuav/pgsql-ssl
  • rxnpatch/rxnpatch-broken/2023-10-06T094250
  • grubba/fdlib
  • grubba/wip/sakura/8.0
  • v8.0.2020
  • v8.0.2018
  • v8.0.2016
  • v8.0.2014
  • v8.0.2012
  • v8.0.2008
  • v8.0.2006
  • v8.0.2004
  • v8.0.2002
  • v8.0.2000
  • v8.0.1998
  • v8.0.1996
  • v8.0.1994
  • v8.0.1992
  • v8.0.1990
  • v8.0.1988
  • v8.0.1986
  • rxnpatch/clusters/8.0/2025-04-29T124414
  • rxnpatch/2025-04-29T124414
  • v8.0.1984
41 results

acconfig.h

Blame
  • ram-smalloc.c 8.46 KiB
    /*
     * $Id: ram-smalloc.c,v 0.30 1999/05/24 09:34:35 ceder Exp $
     * Copyright (C) 1991-1996, 1998-1999  Lysator Academic Computer Association.
     *
     * This file is part of the LysKOM server.
     * 
     * LysKOM is free software; you can redistribute it and/or modify it
     * under the terms of the GNU General Public License as published by 
     * the Free Software Foundation; either version 1, or (at your option) 
     * any later version.
     * 
     * LysKOM is distributed in the hope that it will be useful, but WITHOUT
     * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
     * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
     * for more details.
     * 
     * You should have received a copy of the GNU General Public License
     * along with LysKOM; see the file COPYING.  If not, write to
     * Lysator, c/o ISY, Linkoping University, S-581 83 Linkoping, SWEDEN,
     * or the Free Software Foundation, Inc., 675 Mass Ave, Cambridge, 
     * MA 02139, USA.
     *
     * Please mail bug reports to bug-lyskom@lysator.liu.se. 
     */
    /*
     * smalloc.c
     *
     * Contains memory allocator routines
     *
     *	TEST VERSION by ceder
     */
    
    
    #ifdef HAVE_CONFIG_H
    #  include <config.h>
    #endif
    
    /*
     * Finding memory leaks
     * ====================
     *
     * This code contains some stubs that can be useful when hunting for
     * memory leaks.  To use it, you must configure with
     * --with-traced-allocations and recompile. You actually only need to
     * recompile ram-smalloc.c, ramkomd.c and the programs in testsuite
     * after changing it, so "make -t; rm src/server/ram-smalloc.o \
     * src/server/ramkomd.o src/server/testsuite/test-*.o; make" is the 
     * fastest way to change between tracing and a normal compile.
     *
     * Run the resulting lyskomd under gdb, like this:
     *            bash$ gdb lyskomd
     *            (gdb) source trace-mem.gdb
     *            (gdb) run
     *            Where does the trace want to go today? [stderr] RET
     * gdb will print a backtrace and continue whenever memory is
     * allocated, reallocated or released.  The program itself will also
     * print out some information.  The result is a long log file.
     *
     * Run M-x resolve-trace (from handle-malloc-dump.el on the resulting
     * output.  Look in the *Result* buffer for the result.
     *
     * Using the test suite to find memory leaks
     * =========================================
     *
     * This code can also be used together with the test suite, even
     * though that is slightly more complicated.  Begin by starting a gdb
     * whose output is saved, for example by running it in a shell buffer
     * in emacs (note: do not use M-x gdb -- that will slow down the
     * process and it is slow enough as it is):
     *            bash$ gdb lyskomd
     *            (gdb) source trace-mem.gdb
     *            (gdb) shell tty
     *            /dev/ttypd
     * Insert the following two statements in the *.exp script before the
     * call to lyskomd_start that you want to trace:
     *	      set attach 1
     *            set MEMTRACE /dev/ttypd
     * MEMTRACE should be set to the tty where gdb is running.  Start the
     * test suite:
     *	      bash$ runtest --tool lyskomd leaks.0/99.exp
     *            [...]
     *            Please attach to lyskomd pid 4711 and hit RETURN
     * Attach to the process:
     *            (gdb) attach 4711
     *            (gdb) continue
     * Press enter to resume the test suite.  Lots of output should appear
     * from gdb.
     *
     */
    
    static const char *
    rcsid = "$Id: ram-smalloc.c,v 0.30 1999/05/24 09:34:35 ceder Exp $";
    #include "rcs.h"
    USE(rcsid);
    
    #ifdef HAVE_STDLIB_H
    #  include <stdlib.h>
    #endif
    #include <stdio.h>
    #include <sys/types.h>
    #include <assert.h>
    #include <errno.h>
    
    #include "exp.h"
    #include "s-string.h"
    #include "kom-types.h"
    #include "lyskomd.h"
    #include "server/smalloc.h"
    #ifdef TRACED_ALLOCATIONS
    #  include "trace-alloc.h"
    #endif
    
    static int no_of_allocated_blocks = 0;
    
    #ifdef TRACED_ALLOCATIONS
    
    static FILE *malloc_fp = NULL;
    
    void
    trace_alloc_file(const char *loc)
    {
        if (loc[0] == '\0')
    	malloc_fp = stderr;
        else
    	malloc_fp = fopen(loc, "w");
    
        if (malloc_fp == NULL)
    	restart_kom("init_malloc_fp failed: %s, %d\n", loc, errno);
        fprintf(malloc_fp, "A new trace from lyskomd starts here\n");
    }
    
    static void
    trace_smalloc(size_t size,
    	      void *result)
    {
        assert(malloc_fp != NULL);
        fprintf(malloc_fp, "smalloc:\nArg: 0x%lx\nRes: 0x%lx\n",
    	    (long)size, (long)result);
        fprintf(malloc_fp, "==== end ====\n");
        fflush(malloc_fp);
    }
    #endif
    
    /*
     * "safe" malloc. Handles the case when malloc returns NULL.
     * smalloc cannot fail.
     */
    EXPORT  void *
    smalloc(size_t size)
    {
       unsigned int *p;
       
       p = (unsigned int *) malloc(size + 2*sizeof(unsigned int) + 2);
       if (p == NULL)
           restart_kom("Can't allocate %lu bytes.\n", (unsigned long)size);
    
       ++no_of_allocated_blocks;
    
       *p++ = SMALLOC_MAGIC_ALLOC;
       *p++ = size;
       ((unsigned char *) p)[size]   = 0x89;
       ((unsigned char *) p)[size+1] = 0xA7;
    
    #ifdef TRACED_ALLOCATIONS
       trace_smalloc(size, p);
    #endif
    
       return (void *) p;
    }
    
    #ifdef TRACED_ALLOCATIONS
    static void
    trace_free(void *block)
    {
        assert(malloc_fp != NULL);
        fprintf(malloc_fp, "sfree:\nArg: 0x%lx\n", (long)block);
        fprintf(malloc_fp, "==== end ====\n");
        fflush(malloc_fp);
    }
    #endif
    
    EXPORT  void
    sfree(void * ptr)	/* it is legal to sfree a NULL pointer */
    {
        unsigned int *ip;
        
        if ( ptr != NULL )
        {
    #ifdef TRACED_ALLOCATIONS
    	trace_free(ptr);
    #endif
            ip = (unsigned int *) ptr;
    	ip -= 2;
    	switch (*ip)
    	{
    	    case SMALLOC_MAGIC_ALLOC:
    		if (((unsigned char *) (ip+2))[ip[1]] != 0x89 ||
    		    ((unsigned char *) (ip+2))[ip[1]+1] != 0xA7)
    		  restart_kom("SFREE: Buffer overflow, bsize = %ul\n", ip[1]);
    	        --no_of_allocated_blocks;
    		*ip = SMALLOC_MAGIC_FREE;
    		free( ip );
    		break;
    
    	    case SMALLOC_MAGIC_FREE:
    		restart_kom("SFREE: Trying to free already freed block\n");
    
    	    default:
    		restart_kom("SFREE: Illegal magic number\n");
    	}
        }
    }
    
    #ifdef TRACED_ALLOCATIONS
    static void
    trace_srealloc(size_t size,
    	       void *arg,		   
    	       void *result)
    {
        assert(malloc_fp != NULL);
        fprintf(malloc_fp, "srealloc:\nSize: 0x%lx\nArg: 0x%lx\nRes: 0x%lx\n",
    	    (long)size, (long)arg, (long)result);
        fprintf(malloc_fp, "==== end ====\n");
        fflush(malloc_fp);
    }
    #endif
    EXPORT  void *
    srealloc(void * ptr, size_t size) /* Never fails. It is legal to */
    {				    /* realloc the NULL ptr. */
        unsigned int   * ip;
        unsigned int   * new_ptr;
    
        if ( ptr == NULL )
    	return smalloc(size);
    
        ip = (unsigned int *) ptr;
        ip -= 2;
        switch (*ip)
        {
            case SMALLOC_MAGIC_ALLOC:
                break;
    
    	case SMALLOC_MAGIC_FREE:
    	    restart_kom("SREALLOC: Trying to realloc freed block\n");
    
    	default:
    	    restart_kom("SREALLOC: Illegal magic number\n");
        }
    
        if (((unsigned char *) (ip+2))[ip[1]] != 0x89 ||
    	((unsigned char *) (ip+2))[ip[1]+1] != 0xA7)
          restart_kom("SREALLOC: Buffer overflow, osize = %ul, nsize = %lu.\n",
    		  ip[1], (unsigned long)size);
    
        *ip = SMALLOC_MAGIC_FREE;
        if ( (new_ptr = (unsigned int *) realloc((void *) ip,
    				size+2*sizeof(unsigned int)+2) ) == NULL )
        {
    	restart_kom("Out of memory - can't realloc. ptr = %lu size = %lu.\n",
    		    (unsigned long)ptr, (unsigned long)size);
        }
    
        *new_ptr++ = SMALLOC_MAGIC_ALLOC;
        *new_ptr++ = size;
    
        ((unsigned char *) new_ptr)[size]   = 0x89;
        ((unsigned char *) new_ptr)[size+1] = 0xA7;
    
    #ifdef TRACED_ALLOCATIONS
        trace_srealloc(size, ptr, new_ptr);
    #endif
    
        return (void *) new_ptr;
    }
    
    
    /*
     * Allocate temporary memory, which is automatically freed after this
     * atomic call.
     */
    
    static void **tmp_alloc_table   = NULL;
    static int tmp_alloc_table_size = 0; /* Size */
    static int tmp_alloc_table_use  = 0; /* Used size */
    
    EXPORT  void *
    tmp_alloc(unsigned long size)
    {
        if ( tmp_alloc_table_size <= tmp_alloc_table_use )
        {
    	/* Need to increas table. */
    	tmp_alloc_table = srealloc (tmp_alloc_table,
    				    ((++tmp_alloc_table_size)
    				     * sizeof (void *)));
        }
    
        return (tmp_alloc_table[ tmp_alloc_table_use++ ]
    	    = smalloc (size));
    }
    
    
    /*
     * Free all core which is allocated with tmp_alloc(). This is called from
     * end_of_atomic().
     */
    EXPORT void
    free_tmp(void)
    {
        int i;
    
        for ( i = 0; i < tmp_alloc_table_use; i++ )
        {
    	sfree ( tmp_alloc_table[ i ] );
    	tmp_alloc_table[ i ] = NULL;
        }
    
        tmp_alloc_table_use = 0;
    }
    
    EXPORT  void
    free_all_tmp(void)
    {
        free_tmp();
        sfree( tmp_alloc_table );
        tmp_alloc_table = NULL;
        tmp_alloc_table_size = 0;
    }
    
    EXPORT void
    dump_smalloc_counts(FILE *stat_file)
    {
        fprintf(stat_file, "---ram-smalloc.c:\n%s%d\n",
    	    "\tAllocated blocks (grand total): ",
    	    no_of_allocated_blocks);
    }