ccache: applied a number of patches from the ccache-win32 issue tracker
[msysgit.git] / src / ccache-win32 / patches / 0005-ccache-on-win32-crashes-sometimes.patch
blob7972dd71a7fbda5c40bdb6c5951390b2291eb392
1 From 5e1ddeddca818e4f9785fb1d47c930df05e5dfcc Mon Sep 17 00:00:00 2001
2 From: Pat Thoyts <patthoyts@users.sourceforge.net>
3 Date: Wed, 15 May 2013 13:15:51 +0100
4 Subject: [PATCH] ccache on win32 crashes sometimes
6 Compiling a more or less large project under Windows XP with ccache-2.4-
7 win32 aborts with a crash dialog ("send problem report to microsoft" -
8 dialog) in irregular intervals.
10 I could trace the problem to the x_realloc code, which looks like this:
13 this is like realloc() but dies if the malloc fails
15 void *x_realloc(void *ptr, size_t size)
17 void *p2;
18 if (!ptr) return x_malloc(size);
19 p2 = malloc(size);
20 if (!p2) {
21 fatal("out of memory in x_realloc");
23 if (ptr) {
24 memcpy(p2, ptr, size);
25 free(ptr);
27 return p2;
30 Suppose ptr points to a 100 bytes area of memory and you
31 reallocate this to 1000000 bytes. Then this line
33 memcpy(p2, ptr, size);
35 will copy 1000000 bytes of data from the old to the new
36 location, which means that memcpy will read memory far
37 outside the original allocated area.
39 [ccache-win32 issue #8]
41 Signed-off-by: Pat Thoyts <patthoyts@users.sourceforge.net>
42 ---
43 args.c | 11 ++++++++---
44 ccache.h | 3 ++-
45 cleanup.c | 6 +++++-
46 util.c | 4 ++--
47 4 files changed, 17 insertions(+), 7 deletions(-)
49 diff --git a/args.c b/args.c
50 index 31e5471..edbde7f 100644
51 --- a/args.c
52 +++ b/args.c
53 @@ -26,7 +26,8 @@ ARGS *args_init(int init_argc, char **init_args)
54 int i;
55 args = (ARGS *)x_malloc(sizeof(ARGS));
56 args->argc = 0;
57 - args->argv = (char **)x_malloc(sizeof(char *));
58 + args->argvSize = sizeof(char *);
59 + args->argv = (char **)x_malloc(args->argvSize);
60 args->argv[0] = NULL;
61 for (i=0;i<init_argc;i++) {
62 args_add(args, init_args[i]);
63 @@ -37,7 +38,9 @@ ARGS *args_init(int init_argc, char **init_args)
65 void args_add(ARGS *args, const char *s)
67 - args->argv = (char**)x_realloc(args->argv, (args->argc + 2) * sizeof(char *));
68 + size_t size = (args->argc + 2) * sizeof(char *);
69 + args->argv = (char**)x_realloc(args->argv, size, args->argvSize);
70 + args->argvSize = size;
71 args->argv[args->argc] = x_strdup(s);
72 args->argc++;
73 args->argv[args->argc] = NULL;
74 @@ -66,7 +69,9 @@ void args_remove_first(ARGS *args)
75 /* add an argument into the front of the argument list */
76 void args_add_prefix(ARGS *args, const char *s)
78 - args->argv = (char**)x_realloc(args->argv, (args->argc + 2) * sizeof(char *));
79 + size_t size = (args->argc + 2) * sizeof(char *);
80 + args->argv = (char**)x_realloc(args->argv, size, args->argvSize);
81 + args->argvSize = size;
82 memmove(&args->argv[1], &args->argv[0],
83 (args->argc+1) * sizeof(args->argv[0]));
84 args->argv[0] = x_strdup(s);
85 diff --git a/ccache.h b/ccache.h
86 index d512e78..e65888d 100644
87 --- a/ccache.h
88 +++ b/ccache.h
89 @@ -95,7 +95,7 @@ int copy_file(const char *src, const char *dest);
90 int create_dir(const char *dir);
91 void x_asprintf(char **ptr, const char *format, ...);
92 char *x_strdup(const char *s);
93 -void *x_realloc(void *ptr, size_t size);
94 +void *x_realloc(void *ptr, size_t size, size_t oldSize);
95 void *x_malloc(size_t size);
96 void traverse(const char *dir, void (*fn)(const char *, struct stat *));
97 char *str_basename(const char *s);
98 @@ -143,6 +143,7 @@ char *find_executable(const char *name, const char *exclude_name);
99 typedef struct {
100 char **argv;
101 int argc;
102 + size_t argvSize;
103 } ARGS;
106 diff --git a/cleanup.c b/cleanup.c
107 index 9931228..1956e04 100644
108 --- a/cleanup.c
109 +++ b/cleanup.c
110 @@ -49,6 +49,7 @@ static int files_compare(struct files **f1, struct files **f2)
111 static void traverse_fn(const char *fname, struct stat *st)
113 char *p;
114 + unsigned oldAllocated;
116 if (!S_ISREG(st->st_mode)) return;
118 @@ -60,9 +61,11 @@ static void traverse_fn(const char *fname, struct stat *st)
119 free(p);
121 if (num_files == allocated) {
122 + oldAllocated = allocated;
123 allocated = 10000 + num_files*2;
124 files = (struct files **)x_realloc(files,
125 - sizeof(struct files *)*allocated);
126 + sizeof(struct files *)*allocated,
127 + sizeof(struct files *)*oldAllocated);
130 files[num_files] = (struct files *)x_malloc(sizeof(struct files));
131 @@ -111,6 +114,7 @@ void cleanup_dir(const char *dir, size_t maxfiles, size_t maxsize)
132 files_threshold = maxfiles * LIMIT_MULTIPLE;
134 num_files = 0;
135 + allocated = 0;
136 total_size = 0;
138 /* build a list of files */
139 diff --git a/util.c b/util.c
140 index 54fae89..531883d 100644
141 --- a/util.c
142 +++ b/util.c
143 @@ -200,7 +200,7 @@ void *x_malloc(size_t size)
145 this is like realloc() but dies if the malloc fails
147 -void *x_realloc(void *ptr, size_t size)
148 +void *x_realloc(void *ptr, size_t size, size_t oldSize)
150 void *p2;
151 if (!ptr) return x_malloc(size);
152 @@ -209,7 +209,7 @@ void *x_realloc(void *ptr, size_t size)
153 fatal("out of memory in x_realloc");
155 if (ptr) {
156 - memcpy(p2, ptr, size);
157 + memcpy(p2, ptr, ((oldSize < size) ? oldSize : size));
158 free(ptr);
160 return p2;
162 1.8.1.msysgit.1