From 9c7408051273499201290a52edb4fa0d73abe2f5 Mon Sep 17 00:00:00 2001 From: Vitor Santos Costa Date: Tue, 28 Jul 2009 18:30:15 -0500 Subject: [PATCH] fix memory overflow when doing very large writes on strings (obs from Jos Deroo). --- C/iopreds.c | 31 ++++++++++++++++++++++++++----- C/tracer.c | 4 ---- H/iopreds.h | 4 ++++ 3 files changed, 30 insertions(+), 9 deletions(-) diff --git a/C/iopreds.c b/C/iopreds.c index 87a424d28..b501ff9b1 100644 --- a/C/iopreds.c +++ b/C/iopreds.c @@ -742,13 +742,21 @@ MemPutc(int sno, int ch) } #endif s->u.mem_string.buf[s->u.mem_string.pos++] = ch; - if (s->u.mem_string.pos == s->u.mem_string.max_size) { + if (s->u.mem_string.pos >= s->u.mem_string.max_size -256) { extern int Yap_page_size; + int old_src = s->u.mem_string.src, new_src; + /* oops, we have reached an overflow */ Int new_max_size = s->u.mem_string.max_size + Yap_page_size; char *newbuf; - if ((newbuf = Yap_AllocAtomSpace(new_max_size*sizeof(char))) == NULL) { + if ((newbuf = Yap_AllocAtomSpace(new_max_size*sizeof(char))) != NULL) { + new_src = MEM_BUF_CODE; +#if !USE_SYSTEM_MALLOC + } else if ((newbuf = (ADDR)malloc(new_max_size*sizeof(char))) != NULL) { + new_src = MEM_BUF_MALLOC; +#endif + } else { if (Stream[sno].u.mem_string.error_handler) { Yap_Error_Size = new_max_size*sizeof(char); save_machine_regs(); @@ -770,9 +778,14 @@ MemPutc(int sno, int ch) } } #endif - Yap_FreeAtomSpace(s->u.mem_string.buf); + if (old_src == MEM_BUF_CODE) { + Yap_FreeAtomSpace(s->u.mem_string.buf); + } else { + free(s->u.mem_string.buf); + } s->u.mem_string.buf = newbuf; s->u.mem_string.max_size = new_max_size; + s->u.mem_string.src = new_src; } count_output_char(ch,s); return ((int) ch); @@ -2740,6 +2753,7 @@ open_buf_read_stream(char *nbuf, Int nchars) st->u.mem_string.buf = nbuf; st->u.mem_string.max_size = nchars; st->u.mem_string.error_handler = NULL; + st->u.mem_string.src = MEM_BUF_CODE; return sno; } @@ -3235,7 +3249,11 @@ Yap_CloseStreams (int loud) } #endif else if (Stream[sno].status & InMemory_Stream_f) { - Yap_FreeAtomSpace(Stream[sno].u.mem_string.buf); + if (Stream[sno].u.mem_string.src == MEM_BUF_CODE) { + Yap_FreeAtomSpace(Stream[sno].u.mem_string.buf); + } else { + free(Stream[sno].u.mem_string.buf); + } } else if (!(Stream[sno].status & Null_Stream_f)) YP_fclose (Stream[sno].u.file.file); else { @@ -3272,7 +3290,10 @@ CloseStream(int sno) #endif } else if (Stream[sno].status & (InMemory_Stream_f)) { - Yap_FreeAtomSpace(Stream[sno].u.mem_string.buf); + if (Stream[sno].u.mem_string.src == MEM_BUF_CODE) + Yap_FreeAtomSpace(Stream[sno].u.mem_string.buf); + else + free(Stream[sno].u.mem_string.buf); } Stream[sno].status = Free_Stream_f; PurgeAlias(sno); diff --git a/C/tracer.c b/C/tracer.c index 362e6e854..4b91937ed 100644 --- a/C/tracer.c +++ b/C/tracer.c @@ -172,10 +172,6 @@ low_level_trace(yap_low_level_port port, PredEntry *pred, CELL *args) LOCK(Yap_heap_regs->low_level_trace_lock); sc = Yap_heap_regs; vsc_count++; - if (vsc_count < 50000) - return; - if (vsc_count == 50084) - jmp_deb(1); #ifdef THREADS Yap_heap_regs->thread_handle[worker_id].thread_inst_count++; #endif diff --git a/H/iopreds.h b/H/iopreds.h index 2bf2ec26a..3c3a04598 100644 --- a/H/iopreds.h +++ b/H/iopreds.h @@ -40,6 +40,9 @@ FILE *rl_instream, *rl_outstream; #endif +#define MEM_BUF_CODE 0 +#define MEM_BUF_MALLOC 1 + typedef int (*GetsFunc)(int, UInt, char *); typedef struct stream_desc @@ -57,6 +60,7 @@ typedef struct stream_desc } file; struct { char *buf; /* where the file is being read from/written to */ + int src; /* where the space comes from, 0 code space, 1 malloc */ Int max_size; /* maximum buffer size (may be changed dynamically) */ UInt pos; volatile void *error_handler;