Skip to content

Commit a6dde77

Browse files
committed
fix bug that causes premature pops from obstack
basically, the alignment step did not check if it walked off the end of the buffer
1 parent 5f8e0dd commit a6dde77

File tree

1 file changed

+21
-9
lines changed

1 file changed

+21
-9
lines changed

src/rt/rust_obstack.cpp

Lines changed: 21 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,7 @@
1818
#endif
1919

2020
#undef DPRINT
21-
#define DPRINT(fmt, ...)
21+
#define DPRINT(fmt, ...)
2222

2323
const size_t DEFAULT_CHUNK_SIZE = 128;
2424
const size_t MAX_CHUNK_SIZE = (1024*64);
@@ -38,16 +38,20 @@ struct rust_obstack_alloc {
3838

3939
void *
4040
rust_obstack_chunk::alloc(size_t len, type_desc *tydesc) {
41-
alen = align_to(alen, DEFAULT_ALIGNMENT);
41+
DPRINT("alloc(%lu) alen=%lu size=%lu\n", len, alen, size);
4242

43-
if (sizeof(rust_obstack_alloc) + len > size - alen) {
44-
DPRINT("Not enough space, len=%lu!\n", len);
43+
size_t aligned_alen = align_to(alen, DEFAULT_ALIGNMENT);
44+
size_t end_alen = aligned_alen + sizeof(rust_obstack_alloc) + len;
45+
if (end_alen > size) {
46+
DPRINT("Not enough space, len=%lu alen=%lu aligned=%lu end=%lu!\n",
47+
len, alen, aligned_alen, end_alen);
4548
return NULL; // Not enough space.
4649
}
4750

48-
rust_obstack_alloc *a = new(data + alen) rust_obstack_alloc(len, tydesc);
49-
alen += sizeof(*a) + len;
51+
rust_obstack_alloc *a =
52+
new(data + aligned_alen) rust_obstack_alloc(len, tydesc);
5053
memset(a->data, '\0', len); // FIXME: For GC.
54+
alen = end_alen;
5155
return &a->data;
5256
}
5357

@@ -63,7 +67,9 @@ rust_obstack_chunk::free(void *ptr) {
6367

6468
void *
6569
rust_obstack_chunk::mark() {
66-
return data + alen;
70+
uint8_t *m = data + alen;
71+
assert (m >= data && m <= data+size);
72+
return m;
6773
}
6874

6975
// Allocates the given number of bytes in a new chunk.
@@ -109,7 +115,9 @@ rust_obstack::free(void *ptr) {
109115

110116
assert(chunk);
111117
while (!chunk->free(ptr)) {
112-
DPRINT("deleting chunk at %p\n", chunk);
118+
DPRINT("deleting chunk at %p (ptr=%p, data=%p-%p)\n",
119+
chunk, ptr,
120+
chunk->data, chunk->data + chunk->size);
113121
rust_obstack_chunk *prev = chunk->prev;
114122
task->free(chunk);
115123
chunk = prev;
@@ -119,7 +127,11 @@ rust_obstack::free(void *ptr) {
119127

120128
void *
121129
rust_obstack::mark() {
122-
return chunk ? chunk->mark() : NULL;
130+
void *m = chunk ? chunk->mark() : NULL;
131+
DPRINT("mark == %p, chunk == %p, data == %p-%p\n", m, chunk,
132+
(chunk ? chunk->data : NULL),
133+
(chunk ? chunk->data + chunk->size : NULL));
134+
return m;
123135
}
124136

125137

0 commit comments

Comments
 (0)