nsprpub/pr/tests/dbmalloc.c

changeset 0
6474c204b198
     1.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     1.2 +++ b/nsprpub/pr/tests/dbmalloc.c	Wed Dec 31 06:09:35 2014 +0100
     1.3 @@ -0,0 +1,310 @@
     1.4 +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
     1.5 +/* This Source Code Form is subject to the terms of the Mozilla Public
     1.6 + * License, v. 2.0. If a copy of the MPL was not distributed with this
     1.7 + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
     1.8 +
     1.9 +/***********************************************************************
    1.10 +**
    1.11 +** Name: dbmalloc.c
    1.12 +**
    1.13 +** Description: Testing malloc (OBSOLETE)
    1.14 +**
    1.15 +** Modification History:
    1.16 +** 14-May-97 AGarcia- Converted the test to accomodate the debug_mode flag.
    1.17 +**	         The debug mode will print all of the printfs associated with this test.
    1.18 +**			 The regress mode will be the default mode. Since the regress tool limits
    1.19 +**           the output to a one line status:PASS or FAIL,all of the printf statements
    1.20 +**			 have been handled with an if (debug_mode) statement. 
    1.21 +***********************************************************************/
    1.22 +#include <stdio.h>
    1.23 +#include <stdlib.h>
    1.24 +#include <time.h>
    1.25 +#include <string.h>
    1.26 +#include "nspr.h"
    1.27 +
    1.28 +void
    1.29 +usage
    1.30 +(
    1.31 +    void
    1.32 +)
    1.33 +{
    1.34 +    fprintf(stderr, "Usage: dbmalloc ('-m'|'-s') '-f' num_fails ('-d'|'-n') filename [...]\n");
    1.35 +    exit(0);
    1.36 +}
    1.37 +
    1.38 +typedef struct node_struct
    1.39 +{
    1.40 +    struct node_struct *next, *prev;
    1.41 +    int line;
    1.42 +    char value[4];
    1.43 +}
    1.44 +    node_t,
    1.45 +   *node_pt;
    1.46 +
    1.47 +node_pt get_node(const char *line)
    1.48 +{
    1.49 +    node_pt rv;
    1.50 +    int l = strlen(line);
    1.51 +    rv = (node_pt)PR_MALLOC(sizeof(node_t) + l + 1 - 4);
    1.52 +    if( (node_pt)0 == rv ) return (node_pt)0;
    1.53 +    memcpy(&rv->value[0], line, l+1);
    1.54 +    rv->next = rv->prev = (node_pt)0;
    1.55 +    return rv;
    1.56 +}
    1.57 +
    1.58 +void
    1.59 +dump
    1.60 +(
    1.61 +    const char *name,
    1.62 +    node_pt     node,
    1.63 +    int         mf,
    1.64 +    int         debug
    1.65 +)
    1.66 +{
    1.67 +    if( (node_pt)0 != node->prev ) dump(name, node->prev, mf, debug);
    1.68 +    if( 0 != debug ) printf("[%s]: %6d: %s", name, node->line, node->value);
    1.69 +    if( node->line == mf ) fprintf(stderr, "[%s]: Line %d was allocated!\n", name, node->line);
    1.70 +    if( (node_pt)0 != node->next ) dump(name, node->next, mf, debug);
    1.71 +    return;
    1.72 +}
    1.73 +
    1.74 +void
    1.75 +release
    1.76 +(
    1.77 +    node_pt node
    1.78 +)
    1.79 +{
    1.80 +    if( (node_pt)0 != node->prev ) release(node->prev);
    1.81 +    if( (node_pt)0 != node->next ) release(node->next);
    1.82 +    PR_DELETE(node);
    1.83 +}
    1.84 +
    1.85 +int
    1.86 +t2
    1.87 +(
    1.88 +    const char *name,
    1.89 +    int         mf,
    1.90 +    int         debug
    1.91 +)
    1.92 +{
    1.93 +    int rv;
    1.94 +    FILE *fp;
    1.95 +    int l = 0;
    1.96 +    node_pt head = (node_pt)0;
    1.97 +    char buffer[ BUFSIZ ];
    1.98 +
    1.99 +    fp = fopen(name, "r");
   1.100 +    if( (FILE *)0 == fp )
   1.101 +    {
   1.102 +        fprintf(stderr, "[%s]: Cannot open \"%s.\"\n", name, name);
   1.103 +        return -1;
   1.104 +    }
   1.105 +
   1.106 +    /* fgets mallocs a buffer, first time through. */
   1.107 +    if( (char *)0 == fgets(buffer, BUFSIZ, fp) )
   1.108 +    {
   1.109 +        fprintf(stderr, "[%s]: \"%s\" is empty.\n", name, name);
   1.110 +        (void)fclose(fp);
   1.111 +        return -1;
   1.112 +    }
   1.113 +
   1.114 +    rewind(fp);
   1.115 +
   1.116 +    if( PR_SUCCESS != PR_ClearMallocCount() )
   1.117 +    {
   1.118 +        fprintf(stderr, "[%s]: Cannot clear malloc count.\n", name);
   1.119 +        (void)fclose(fp);
   1.120 +        return -1;
   1.121 +    }
   1.122 +
   1.123 +    if( PR_SUCCESS != PR_SetMallocCountdown(mf) )
   1.124 +    {
   1.125 +        fprintf(stderr, "[%s]: Cannot set malloc countdown to %d\n", name, mf);
   1.126 +        (void)fclose(fp);
   1.127 +        return -1;
   1.128 +    }
   1.129 +
   1.130 +    while( fgets(buffer, BUFSIZ, fp) )
   1.131 +    {
   1.132 +        node_pt n;
   1.133 +        node_pt *w = &head;
   1.134 +
   1.135 +        if( (strlen(buffer) == (BUFSIZ-1)) && (buffer[BUFSIZ-2] != '\n') )
   1.136 +            buffer[BUFSIZ-2] == '\n';
   1.137 +
   1.138 +        l++;
   1.139 +
   1.140 +        n = get_node(buffer);
   1.141 +        if( (node_pt)0 == n ) 
   1.142 +        {
   1.143 +            printf("[%s]: Line %d: malloc failure!\n", name, l);
   1.144 +            continue;
   1.145 +        }
   1.146 +
   1.147 +        n->line = l;
   1.148 +
   1.149 +        while( 1 )
   1.150 +        {
   1.151 +            int comp;
   1.152 +
   1.153 +            if( (node_pt)0 == *w )
   1.154 +            {
   1.155 +                *w = n;
   1.156 +                break;
   1.157 +            }
   1.158 +
   1.159 +            comp = strcmp((*w)->value, n->value);
   1.160 +            if( comp < 0 ) w = &(*w)->next;
   1.161 +            else w = &(*w)->prev;
   1.162 +        }
   1.163 +    }
   1.164 +
   1.165 +    (void)fclose(fp);
   1.166 +
   1.167 +    dump(name, head, mf, debug);
   1.168 +
   1.169 +    rv = PR_GetMallocCount();
   1.170 +    PR_ClearMallocCountdown();
   1.171 +
   1.172 +    release(head);
   1.173 +
   1.174 +    return rv;
   1.175 +}
   1.176 +
   1.177 +int nf = 0;
   1.178 +int debug = 0;
   1.179 +
   1.180 +void
   1.181 +test
   1.182 +(
   1.183 +    const char *name
   1.184 +)
   1.185 +{
   1.186 +    int n, i;
   1.187 +
   1.188 +    extern int nf, debug;
   1.189 +
   1.190 +    printf("[%s]: starting test 0\n", name);
   1.191 +    n = t2(name, 0, debug);
   1.192 +    if( -1 == n ) return;
   1.193 +    printf("[%s]: test 0 had %ld allocations.\n", name, n);
   1.194 +
   1.195 +    if( 0 >= n ) return;
   1.196 +
   1.197 +    for( i = 0; i < nf; i++ )
   1.198 +    {
   1.199 +        int which = rand() % n;
   1.200 +        if( 0 == which ) printf("[%s]: starting test %d -- no allocation should fail\n", name, i+1);
   1.201 +        else printf("[%s]: starting test %d -- allocation %d should fail\n", name, i+1, which);
   1.202 +        (void)t2(name, which, debug);
   1.203 +        printf("[%s]: test %d done.\n", name, i+1);
   1.204 +    }
   1.205 +
   1.206 +    return;
   1.207 +}
   1.208 +
   1.209 +int main(int argc, char **argv)
   1.210 +{
   1.211 +    int okay = 0;
   1.212 +    int multithread = 0;
   1.213 +
   1.214 +    struct threadlist
   1.215 +    {
   1.216 +        struct threadlist *next;
   1.217 +        PRThread *thread;
   1.218 +    }
   1.219 +        *threadhead = (struct threadlist *)0;
   1.220 +
   1.221 +    extern int nf, debug;
   1.222 +
   1.223 +    srand(time(0));
   1.224 +
   1.225 +    PR_Init(PR_USER_THREAD, PR_PRIORITY_NORMAL, 0);
   1.226 +    PR_STDIO_INIT();
   1.227 +
   1.228 +    printf("[main]: We %s using the debugging malloc.\n",
   1.229 +           PR_IsDebuggingMalloc() ? "ARE" : "ARE NOT");
   1.230 +
   1.231 +    while( argv++, --argc )
   1.232 +    {
   1.233 +        if( '-' == argv[0][0] )
   1.234 +        {
   1.235 +            switch( argv[0][1] )
   1.236 +            {
   1.237 +                case 'f':
   1.238 +                    nf = atoi(argv[0][2] ? &argv[0][2] :
   1.239 +                              --argc ? *++argv : "0");
   1.240 +                    break;
   1.241 +                case 'd':
   1.242 +                    debug = 1;
   1.243 +                    break;
   1.244 +                case 'n':
   1.245 +                    debug = 0;
   1.246 +                    break;
   1.247 +                case 'm':
   1.248 +                    multithread = 1;
   1.249 +                    break;
   1.250 +                case 's':
   1.251 +                    multithread = 0;
   1.252 +                    break;
   1.253 +                default:
   1.254 +                    usage();
   1.255 +                    break;
   1.256 +            }
   1.257 +        }
   1.258 +        else
   1.259 +        {
   1.260 +            FILE *fp = fopen(*argv, "r");
   1.261 +            if( (FILE *)0 == fp )
   1.262 +            {
   1.263 +                fprintf(stderr, "Cannot open \"%s.\"\n", *argv);
   1.264 +                continue;
   1.265 +            }
   1.266 +
   1.267 +            okay++;
   1.268 +            (void)fclose(fp);
   1.269 +            if( multithread )
   1.270 +            {
   1.271 +                struct threadlist *n;
   1.272 +
   1.273 +                n = (struct threadlist *)malloc(sizeof(struct threadlist));
   1.274 +                if( (struct threadlist *)0 == n ) 
   1.275 +                {
   1.276 +                    fprintf(stderr, "This is getting tedious. \"%s\"\n", *argv);
   1.277 +                    continue;
   1.278 +                }
   1.279 +
   1.280 +                n->next = threadhead;
   1.281 +                n->thread = PR_CreateThread(PR_USER_THREAD, (void (*)(void *))test, 
   1.282 +                                            *argv, PR_PRIORITY_NORMAL, 
   1.283 +                                            PR_LOCAL_THREAD, PR_JOINABLE_THREAD,
   1.284 +                                            0);
   1.285 +                if( (PRThread *)0 == n->thread )
   1.286 +                {
   1.287 +                    fprintf(stderr, "Can't create thread for \"%s.\"\n", *argv);
   1.288 +                    continue;
   1.289 +                }
   1.290 +                else
   1.291 +                {
   1.292 +                    threadhead = n;
   1.293 +                }
   1.294 +            }
   1.295 +            else
   1.296 +            {
   1.297 +                test(*argv);
   1.298 +            }
   1.299 +        }
   1.300 +    }
   1.301 +
   1.302 +    if( okay == 0 ) usage();
   1.303 +    else while( (struct threadlist *)0 != threadhead )
   1.304 +    {
   1.305 +        struct threadlist *x = threadhead->next;
   1.306 +        (void)PR_JoinThread(threadhead->thread);
   1.307 +        PR_DELETE(threadhead);
   1.308 +        threadhead = x;
   1.309 +    }
   1.310 +
   1.311 +    return 0;
   1.312 +}
   1.313 +

mercurial