diff options
author | Chris Liddell <chris.liddell@artifex.com> | 2016-09-07 11:33:28 +0100 |
---|---|---|
committer | Chris Liddell <chris.liddell@artifex.com> | 2016-09-13 16:23:26 +0100 |
commit | cd95789bc8eaf0e86f902c8ba3f796340ffdad25 (patch) | |
tree | d7e7a8aecfceb66e7d57c63e3f0c752699aa9f34 | |
parent | dbfde5f3400e97b6d9b71a6549ff419dcefc9a95 (diff) | |
download | ghostpdl-cd95789bc8eaf0e86f902c8ba3f796340ffdad25.tar.gz |
Ensure PCL/XPS free all their memory.
Noticed in passing (thrown up by ASAN): the plmain code was not fully shutting
down the memory manager when using the chunk allocator.
This commit adds a convenient function (gs_memory_chunk_wrap) and a
pl_alloc_finit() function to ensure that all happens.
-rw-r--r-- | base/gsmalloc.c | 3 | ||||
-rw-r--r-- | base/gsmchunk.c | 16 | ||||
-rw-r--r-- | base/gsmchunk.h | 7 | ||||
-rw-r--r-- | pcl/pl/plalloc.c | 7 | ||||
-rw-r--r-- | pcl/pl/plalloc.h | 1 | ||||
-rw-r--r-- | pcl/pl/plmain.c | 48 |
6 files changed, 65 insertions, 17 deletions
diff --git a/base/gsmalloc.c b/base/gsmalloc.c index 9a8a09c1d..e8e17c640 100644 --- a/base/gsmalloc.c +++ b/base/gsmalloc.c @@ -337,7 +337,8 @@ gs_heap_free_object(gs_memory_t * mem, void *ptr, client_name_t cname) bp->next->prev = bp->prev; if (bp == mmem->allocated) { mmem->allocated = bp->next; - mmem->allocated->prev = NULL; + if (mmem->allocated) + mmem->allocated->prev = NULL; } mmem->used -= bp->size + sizeof(gs_malloc_block_t); if (mmem->monitor) diff --git a/base/gsmchunk.c b/base/gsmchunk.c index 9bde4195e..b5a92eadc 100644 --- a/base/gsmchunk.c +++ b/base/gsmchunk.c @@ -175,6 +175,22 @@ gs_memory_chunk_release(gs_memory_t *mem) "gs_memory_chunk_release"); } +/* Release chunk memory manager, and return the target */ +gs_memory_t * /* Always succeeds */ +gs_memory_chunk_unwrap(gs_memory_t *mem) +{ + gs_memory_t *tmem; + + if (mem->procs.status != chunk_status) { + tmem = mem; + } + else { + tmem = ((gs_memory_chunk_t *)mem)->target; + gs_memory_chunk_release(mem); + } + return tmem; +} + /* ---------- Accessors ------------- */ /* Retrieve this allocator's target */ diff --git a/base/gsmchunk.h b/base/gsmchunk.h index e46bae8ed..3464b2e9a 100644 --- a/base/gsmchunk.h +++ b/base/gsmchunk.h @@ -31,6 +31,13 @@ int gs_memory_chunk_wrap(gs_memory_t **wrapped, /* chunk allocator init */ /* Release a chunk memory manager and all of the memory it held */ void gs_memory_chunk_release(gs_memory_t *cmem); +/* Release chunk memory manager, and return the target */ +/* if "mem" is not a chunk memory manager instance, "mem" + * is return untouched + */ +gs_memory_t * /* Always succeeds */ +gs_memory_chunk_unwrap(gs_memory_t *mem); + /* ---------- Accessors ------------- */ /* Retrieve this allocator's target */ diff --git a/pcl/pl/plalloc.c b/pcl/pl/plalloc.c index d5441fc1b..78ba094a0 100644 --- a/pcl/pl/plalloc.c +++ b/pcl/pl/plalloc.c @@ -42,3 +42,10 @@ pl_alloc_init() return pl_mem; } + +void +pl_alloc_finit(gs_memory_t *mem) +{ + gs_memory_t *tmem = gs_memory_chunk_unwrap(mem); + gs_malloc_release(tmem); +} diff --git a/pcl/pl/plalloc.h b/pcl/pl/plalloc.h index d919f8be8..0e540bf2b 100644 --- a/pcl/pl/plalloc.h +++ b/pcl/pl/plalloc.h @@ -16,3 +16,4 @@ /* initialize the gs allocator. */ gs_memory_t *pl_alloc_init(void); +void pl_alloc_finit(gs_memory_t *mem); diff --git a/pcl/pl/plmain.c b/pcl/pl/plmain.c index b58154191..499eda45c 100644 --- a/pcl/pl/plmain.c +++ b/pcl/pl/plmain.c @@ -257,6 +257,7 @@ pl_main_aux(int argc, char *argv[], void *disp) pl_interp_instance_t *curr_instance = 0; gs_c_param_list params; int (*arg_get_codepoint) (FILE * file, const char **astr) = NULL; + int code = 0; mem = pl_alloc_init(); @@ -303,7 +304,8 @@ pl_main_aux(int argc, char *argv[], void *disp) pjl_instance, &inst, &pl_pre_finish_page, &pl_post_finish_page) < 0) { errprintf(mem, "%s", err_buf); - return -1; + code = -1; + goto done; } #ifdef DEBUG if (gs_debug_c(':')) @@ -327,7 +329,8 @@ pl_main_aux(int argc, char *argv[], void *disp) if (pl_init_job(pjl_instance) < 0) { errprintf(mem, "Unable to init PJL job.\n"); - return -1; + code = -1; + goto done; } /* Process any new options. May request new device. */ @@ -360,7 +363,8 @@ pl_main_aux(int argc, char *argv[], void *disp) } errprintf(mem, "\n"); - return -1; + code = -1; + goto done; } if (!filename) @@ -384,7 +388,8 @@ pl_main_aux(int argc, char *argv[], void *disp) characteristics structure */ if (pl_main_cursor_open(mem, &r, filename, buf, sizeof(buf)) < 0) { errprintf(mem, "Unable to open %s for reading.\n", filename); - return -1; + code = -1; + goto done; } #ifdef DEBUG @@ -407,7 +412,8 @@ pl_main_aux(int argc, char *argv[], void *disp) pl_process_eof(curr_instance); if (close_job(&universe, &inst) < 0) { dmprintf(mem, "Unable to deinit PDL job.\n"); - return -1; + code = -1; + goto done; } } break; @@ -424,7 +430,8 @@ pl_main_aux(int argc, char *argv[], void *disp) if (new_job) { if (mem->gs_lib_ctx->gs_next_id > 0xFF000000) { dmprintf(mem, "Once a year reset the gs_next_id.\n"); - return -1; + code = -1; + goto done; } if_debug0m('I', mem, "Selecting PDL\n"); @@ -437,12 +444,14 @@ pl_main_aux(int argc, char *argv[], void *disp) params); if (curr_instance == NULL) { errprintf(mem, "%s", err_buf); - return -1; + code = -1; + goto done; } if (pl_init_job(curr_instance) < 0) { dmprintf(mem, "Unable to init PDL job.\n"); - return -1; + code = -1; + goto done; } if_debug1m('I', mem, "selected and initializing (%s)\n", pl_characteristics(curr_instance->interp-> @@ -484,11 +493,13 @@ pl_main_aux(int argc, char *argv[], void *disp) implementation)->language); if (close_job(&universe, &inst) < 0) { dmprintf(mem, "Unable to deinit PDL job.\n"); - return -1; + code = -1; + goto done; } if (pl_init_job(pjl_instance) < 0) { dmprintf(mem, "Unable to init PJL job.\n"); - return -1; + code = -1; + goto done; } pl_renew_cursor_status(&r); } else if (code < 0) { /* error and not exit language */ @@ -517,7 +528,8 @@ pl_main_aux(int argc, char *argv[], void *disp) inst.error_report > 0); if (close_job(&universe, &inst) < 0) { dmprintf(mem, "Unable to deinit PJL.\n"); - return -1; + code = -1; + goto done; } /* Print PDL status if applicable, then dnit PDL job */ code = 0; @@ -538,7 +550,8 @@ pl_main_aux(int argc, char *argv[], void *disp) if (gx_saved_pages_param_process((gx_device_printer *)pdev, (byte *)"print normal flush", 18) < 0) { errprintf(mem, "Unable to print saved-pages.\n"); - return -1; + code = -1; + goto done; } } /* release param list */ @@ -546,13 +559,15 @@ pl_main_aux(int argc, char *argv[], void *disp) /* Dnit PDLs */ if (pl_main_universe_dnit(&universe, err_buf)) { errprintf(mem, "%s", err_buf); - return -1; + code = -1; + goto done; } /* dnit pjl */ if (pl_deallocate_interp_instance(pjl_instance) < 0 || pl_deallocate_interp(pjl_interp) < 0) { dmprintf(mem, "Unable to close out PJL instance.\n"); - return -1; + code = -1; + goto done; } /* We lost the ability to print peak memory usage with the loss @@ -563,8 +578,9 @@ pl_main_aux(int argc, char *argv[], void *disp) if (gs_debug_c('A')) dmprintf(mem, "Final time"); pl_platform_dnit(0); - gs_malloc_release(mem); - return 0; + pl_alloc_finit(mem); +done: + return code; } GSDLLEXPORT int GSDLLAPI |