From 910e31f0154734f5bdfaa2d334a037eeeead295b Mon Sep 17 00:00:00 2001 From: Corinna Vinschen Date: Mon, 29 Nov 2010 20:51:38 +0000 Subject: [PATCH] * fhandler_tty.cc (fhandler_tty_slave::dup): Free path_conv strings to avoid memory leak. Add comment. (fhandler_pty_master::dup): Ditto. * path.h (path_conv::free_strings): New method. --- winsup/cygwin/ChangeLog | 7 +++++++ winsup/cygwin/fhandler_tty.cc | 14 ++++++++++++++ winsup/cygwin/path.h | 5 +++++ 3 files changed, 26 insertions(+) diff --git a/winsup/cygwin/ChangeLog b/winsup/cygwin/ChangeLog index 4986faab9..5fcd5b8c9 100644 --- a/winsup/cygwin/ChangeLog +++ b/winsup/cygwin/ChangeLog @@ -1,3 +1,10 @@ +2010-11-29 Corinna Vinschen + + * fhandler_tty.cc (fhandler_tty_slave::dup): Free path_conv strings + to avoid memory leak. Add comment. + (fhandler_pty_master::dup): Ditto. + * path.h (path_conv::free_strings): New method. + 2010-11-23 Corinna Vinschen * autoload.cc (SendARP): Remove. diff --git a/winsup/cygwin/fhandler_tty.cc b/winsup/cygwin/fhandler_tty.cc index 23a07d0b4..0c32d5311 100644 --- a/winsup/cygwin/fhandler_tty.cc +++ b/winsup/cygwin/fhandler_tty.cc @@ -979,6 +979,18 @@ int fhandler_tty_slave::dup (fhandler_base *child) { fhandler_tty_slave *arch = (fhandler_tty_slave *) archetype; + /* In dtable::dup_worker, the path_conv member has already been assigned + from "this" to "child". Part of this assigment (path_conv::operator=) + is to allocate memory for the strings "path" and "normalized_path from + cygheap. The below `child = *arch' statement will overwrite child's + path_conv again, this time from "*arch". By doing that, it will allocate + new strings from cygheap, overwriting the old pointer values. Thus, the + old allocated strings are lost, and we're leaking memory for each tty dup, + unless we free the strings here. + FIXME: We can't redefine path_conv::operator= so that it frees the old + strings. Probably it would be most helpful to copy only the required + members from *arch, rather than copying everything. */ + child->pc.free_strings (); *(fhandler_tty_slave *) child = *arch; child->set_flags (get_flags ()); child->usecount = 0; @@ -992,6 +1004,8 @@ int fhandler_pty_master::dup (fhandler_base *child) { fhandler_tty_master *arch = (fhandler_tty_master *) archetype; + /* See comment in fhandler_tty_slave::dup. */ + child->pc.free_strings (); *(fhandler_tty_master *) child = *arch; child->set_flags (get_flags ()); child->usecount = 0; diff --git a/winsup/cygwin/path.h b/winsup/cygwin/path.h index c5b10e3c7..ef6cac44e 100644 --- a/winsup/cygwin/path.h +++ b/winsup/cygwin/path.h @@ -293,6 +293,11 @@ class path_conv wide_path = NULL; return *this; } + void free_strings () + { + cfree (modifiable_path ()); + cfree ((char *) normalized_path); + } DWORD get_devn () const {return dev.devn;} short get_unitn () const {return dev.minor;} DWORD file_attributes () const {return fileattr;}