summary | shortlog | log | commit | commitdiff | tree
raw | patch | inline | side by side (parent: 2def854)
raw | patch | inline | side by side (parent: 2def854)
author | Sebastian Harl <sh@tokkee.org> | |
Thu, 25 Sep 2008 22:26:52 +0000 (00:26 +0200) | ||
committer | Sebastian Harl <sh@tokkee.org> | |
Thu, 25 Sep 2008 22:26:52 +0000 (00:26 +0200) |
This fixes a couple of memory leaks in rrdtool, librrd and the Perl and Ruby
bindings.
Closes: #499349
bindings.
Closes: #499349
debian/changelog | patch | blob | history | |
debian/patches/bts499349-memleaks | [new file with mode: 0644] | patch | blob |
debian/patches/series | patch | blob | history |
diff --git a/debian/changelog b/debian/changelog
index 6d14f094c1adeab03f6a7db8aaf7b84144f48eb1..3b9b96ddc75f885656fe884ebe69c63050339943 100644 (file)
--- a/debian/changelog
+++ b/debian/changelog
valuable debugging information (Closes: #498183).
- Added upstream patch bts496847-error-handling to fix error handling of
syscalls in rrdtool(1) (Closes: #496847).
+ - Added upstream patch bts499349-memleaks to fix a couple of memory leaks
+ in rrdtool, librrd and the Perl and Ruby bindings (Closes: #499349).
* debian/NEWS:
- Added. Documented the changes required by the switch to libpango
(Closes: #493575, #493594).
- -- Sebastian Harl <sh@tokkee.org> Fri, 26 Sep 2008 00:07:32 +0200
+ -- Sebastian Harl <sh@tokkee.org> Fri, 26 Sep 2008 00:24:55 +0200
rrdtool (1.3.1-3) unstable; urgency=low
diff --git a/debian/patches/bts499349-memleaks b/debian/patches/bts499349-memleaks
--- /dev/null
@@ -0,0 +1,369 @@
+diff a/src/rrd_create.c b/src/rrd_create.c
+--- a/src/rrd_create.c
++++ b/src/rrd_create.c
+@@ -27,6 +27,9 @@ void parseGENERIC_DS(
+ long int rra_random_row(
+ rra_def_t *);
+
++static void rrd_free2(
++ rrd_t *rrd); /* our onwn copy, immmune to mmap */
++
+ int rrd_create(
+ int argc,
+ char **argv)
+@@ -125,15 +128,14 @@ int rrd_create_r(
+ /* static header */
+ if ((rrd.stat_head = calloc(1, sizeof(stat_head_t))) == NULL) {
+ rrd_set_error("allocating rrd.stat_head");
+- free(rrd.stat_head);
++ rrd_free2(&rrd);
+ return (-1);
+ }
+
+ /* live header */
+ if ((rrd.live_head = calloc(1, sizeof(live_head_t))) == NULL) {
+ rrd_set_error("allocating rrd.live_head");
+- free(rrd.stat_head);
+- free(rrd.live_head);
++ rrd_free2(&rrd);
+ return (-1);
+ }
+
+@@ -166,8 +168,7 @@ int rrd_create_r(
+ old_size + sizeof(ds_def_t))) ==
+ NULL) {
+ rrd_set_error("allocating rrd.ds_def");
+- free(rrd.stat_head);
+- free(rrd.live_head);
++ rrd_free2(&rrd);
+ return (-1);
+ }
+ memset(&rrd.ds_def[rrd.stat_head->ds_cnt], 0, sizeof(ds_def_t));
+@@ -199,8 +200,7 @@ int rrd_create_r(
+ rrd_set_error("invalid DS format");
+ }
+ if (rrd_test_error()) {
+- free(rrd.stat_head);
+- free(rrd.live_head);
++ rrd_free2(&rrd);
+ return -1;
+ }
+
+@@ -223,8 +223,7 @@ int rrd_create_r(
+ }
+
+ if (rrd_test_error()) {
+- free(rrd.stat_head);
+- free(rrd.live_head);
++ rrd_free2(&rrd);
+ return -1;
+ }
+ rrd.stat_head->ds_cnt++;
+@@ -238,8 +237,7 @@ int rrd_create_r(
+ old_size + sizeof(rra_def_t))) ==
+ NULL) {
+ rrd_set_error("allocating rrd.rra_def");
+- free(rrd.stat_head);
+- free(rrd.live_head);
++ rrd_free2(&rrd);
+ return (-1);
+ }
+ memset(&rrd.rra_def[rrd.stat_head->rra_cnt], 0,
+@@ -496,8 +494,7 @@ int rrd_create_r(
+ if (rrd_test_error()) {
+ /* all errors are unrecoverable */
+ free(argvcopy);
+- free(rrd.stat_head);
+- free(rrd.live_head);
++ rrd_free2(&rrd);
+ return (-1);
+ }
+ token = strtok_r(NULL, ":", &tokptr);
+@@ -524,16 +521,14 @@ int rrd_create_r(
+ if (create_hw_contingent_rras(&rrd, period, hashed_name) ==
+ -1) {
+ rrd_set_error("creating contingent RRA");
+- free(rrd.stat_head);
+- free(rrd.live_head);
++ rrd_free2(&rrd);
+ return -1;
+ }
+ }
+ rrd.stat_head->rra_cnt++;
+ } else {
+ rrd_set_error("can't parse argument '%s'", argv[i]);
+- free(rrd.stat_head);
+- free(rrd.live_head);
++ rrd_free2(&rrd);
+ return -1;
+ }
+ }
+@@ -541,15 +536,13 @@ int rrd_create_r(
+
+ if (rrd.stat_head->rra_cnt < 1) {
+ rrd_set_error("you must define at least one Round Robin Archive");
+- free(rrd.stat_head);
+- free(rrd.live_head);
++ rrd_free2(&rrd);
+ return (-1);
+ }
+
+ if (rrd.stat_head->ds_cnt < 1) {
+ rrd_set_error("you must define at least one Data Source");
+- free(rrd.stat_head);
+- free(rrd.live_head);
++ rrd_free2(&rrd);
+ return (-1);
+ }
+ return rrd_create_fn(filename, &rrd);
+@@ -618,6 +611,7 @@ int create_hw_contingent_rras(
+ if ((rrd->rra_def = rrd_realloc(rrd->rra_def,
+ old_size + 4 * sizeof(rra_def_t))) ==
+ NULL) {
++ rrd_free2(rrd);
+ rrd_set_error("allocating rrd.rra_def");
+ return (-1);
+ }
+@@ -682,15 +676,15 @@ int rrd_create_fn(
+ int unkn_cnt;
+ rrd_file_t *rrd_file_dn;
+ rrd_t rrd_dn;
+- unsigned flags = O_WRONLY | O_CREAT | O_TRUNC;
++ unsigned flags = O_WRONLY | O_CREAT | O_TRUNC;
++
+ #if defined(_WIN32) && !defined(__CYGWIN__) && !defined(__CYGWIN32__)
+ flags |= O_BINARY;
+ #endif
+
+ if ((rrd_file = open(file_name, flags, 0666)) < 0) {
+ rrd_set_error("creating '%s': %s", file_name, rrd_strerror(errno));
+- free(rrd->stat_head);
+- free(rrd->live_head);
++ rrd_free2(rrd);
+ return (-1);
+ }
+
+@@ -705,8 +699,7 @@ int rrd_create_fn(
+
+ if ((rrd->pdp_prep = calloc(1, sizeof(pdp_prep_t))) == NULL) {
+ rrd_set_error("allocating pdp_prep");
+- free(rrd->stat_head);
+- free(rrd->live_head);
++ rrd_free2(rrd);
+ close(rrd_file);
+ return (-1);
+ }
+@@ -722,8 +715,7 @@ int rrd_create_fn(
+
+ if ((rrd->cdp_prep = calloc(1, sizeof(cdp_prep_t))) == NULL) {
+ rrd_set_error("allocating cdp_prep");
+- free(rrd->stat_head);
+- free(rrd->live_head);
++ rrd_free2(rrd);
+ close(rrd_file);
+ return (-1);
+ }
+@@ -770,8 +762,7 @@ int rrd_create_fn(
+
+ if ((rrd->rra_ptr = calloc(1, sizeof(rra_ptr_t))) == NULL) {
+ rrd_set_error("allocating rra_ptr");
+- free(rrd->stat_head);
+- free(rrd->live_head);
++ rrd_free2(rrd);
+ close(rrd_file);
+ return (-1);
+ }
+@@ -788,8 +779,7 @@ int rrd_create_fn(
+ /* write the empty data area */
+ if ((unknown = (rrd_value_t *) malloc(512 * sizeof(rrd_value_t))) == NULL) {
+ rrd_set_error("allocating unknown");
+- free(rrd->stat_head);
+- free(rrd->live_head);
++ rrd_free2(rrd);
+ close(rrd_file);
+ return (-1);
+ }
+@@ -807,8 +797,7 @@ int rrd_create_fn(
+ }
+ free(unknown);
+ fdatasync(rrd_file);
+- free(rrd->stat_head);
+- free(rrd->live_head);
++ rrd_free2(rrd);
+ if (close(rrd_file) == -1) {
+ rrd_set_error("creating rrd: %s", rrd_strerror(errno));
+ return -1;
+@@ -821,6 +810,20 @@ int rrd_create_fn(
+ return (0);
+ }
+
++
++static void rrd_free2(
++ rrd_t *rrd)
++{
++ free(rrd->live_head);
++ free(rrd->stat_head);
++ free(rrd->ds_def);
++ free(rrd->rra_def);
++ free(rrd->rra_ptr);
++ free(rrd->pdp_prep);
++ free(rrd->cdp_prep);
++ free(rrd->rrd_value);
++}
++
+ static int rand_init = 0;
+
+ long int rra_random_row(
+diff a/src/rrd_tool.c b/src/rrd_tool.c
+--- a/src/rrd_tool.c
++++ b/src/rrd_tool.c
+@@ -364,6 +364,7 @@ static char *fgetslong(
+ return *aLinePtr = linebuf;
+ bufsize += MAX_LENGTH;
+ if (!(linebuf = realloc(linebuf, bufsize))) {
++ free(linebuf);
+ perror("fgetslong: realloc");
+ exit(1);
+ }
+@@ -448,6 +449,7 @@ int main(
+
+ while (fgetslong(&aLine, stdin)) {
+ if ((argc = CountArgs(aLine)) == 0) {
++ free(aLine);
+ printf("ERROR: not enough arguments\n");
+ }
+ if ((myargv = (char **) malloc((argc + 1) *
+@@ -456,6 +458,8 @@ int main(
+ exit(1);
+ }
+ if ((argc = CreateArgs(argv[0], aLine, argc, myargv)) < 0) {
++ free(aLine);
++ free(myargv);
+ printf("ERROR: creating arguments\n");
+ } else {
+ int ret = HandleInputLine(argc, myargv, stdout);
+diff a/src/rrd_graph.c b/src/rrd_graph.c
+--- a/src/rrd_graph.c
++++ b/src/rrd_graph.c
+@@ -3059,6 +3059,7 @@ int graph_paint(
+ (im->surface, CAIRO_SVG_VERSION_1_1);
+ break;
+ };
++ cairo_destroy(im->cr);
+ im->cr = cairo_create(im->surface);
+ cairo_set_antialias(im->cr, im->graph_antialias);
+ cairo_scale(im->cr, im->zoom, im->zoom);
+diff a/src/rrd_gfx.c b/src/rrd_gfx.c
+--- a/src/rrd_gfx.c
++++ b/src/rrd_gfx.c
+@@ -158,10 +158,11 @@ static PangoLayout *gfx_prep_text(
+ /* pango_cairo_update_context(cr, pango_context); */
+
+ pango_layout_set_tabs(layout, tab_array);
++ pango_tab_array_free(tab_array);
+ font_desc = pango_font_description_from_string(font);
+ pango_font_description_set_size(font_desc, size * PANGO_SCALE);
+ pango_layout_set_font_description(layout, font_desc);
+-
++ pango_font_description_free(font_desc);
+ /* pango expects the string to be utf-8 encoded */
+ utf8_text = g_locale_to_utf8((const gchar *) text, -1, NULL, NULL, NULL);
+
+@@ -191,7 +192,6 @@ double gfx_get_text_width(
+ gfx_color_t color = { 0, 0, 0, 0 };
+ layout = gfx_prep_text(im, start, color, font, size, tabwidth, text);
+ pango_layout_get_pixel_extents(layout, NULL, &log_rect);
+- pango_tab_array_free(pango_layout_get_tabs(layout));
+ g_object_unref(layout);
+ return log_rect.width;
+ }
+@@ -252,7 +252,6 @@ void gfx_text(
+ pango_cairo_update_layout(cr, layout);
+ cairo_move_to(cr, sx, sy);
+ pango_cairo_show_layout(cr, layout);
+- pango_tab_array_free(pango_layout_get_tabs(layout));
+ g_object_unref(layout);
+ cairo_restore(cr);
+
+diff a/src/rrd_tool.c b/src/rrd_tool.c
+--- a/src/rrd_tool.c
++++ b/src/rrd_tool.c
+@@ -369,7 +369,11 @@ static char *fgetslong(
+ exit(1);
+ }
+ }
+- return *aLinePtr = linebuf[0] ? linebuf : 0;
++ if (linebuf[0]){
++ return *aLinePtr = linebuf;
++ }
++ free(linebuf);
++ return *aLinePtr = 0;
+ }
+
+ int main(
+diff a/bindings/perl-shared/RRDs.xs b/bindings/perl-shared/RRDs.xs
+--- a/bindings/perl-shared/RRDs.xs
++++ b/bindings/perl-shared/RRDs.xs
+@@ -78,8 +78,8 @@ extern "C" {
+ free(argv); \
+ if (rrd_test_error()) XSRETURN_UNDEF; \
+ hash = newHV(); \
++ save=data; \
+ while (data) { \
+- save=data; \
+ /* the newSV will get copied by hv so we create it as a mortal \
+ to make sure it does not keep hanging round after the fact */ \
+ switch (data->type) { \
+@@ -97,18 +97,14 @@ extern "C" {
+ break; \
+ case RD_I_STR: \
+ hvs(newSVpv(data->value.u_str,0)); \
+- rrd_freemem(data->value.u_str); \
+ break; \
+ case RD_I_BLO: \
+ hvs(newSVpv(data->value.u_blo.ptr,data->value.u_blo.size)); \
+- rrd_freemem(data->value.u_blo.ptr); \
+ break; \
+ } \
+- rrd_freemem(data->key); \
+ data = data->next; \
+- rrd_freemem(save); \
+- } \
+- rrd_freemem(data); \
++ } \
++ rrd_info_free(save); \
+ RETVAL = newRV_noinc((SV*)hash);
+
+ /*
+diff a/bindings/ruby/main.c b/bindings/ruby/main.c
+--- a/bindings/ruby/main.c
++++ b/bindings/ruby/main.c
+@@ -155,6 +155,7 @@ VALUE rb_rrd_infocall(
+
+ RRD_CHECK_ERROR result = rb_hash_new();
+
++ p = data;
+ while (data) {
+ VALUE key = rb_str_new2(data->key);
+
+@@ -171,19 +172,16 @@ VALUE rb_rrd_infocall(
+ break;
+ case RD_I_STR:
+ rb_hash_aset(result, key, rb_str_new2(data->value.u_str));
+- rrd_freemem(data->value.u_str);
+ break;
+ case RD_I_BLO:
+ rb_hash_aset(result, key,
+ rb_str_new(data->value.u_blo.ptr,
+ data->value.u_blo.size));
+- rrd_freemem(data->value.u_blo.ptr);
+ break;
+ }
+- p = data;
+ data = data->next;
+- rrd_freemem(p);
+ }
++ rrd_info_free(p);
+ return result;
+ }
+
diff --git a/debian/patches/series b/debian/patches/series
index 5a746d01cc49975882af1a4f9baff0a5432450e9..0d277c73ffa09dd282cea5f0245794a66b69fcc1 100644 (file)
--- a/debian/patches/series
+++ b/debian/patches/series
bts499350-data-corruption
bts498183-segfault-madvise
bts496847-error-handling
+bts499349-memleaks