From patchwork Mon Sep 4 17:13:42 2006 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Klaus Schmidinger X-Patchwork-Id: 12385 Received: from raven.cadsoft.de ([217.7.101.211]) by www.linuxtv.org with esmtp (Exim 4.50) id 1GKI14-000620-LU for vdr@linuxtv.org; Mon, 04 Sep 2006 19:13:46 +0200 Received: from [192.168.100.10] (hawk.cadsoft.de [192.168.100.10]) by raven.cadsoft.de (8.13.3/8.13.3) with ESMTP id k84HDiId015992 for ; Mon, 4 Sep 2006 19:13:45 +0200 Message-ID: <44FC5EC6.3040005@cadsoft.de> Date: Mon, 04 Sep 2006 19:13:42 +0200 From: Klaus Schmidinger Organization: CadSoft Computer GmbH User-Agent: Thunderbird 1.5.0.4 (X11/20060516) MIME-Version: 1.0 To: vdr@linuxtv.org Subject: Re: [vdr] *** glibc detected *** double free or corruption 1.4.2-1 Patch References: <000001c6d034$1624dff0$426e9fd0$@net> <20060904174148.8aa03314.hilse@web.de> <44FC53FB.5090809@gmx.de> <44FC5896.8050905@gmx.de> <44FC5E13.7030301@cadsoft.de> In-Reply-To: <44FC5E13.7030301@cadsoft.de> X-Greylist: Sender IP whitelisted, not delayed by milter-greylist-2.0 (raven.cadsoft.de [192.168.1.1]); Mon, 04 Sep 2006 19:13:45 +0200 (CEST) X-BeenThere: vdr@linuxtv.org X-Mailman-Version: 2.1.5 Precedence: list Reply-To: VDR Mailing List List-Id: VDR Mailing List List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Mon, 04 Sep 2006 17:13:46 -0000 Status: O X-Status: X-Keywords: X-UID: 10592 Klaus Schmidinger wrote: > Udo Richter wrote: >> Udo Richter wrote: >>> ==4652== Invalid free() / delete / delete[] >>> ==4652== at 0x1B904B04: free (vg_replace_malloc.c:152) >>> ==4652== by 0x8103F5F: cTimer::operator=(cTimer const&) >>> (timers.c:108) >>> ==4652== by 0x80FE349: cSVDRP::CmdMODT(char const*) (svdrp.c:1136) >>> ==4652== by 0x81015C1: cSVDRP::Process() (svdrp.c:1563) >>> ==4652== by 0x80B3458: cInterface::GetKey(bool) (interface.c:37) >>> ==4652== by 0x810D919: main (vdr.c:866) >>> ==4652== Address 0x1BEEAC90 is 0 bytes inside a block of size 63 free'd >>> ==4652== at 0x1B904B04: free (vg_replace_malloc.c:152) >>> ==4652== by 0x8104D6F: cTimer::Parse(char const*) (timers.c:244) >>> ==4652== by 0x80FE493: cSVDRP::CmdMODT(char const*) (svdrp.c:1132) >>> ==4652== by 0x81015C1: cSVDRP::Process() (svdrp.c:1563) >>> ==4652== by 0x80B3458: cInterface::GetKey(bool) (interface.c:37) >>> ==4652== by 0x810D919: main (vdr.c:866) >> >> >> I think I've found it: >> >> This is line 1127 of svdrp.c: >> >> cTimer t = *timer; >> >> Although this looks like it calls cTimer::operator=, it actually calls >> the default copy constructor of cTimer, because in this case = is not >> an assignment, but an initialization. Because of that, the aux field >> is used by both objects, thus the double free. Try this line to see if >> it causes this: >> >> cTimer t; >> t = *timer; > > It's probably best to implement an actual copy-constructor. > > Please try the attached patch, which contains both changes. Opps, sorry, there was a typo. Attached is the correct version. (Never code when in a hurry... ;-) Klaus --- timers.h 2006/04/08 12:41:44 1.28 +++ timers.h 2006/09/04 17:07:39 @@ -44,6 +44,7 @@ public: cTimer(bool Instant = false, bool Pause = false, cChannel *Channel = NULL); cTimer(const cEvent *Event); + cTimer(const cTimer &Timer); virtual ~cTimer(); cTimer& operator= (const cTimer &Timer); virtual int Compare(const cListObject &ListObject) const; --- timers.c 2006/09/02 10:20:36 1.63 +++ timers.c 2006/09/04 17:08:32 @@ -83,6 +83,11 @@ event = NULL; // let SetEvent() be called to get a log message } +cTimer::cTimer(const cTimer &Timer) +{ + *this = Timer; +} + cTimer::~cTimer() { free(aux); @@ -90,24 +95,26 @@ cTimer& cTimer::operator= (const cTimer &Timer) { - startTime = Timer.startTime; - stopTime = Timer.stopTime; - lastSetEvent = 0; - recording = Timer.recording; - pending = Timer.pending; - inVpsMargin = Timer.inVpsMargin; - flags = Timer.flags; - channel = Timer.channel; - day = Timer.day; - weekdays = Timer.weekdays; - start = Timer.start; - stop = Timer.stop; - priority = Timer.priority; - lifetime = Timer.lifetime; - strncpy(file, Timer.file, sizeof(file)); - free(aux); - aux = Timer.aux ? strdup(Timer.aux) : NULL; - event = NULL; + if (&Timer != this) { + startTime = Timer.startTime; + stopTime = Timer.stopTime; + lastSetEvent = 0; + recording = Timer.recording; + pending = Timer.pending; + inVpsMargin = Timer.inVpsMargin; + flags = Timer.flags; + channel = Timer.channel; + day = Timer.day; + weekdays = Timer.weekdays; + start = Timer.start; + stop = Timer.stop; + priority = Timer.priority; + lifetime = Timer.lifetime; + strncpy(file, Timer.file, sizeof(file)); + free(aux); + aux = Timer.aux ? strdup(Timer.aux) : NULL; + event = NULL; + } return *this; }