Thu, 15 Jan 2015 15:59:08 +0100
Implement a real Private Browsing Mode condition by changing the API/ABI;
This solves Tor bug #9701, complying with disk avoidance documented in
https://www.torproject.org/projects/torbrowser/design/#disk-avoidance.
1 /* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*-
2 *
3 * This Source Code Form is subject to the terms of the Mozilla Public
4 * License, v. 2.0. If a copy of the MPL was not distributed with this
5 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
6 #include <stdio.h>
7 #include <stdlib.h>
8 #include <string.h>
9 #include <errno.h>
10 #ifdef HAVE_GETOPT_H
11 #include <getopt.h>
12 #else
13 extern int getopt(int argc, char *const *argv, const char *shortopts);
14 extern char *optarg;
15 extern int optind;
16 #ifdef XP_WIN32
17 int optind=1;
18 #endif
19 #endif
20 #include <time.h>
21 #include "nsTraceMalloc.h"
22 #include "tmreader.h"
23 #include "prlog.h"
25 static char *program;
27 typedef struct handler_data {
28 uint32_t current_heapsize;
29 uint32_t max_heapsize;
30 uint32_t bytes_allocated;
31 uint32_t current_allocations;
32 uint32_t total_allocations;
33 uint32_t unmatched_frees;
34 int finished;
35 } handler_data;
37 static void handler_data_init(handler_data *data)
38 {
39 data->current_heapsize = 0;
40 data->max_heapsize = 0;
41 data->bytes_allocated = 0;
42 data->current_allocations = 0;
43 data->total_allocations = 0;
44 data->unmatched_frees = 0;
45 data->finished = 0;
46 }
48 static void handler_data_finish(handler_data *data)
49 {
50 }
52 static void my_tmevent_handler(tmreader *tmr, tmevent *event)
53 {
54 handler_data *data = (handler_data*) tmr->data;
56 switch (event->type) {
57 case TM_EVENT_REALLOC:
58 /* On Windows, original allocation could be before we overrode malloc */
59 if (event->u.alloc.oldserial != 0) {
60 data->current_heapsize -= event->u.alloc.oldsize;
61 --data->current_allocations;
62 } else {
63 ++data->unmatched_frees;
64 PR_ASSERT(event->u.alloc.oldsize == 0);
65 }
66 /* fall-through intentional */
67 case TM_EVENT_MALLOC:
68 case TM_EVENT_CALLOC:
69 ++data->current_allocations;
70 ++data->total_allocations;
71 data->bytes_allocated += event->u.alloc.size;
72 data->current_heapsize += event->u.alloc.size;
73 if (data->current_heapsize > data->max_heapsize)
74 data->max_heapsize = data->current_heapsize;
75 break;
76 case TM_EVENT_FREE:
77 /* On Windows, original allocation could be before we overrode malloc */
78 if (event->serial != 0) {
79 --data->current_allocations;
80 data->current_heapsize -= event->u.alloc.size;
81 } else {
82 ++data->unmatched_frees;
83 PR_ASSERT(event->u.alloc.size == 0);
84 }
85 break;
86 case TM_EVENT_STATS:
87 data->finished = 1;
88 break;
89 }
90 }
93 int main(int argc, char **argv)
94 {
95 int i, j, rv;
96 tmreader *tmr;
97 FILE *fp;
98 time_t start;
99 handler_data data;
101 program = *argv;
103 handler_data_init(&data);
104 tmr = tmreader_new(program, &data);
105 if (!tmr) {
106 perror(program);
107 exit(1);
108 }
110 start = time(NULL);
111 fprintf(stdout, "%s starting at %s", program, ctime(&start));
112 fflush(stdout);
114 argc -= optind;
115 argv += optind;
116 if (argc == 0) {
117 if (tmreader_eventloop(tmr, "-", my_tmevent_handler) <= 0)
118 exit(1);
119 } else {
120 for (i = j = 0; i < argc; i++) {
121 fp = fopen(argv[i], "r");
122 if (!fp) {
123 fprintf(stderr,
124 "TEST-UNEXPECTED-FAIL | leakstats | can't open %s: %s\n",
125 argv[i], strerror(errno));
126 exit(1);
127 }
128 rv = tmreader_eventloop(tmr, argv[i], my_tmevent_handler);
129 if (rv < 0)
130 exit(1);
131 if (rv > 0)
132 j++;
133 fclose(fp);
134 }
135 if (j == 0)
136 exit(1);
137 }
139 if (!data.finished) {
140 fprintf(stderr, "TEST-UNEXPECTED-FAIL | leakstats | log file incomplete\n");
141 exit(1);
142 }
144 fprintf(stdout,
145 "Leaks: %u bytes, %u allocations\n"
146 "Maximum Heap Size: %u bytes\n"
147 "%u bytes were allocated in %u allocations.\n",
148 data.current_heapsize, data.current_allocations,
149 data.max_heapsize,
150 data.bytes_allocated, data.total_allocations);
151 if (data.unmatched_frees != 0)
152 fprintf(stdout,
153 "Logged %u free (or realloc) calls for which we missed the "
154 "original malloc.\n",
155 data.unmatched_frees);
157 handler_data_finish(&data);
158 tmreader_destroy(tmr);
160 exit(0);
161 }