tor-browser

The Tor Browser
git clone https://git.dasho.dev/tor-browser.git
Log | Files | Refs | README | LICENSE

dbmalloc.c (6499B)


      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/. */
      5 
      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
     15 *test.
     16 **           The regress mode will be the default mode. Since the regress tool
     17 *limits
     18 **           the output to a one line status:PASS or FAIL,all of the printf
     19 *statements
     20 **           have been handled with an if (debug_mode) statement.
     21 ***********************************************************************/
     22 #include <stdio.h>
     23 #include <stdlib.h>
     24 #include <time.h>
     25 #include <string.h>
     26 #include "nspr.h"
     27 
     28 void usage(void) {
     29  fprintf(stderr,
     30          "Usage: dbmalloc ('-m'|'-s') '-f' num_fails ('-d'|'-n') filename "
     31          "[...]\n");
     32  exit(0);
     33 }
     34 
     35 typedef struct node_struct {
     36  struct node_struct *next, *prev;
     37  int line;
     38  char value[4];
     39 } node_t, *node_pt;
     40 
     41 node_pt get_node(const char* line) {
     42  node_pt rv;
     43  int l = strlen(line);
     44  rv = (node_pt)PR_MALLOC(sizeof(node_t) + l + 1 - 4);
     45  if ((node_pt)0 == rv) {
     46    return (node_pt)0;
     47  }
     48  memcpy(&rv->value[0], line, l + 1);
     49  rv->next = rv->prev = (node_pt)0;
     50  return rv;
     51 }
     52 
     53 void dump(const char* name, node_pt node, int mf, int debug) {
     54  if ((node_pt)0 != node->prev) {
     55    dump(name, node->prev, mf, debug);
     56  }
     57  if (0 != debug) {
     58    printf("[%s]: %6d: %s", name, node->line, node->value);
     59  }
     60  if (node->line == mf) {
     61    fprintf(stderr, "[%s]: Line %d was allocated!\n", name, node->line);
     62  }
     63  if ((node_pt)0 != node->next) {
     64    dump(name, node->next, mf, debug);
     65  }
     66  return;
     67 }
     68 
     69 void release(node_pt node) {
     70  if ((node_pt)0 != node->prev) {
     71    release(node->prev);
     72  }
     73  if ((node_pt)0 != node->next) {
     74    release(node->next);
     75  }
     76  PR_DELETE(node);
     77 }
     78 
     79 int t2(const char* name, int mf, int debug) {
     80  int rv;
     81  FILE* fp;
     82  int l = 0;
     83  node_pt head = (node_pt)0;
     84  char buffer[BUFSIZ];
     85 
     86  fp = fopen(name, "r");
     87  if ((FILE*)0 == fp) {
     88    fprintf(stderr, "[%s]: Cannot open \"%s.\"\n", name, name);
     89    return -1;
     90  }
     91 
     92  /* fgets mallocs a buffer, first time through. */
     93  if ((char*)0 == fgets(buffer, BUFSIZ, fp)) {
     94    fprintf(stderr, "[%s]: \"%s\" is empty.\n", name, name);
     95    (void)fclose(fp);
     96    return -1;
     97  }
     98 
     99  rewind(fp);
    100 
    101  if (PR_SUCCESS != PR_ClearMallocCount()) {
    102    fprintf(stderr, "[%s]: Cannot clear malloc count.\n", name);
    103    (void)fclose(fp);
    104    return -1;
    105  }
    106 
    107  if (PR_SUCCESS != PR_SetMallocCountdown(mf)) {
    108    fprintf(stderr, "[%s]: Cannot set malloc countdown to %d\n", name, mf);
    109    (void)fclose(fp);
    110    return -1;
    111  }
    112 
    113  while (fgets(buffer, BUFSIZ, fp)) {
    114    node_pt n;
    115    node_pt* w = &head;
    116 
    117    if ((strlen(buffer) == (BUFSIZ - 1)) && (buffer[BUFSIZ - 2] != '\n')) {
    118      buffer[BUFSIZ - 2] == '\n';
    119    }
    120 
    121    l++;
    122 
    123    n = get_node(buffer);
    124    if ((node_pt)0 == n) {
    125      printf("[%s]: Line %d: malloc failure!\n", name, l);
    126      continue;
    127    }
    128 
    129    n->line = l;
    130 
    131    while (1) {
    132      int comp;
    133 
    134      if ((node_pt)0 == *w) {
    135        *w = n;
    136        break;
    137      }
    138 
    139      comp = strcmp((*w)->value, n->value);
    140      if (comp < 0) {
    141        w = &(*w)->next;
    142      } else {
    143        w = &(*w)->prev;
    144      }
    145    }
    146  }
    147 
    148  (void)fclose(fp);
    149 
    150  dump(name, head, mf, debug);
    151 
    152  rv = PR_GetMallocCount();
    153  PR_ClearMallocCountdown();
    154 
    155  release(head);
    156 
    157  return rv;
    158 }
    159 
    160 int nf = 0;
    161 int debug = 0;
    162 
    163 void test(const char* name) {
    164  int n, i;
    165 
    166  extern int nf, debug;
    167 
    168  printf("[%s]: starting test 0\n", name);
    169  n = t2(name, 0, debug);
    170  if (-1 == n) {
    171    return;
    172  }
    173  printf("[%s]: test 0 had %ld allocations.\n", name, n);
    174 
    175  if (0 >= n) {
    176    return;
    177  }
    178 
    179  for (i = 0; i < nf; i++) {
    180    int which = rand() % n;
    181    if (0 == which) {
    182      printf("[%s]: starting test %d -- no allocation should fail\n", name,
    183             i + 1);
    184    } else {
    185      printf("[%s]: starting test %d -- allocation %d should fail\n", name,
    186             i + 1, which);
    187    }
    188    (void)t2(name, which, debug);
    189    printf("[%s]: test %d done.\n", name, i + 1);
    190  }
    191 
    192  return;
    193 }
    194 
    195 int main(int argc, char** argv) {
    196  int okay = 0;
    197  int multithread = 0;
    198 
    199  struct threadlist {
    200    struct threadlist* next;
    201    PRThread* thread;
    202  }* threadhead = (struct threadlist*)0;
    203 
    204  extern int nf, debug;
    205 
    206  srand(time(0));
    207 
    208  PR_Init(PR_USER_THREAD, PR_PRIORITY_NORMAL, 0);
    209 
    210  printf("[main]: We %s using the debugging malloc.\n",
    211         PR_IsDebuggingMalloc() ? "ARE" : "ARE NOT");
    212 
    213  while (argv++, --argc) {
    214    if ('-' == argv[0][0]) {
    215      switch (argv[0][1]) {
    216        case 'f':
    217          nf = atoi(argv[0][2] ? &argv[0][2] : --argc ? *++argv : "0");
    218          break;
    219        case 'd':
    220          debug = 1;
    221          break;
    222        case 'n':
    223          debug = 0;
    224          break;
    225        case 'm':
    226          multithread = 1;
    227          break;
    228        case 's':
    229          multithread = 0;
    230          break;
    231        default:
    232          usage();
    233          break;
    234      }
    235    } else {
    236      FILE* fp = fopen(*argv, "r");
    237      if ((FILE*)0 == fp) {
    238        fprintf(stderr, "Cannot open \"%s.\"\n", *argv);
    239        continue;
    240      }
    241 
    242      okay++;
    243      (void)fclose(fp);
    244      if (multithread) {
    245        struct threadlist* n;
    246 
    247        n = (struct threadlist*)malloc(sizeof(struct threadlist));
    248        if ((struct threadlist*)0 == n) {
    249          fprintf(stderr, "This is getting tedious. \"%s\"\n", *argv);
    250          continue;
    251        }
    252 
    253        n->next = threadhead;
    254        n->thread = PR_CreateThread(PR_USER_THREAD, (void (*)(void*))test,
    255                                    *argv, PR_PRIORITY_NORMAL, PR_LOCAL_THREAD,
    256                                    PR_JOINABLE_THREAD, 0);
    257        if ((PRThread*)0 == n->thread) {
    258          fprintf(stderr, "Can't create thread for \"%s.\"\n", *argv);
    259          continue;
    260        } else {
    261          threadhead = n;
    262        }
    263      } else {
    264        test(*argv);
    265      }
    266    }
    267  }
    268 
    269  if (okay == 0) {
    270    usage();
    271  } else
    272    while ((struct threadlist*)0 != threadhead) {
    273      struct threadlist* x = threadhead->next;
    274      (void)PR_JoinThread(threadhead->thread);
    275      PR_DELETE(threadhead);
    276      threadhead = x;
    277    }
    278 
    279  return 0;
    280 }