nsprpub/pr/tests/dbmalloc.c

Fri, 16 Jan 2015 04:50:19 +0100

author
Michael Schloh von Bennewitz <michael@schloh.com>
date
Fri, 16 Jan 2015 04:50:19 +0100
branch
TOR_BUG_9701
changeset 13
44a2da4a2ab2
permissions
-rw-r--r--

Replace accessor implementation with direct member state manipulation, by
request https://trac.torproject.org/projects/tor/ticket/9701#comment:32

     1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
     2 /* This Source Code Form is subject to the terms of the Mozilla Public
     3  * License, v. 2.0. If a copy of the MPL was not distributed with this
     4  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
     6 /***********************************************************************
     7 **
     8 ** Name: dbmalloc.c
     9 **
    10 ** Description: Testing malloc (OBSOLETE)
    11 **
    12 ** Modification History:
    13 ** 14-May-97 AGarcia- Converted the test to accomodate the debug_mode flag.
    14 **	         The debug mode will print all of the printfs associated with this test.
    15 **			 The regress mode will be the default mode. Since the regress tool limits
    16 **           the output to a one line status:PASS or FAIL,all of the printf statements
    17 **			 have been handled with an if (debug_mode) statement. 
    18 ***********************************************************************/
    19 #include <stdio.h>
    20 #include <stdlib.h>
    21 #include <time.h>
    22 #include <string.h>
    23 #include "nspr.h"
    25 void
    26 usage
    27 (
    28     void
    29 )
    30 {
    31     fprintf(stderr, "Usage: dbmalloc ('-m'|'-s') '-f' num_fails ('-d'|'-n') filename [...]\n");
    32     exit(0);
    33 }
    35 typedef struct node_struct
    36 {
    37     struct node_struct *next, *prev;
    38     int line;
    39     char value[4];
    40 }
    41     node_t,
    42    *node_pt;
    44 node_pt get_node(const char *line)
    45 {
    46     node_pt rv;
    47     int l = strlen(line);
    48     rv = (node_pt)PR_MALLOC(sizeof(node_t) + l + 1 - 4);
    49     if( (node_pt)0 == rv ) return (node_pt)0;
    50     memcpy(&rv->value[0], line, l+1);
    51     rv->next = rv->prev = (node_pt)0;
    52     return rv;
    53 }
    55 void
    56 dump
    57 (
    58     const char *name,
    59     node_pt     node,
    60     int         mf,
    61     int         debug
    62 )
    63 {
    64     if( (node_pt)0 != node->prev ) dump(name, node->prev, mf, debug);
    65     if( 0 != debug ) printf("[%s]: %6d: %s", name, node->line, node->value);
    66     if( node->line == mf ) fprintf(stderr, "[%s]: Line %d was allocated!\n", name, node->line);
    67     if( (node_pt)0 != node->next ) dump(name, node->next, mf, debug);
    68     return;
    69 }
    71 void
    72 release
    73 (
    74     node_pt node
    75 )
    76 {
    77     if( (node_pt)0 != node->prev ) release(node->prev);
    78     if( (node_pt)0 != node->next ) release(node->next);
    79     PR_DELETE(node);
    80 }
    82 int
    83 t2
    84 (
    85     const char *name,
    86     int         mf,
    87     int         debug
    88 )
    89 {
    90     int rv;
    91     FILE *fp;
    92     int l = 0;
    93     node_pt head = (node_pt)0;
    94     char buffer[ BUFSIZ ];
    96     fp = fopen(name, "r");
    97     if( (FILE *)0 == fp )
    98     {
    99         fprintf(stderr, "[%s]: Cannot open \"%s.\"\n", name, name);
   100         return -1;
   101     }
   103     /* fgets mallocs a buffer, first time through. */
   104     if( (char *)0 == fgets(buffer, BUFSIZ, fp) )
   105     {
   106         fprintf(stderr, "[%s]: \"%s\" is empty.\n", name, name);
   107         (void)fclose(fp);
   108         return -1;
   109     }
   111     rewind(fp);
   113     if( PR_SUCCESS != PR_ClearMallocCount() )
   114     {
   115         fprintf(stderr, "[%s]: Cannot clear malloc count.\n", name);
   116         (void)fclose(fp);
   117         return -1;
   118     }
   120     if( PR_SUCCESS != PR_SetMallocCountdown(mf) )
   121     {
   122         fprintf(stderr, "[%s]: Cannot set malloc countdown to %d\n", name, mf);
   123         (void)fclose(fp);
   124         return -1;
   125     }
   127     while( fgets(buffer, BUFSIZ, fp) )
   128     {
   129         node_pt n;
   130         node_pt *w = &head;
   132         if( (strlen(buffer) == (BUFSIZ-1)) && (buffer[BUFSIZ-2] != '\n') )
   133             buffer[BUFSIZ-2] == '\n';
   135         l++;
   137         n = get_node(buffer);
   138         if( (node_pt)0 == n ) 
   139         {
   140             printf("[%s]: Line %d: malloc failure!\n", name, l);
   141             continue;
   142         }
   144         n->line = l;
   146         while( 1 )
   147         {
   148             int comp;
   150             if( (node_pt)0 == *w )
   151             {
   152                 *w = n;
   153                 break;
   154             }
   156             comp = strcmp((*w)->value, n->value);
   157             if( comp < 0 ) w = &(*w)->next;
   158             else w = &(*w)->prev;
   159         }
   160     }
   162     (void)fclose(fp);
   164     dump(name, head, mf, debug);
   166     rv = PR_GetMallocCount();
   167     PR_ClearMallocCountdown();
   169     release(head);
   171     return rv;
   172 }
   174 int nf = 0;
   175 int debug = 0;
   177 void
   178 test
   179 (
   180     const char *name
   181 )
   182 {
   183     int n, i;
   185     extern int nf, debug;
   187     printf("[%s]: starting test 0\n", name);
   188     n = t2(name, 0, debug);
   189     if( -1 == n ) return;
   190     printf("[%s]: test 0 had %ld allocations.\n", name, n);
   192     if( 0 >= n ) return;
   194     for( i = 0; i < nf; i++ )
   195     {
   196         int which = rand() % n;
   197         if( 0 == which ) printf("[%s]: starting test %d -- no allocation should fail\n", name, i+1);
   198         else printf("[%s]: starting test %d -- allocation %d should fail\n", name, i+1, which);
   199         (void)t2(name, which, debug);
   200         printf("[%s]: test %d done.\n", name, i+1);
   201     }
   203     return;
   204 }
   206 int main(int argc, char **argv)
   207 {
   208     int okay = 0;
   209     int multithread = 0;
   211     struct threadlist
   212     {
   213         struct threadlist *next;
   214         PRThread *thread;
   215     }
   216         *threadhead = (struct threadlist *)0;
   218     extern int nf, debug;
   220     srand(time(0));
   222     PR_Init(PR_USER_THREAD, PR_PRIORITY_NORMAL, 0);
   223     PR_STDIO_INIT();
   225     printf("[main]: We %s using the debugging malloc.\n",
   226            PR_IsDebuggingMalloc() ? "ARE" : "ARE NOT");
   228     while( argv++, --argc )
   229     {
   230         if( '-' == argv[0][0] )
   231         {
   232             switch( argv[0][1] )
   233             {
   234                 case 'f':
   235                     nf = atoi(argv[0][2] ? &argv[0][2] :
   236                               --argc ? *++argv : "0");
   237                     break;
   238                 case 'd':
   239                     debug = 1;
   240                     break;
   241                 case 'n':
   242                     debug = 0;
   243                     break;
   244                 case 'm':
   245                     multithread = 1;
   246                     break;
   247                 case 's':
   248                     multithread = 0;
   249                     break;
   250                 default:
   251                     usage();
   252                     break;
   253             }
   254         }
   255         else
   256         {
   257             FILE *fp = fopen(*argv, "r");
   258             if( (FILE *)0 == fp )
   259             {
   260                 fprintf(stderr, "Cannot open \"%s.\"\n", *argv);
   261                 continue;
   262             }
   264             okay++;
   265             (void)fclose(fp);
   266             if( multithread )
   267             {
   268                 struct threadlist *n;
   270                 n = (struct threadlist *)malloc(sizeof(struct threadlist));
   271                 if( (struct threadlist *)0 == n ) 
   272                 {
   273                     fprintf(stderr, "This is getting tedious. \"%s\"\n", *argv);
   274                     continue;
   275                 }
   277                 n->next = threadhead;
   278                 n->thread = PR_CreateThread(PR_USER_THREAD, (void (*)(void *))test, 
   279                                             *argv, PR_PRIORITY_NORMAL, 
   280                                             PR_LOCAL_THREAD, PR_JOINABLE_THREAD,
   281                                             0);
   282                 if( (PRThread *)0 == n->thread )
   283                 {
   284                     fprintf(stderr, "Can't create thread for \"%s.\"\n", *argv);
   285                     continue;
   286                 }
   287                 else
   288                 {
   289                     threadhead = n;
   290                 }
   291             }
   292             else
   293             {
   294                 test(*argv);
   295             }
   296         }
   297     }
   299     if( okay == 0 ) usage();
   300     else while( (struct threadlist *)0 != threadhead )
   301     {
   302         struct threadlist *x = threadhead->next;
   303         (void)PR_JoinThread(threadhead->thread);
   304         PR_DELETE(threadhead);
   305         threadhead = x;
   306     }
   308     return 0;
   309 }

mercurial