From patchwork Thu May 17 15:34:23 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Jonathan Wakely X-Patchwork-Id: 915501 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Authentication-Results: ozlabs.org; spf=pass (mailfrom) smtp.mailfrom=gcc.gnu.org (client-ip=209.132.180.131; helo=sourceware.org; envelope-from=gcc-patches-return-477873-incoming=patchwork.ozlabs.org@gcc.gnu.org; receiver=) Authentication-Results: ozlabs.org; dmarc=fail (p=none dis=none) header.from=redhat.com Authentication-Results: ozlabs.org; dkim=pass (1024-bit key; unprotected) header.d=gcc.gnu.org header.i=@gcc.gnu.org header.b="jk+UYvJV"; dkim-atps=neutral Received: from sourceware.org (server1.sourceware.org [209.132.180.131]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by ozlabs.org (Postfix) with ESMTPS id 40mwMy6ssmz9s4Y for ; Fri, 18 May 2018 01:34:37 +1000 (AEST) DomainKey-Signature: a=rsa-sha1; c=nofws; d=gcc.gnu.org; h=list-id :list-unsubscribe:list-archive:list-post:list-help:sender:date :from:to:subject:message-id:mime-version:content-type; q=dns; s= default; b=LgBLoFRgAL/e7Chi0gMUIC5AJBQqggyoyvBC/xmJF1t2wE9+yQcmY eZI4tkxXwGeeEO5nE8H3vwjaM+P+CFqWaAvCuy5HQA452d4oliGolxpcEOirdlMx 98/qn98TYFYU1C6NRn5dowdmTRjAk8qGh6S9RKDxnjl7vNanfY19iM= DKIM-Signature: v=1; a=rsa-sha1; c=relaxed; d=gcc.gnu.org; h=list-id :list-unsubscribe:list-archive:list-post:list-help:sender:date :from:to:subject:message-id:mime-version:content-type; s= default; bh=dTCnrkHyI8BVSPv7N/oQVpvSsaY=; b=jk+UYvJVAYzD2Y7x6101 JhZqEiMvVT8Ad2qvKEguLILkN+LiekEPZG6tMadt+mB4Dq+1BTjv6McFepNNtuLV b2HP+oXtTmTD82P5KFX0urxnOm28tBO29h149T6lmd1aIv47SMyA67WJ9qowHJi8 h58IhSbaEpzdDcnoq3Kio5A= Received: (qmail 17322 invoked by alias); 17 May 2018 15:34:28 -0000 Mailing-List: contact gcc-patches-help@gcc.gnu.org; run by ezmlm Precedence: bulk List-Id: List-Unsubscribe: List-Archive: List-Post: List-Help: Sender: gcc-patches-owner@gcc.gnu.org Delivered-To: mailing list gcc-patches@gcc.gnu.org Received: (qmail 17196 invoked by uid 89); 17 May 2018 15:34:27 -0000 Authentication-Results: sourceware.org; auth=none X-Virus-Found: No X-Spam-SWARE-Status: No, score=-25.3 required=5.0 tests=AWL, BAYES_00, GIT_PATCH_0, GIT_PATCH_1, GIT_PATCH_2, GIT_PATCH_3, SPF_HELO_PASS autolearn=ham version=3.3.2 spammy=placement X-Spam-User: qpsmtpd, 2 recipients X-HELO: mx1.redhat.com Received: from mx3-rdu2.redhat.com (HELO mx1.redhat.com) (66.187.233.73) by sourceware.org (qpsmtpd/0.93/v0.84-503-g423c35a) with ESMTP; Thu, 17 May 2018 15:34:25 +0000 Received: from smtp.corp.redhat.com (int-mx06.intmail.prod.int.rdu2.redhat.com [10.11.54.6]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by mx1.redhat.com (Postfix) with ESMTPS id 6059D401EF08; Thu, 17 May 2018 15:34:24 +0000 (UTC) Received: from localhost (unknown [10.33.36.4]) by smtp.corp.redhat.com (Postfix) with ESMTP id 1F2192166BAD; Thu, 17 May 2018 15:34:23 +0000 (UTC) Date: Thu, 17 May 2018 16:34:23 +0100 From: Jonathan Wakely To: libstdc++@gcc.gnu.org, gcc-patches@gcc.gnu.org Subject: [PATCH] PR libstdc++/85812 fix memory leak in std::make_exception_ptr Message-ID: <20180517153423.GA13862@redhat.com> MIME-Version: 1.0 Content-Disposition: inline X-Clacks-Overhead: GNU Terry Pratchett User-Agent: Mutt/1.9.2 (2017-12-15) As the PR points out, the constructor called in the placement new expression can throw, in which case the allocation would be leaked. Separating the two implementations makes it much easier to read what the code is doing. PR libstdc++/85812 * libsupc++/cxxabi_init_exception.h (__cxa_free_exception): Declare. * libsupc++/exception_ptr.h (make_exception_ptr) [__cpp_exceptions]: Refactor to separate non-throwing and throwing implementations. [__cpp_rtti && !_GLIBCXX_HAVE_CDTOR_CALLABI]: Deallocate the memory if constructing the object throws. Tested powerpc64le-linux (and also using ASan to verify the fix). Committed to trunk. Backports to gcc-7 and gcc-8 will follow. commit 3d02d84556f2be22945d397ed2fb4dbff8a0788e Author: Jonathan Wakely Date: Thu May 17 13:51:04 2018 +0100 PR libstdc++/85812 fix memory leak in std::make_exception_ptr PR libstdc++/85812 * libsupc++/cxxabi_init_exception.h (__cxa_free_exception): Declare. * libsupc++/exception_ptr.h (make_exception_ptr) [__cpp_exceptions]: Refactor to separate non-throwing and throwing implementations. [__cpp_rtti && !_GLIBCXX_HAVE_CDTOR_CALLABI]: Deallocate the memory if constructing the object throws. diff --git a/libstdc++-v3/libsupc++/cxxabi_init_exception.h b/libstdc++-v3/libsupc++/cxxabi_init_exception.h index d973a087f14..e438c1008d9 100644 --- a/libstdc++-v3/libsupc++/cxxabi_init_exception.h +++ b/libstdc++-v3/libsupc++/cxxabi_init_exception.h @@ -62,6 +62,9 @@ namespace __cxxabiv1 void* __cxa_allocate_exception(size_t) _GLIBCXX_NOTHROW; + void + __cxa_free_exception(void*) _GLIBCXX_NOTHROW; + // Initialize exception (this is a GNU extension) __cxa_refcounted_exception* __cxa_init_primary_exception(void *object, std::type_info *tinfo, diff --git a/libstdc++-v3/libsupc++/exception_ptr.h b/libstdc++-v3/libsupc++/exception_ptr.h index a927327214d..bd355ed880b 100644 --- a/libstdc++-v3/libsupc++/exception_ptr.h +++ b/libstdc++-v3/libsupc++/exception_ptr.h @@ -178,25 +178,31 @@ namespace std exception_ptr make_exception_ptr(_Ex __ex) _GLIBCXX_USE_NOEXCEPT { -#if __cpp_exceptions +#if __cpp_exceptions && __cpp_rtti && !_GLIBCXX_HAVE_CDTOR_CALLABI + void* __e = __cxxabiv1::__cxa_allocate_exception(sizeof(_Ex)); + (void) __cxxabiv1::__cxa_init_primary_exception( + __e, const_cast(&typeid(__ex)), + __exception_ptr::__dest_thunk<_Ex>); try { -#if __cpp_rtti && !_GLIBCXX_HAVE_CDTOR_CALLABI - void *__e = __cxxabiv1::__cxa_allocate_exception(sizeof(_Ex)); - (void)__cxxabiv1::__cxa_init_primary_exception( - __e, const_cast(&typeid(__ex)), - __exception_ptr::__dest_thunk<_Ex>); ::new (__e) _Ex(__ex); return exception_ptr(__e); -#else + } + catch(...) + { + __cxxabiv1::__cxa_free_exception(__e); + return current_exception(); + } +#elif __cpp_exceptions + try + { throw __ex; -#endif } catch(...) { return current_exception(); } -#else +#else // no RTTI and no exceptions return exception_ptr(); #endif }