From patchwork Tue Mar 28 08:24:43 2017 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Yao Qi X-Patchwork-Id: 19741 Received: (qmail 99153 invoked by alias); 28 Mar 2017 08:24:51 -0000 Mailing-List: contact gdb-patches-help@sourceware.org; run by ezmlm Precedence: bulk List-Id: List-Unsubscribe: List-Subscribe: List-Archive: List-Post: List-Help: , Sender: gdb-patches-owner@sourceware.org Delivered-To: mailing list gdb-patches@sourceware.org Received: (qmail 99022 invoked by uid 89); 28 Mar 2017 08:24:50 -0000 Authentication-Results: sourceware.org; auth=none X-Virus-Found: No X-Spam-SWARE-Status: No, score=-25.6 required=5.0 tests=BAYES_00, FREEMAIL_FROM, GIT_PATCH_0, GIT_PATCH_1, GIT_PATCH_2, GIT_PATCH_3, KAM_ASCII_DIVIDERS, RCVD_IN_DNSWL_NONE, RCVD_IN_SORBS_SPAM, SPF_PASS autolearn=ham version=3.3.2 spammy=2058 X-HELO: mail-wr0-f194.google.com Received: from mail-wr0-f194.google.com (HELO mail-wr0-f194.google.com) (209.85.128.194) by sourceware.org (qpsmtpd/0.93/v0.84-503-g423c35a) with ESMTP; Tue, 28 Mar 2017 08:24:48 +0000 Received: by mail-wr0-f194.google.com with SMTP id w43so17425004wrb.1 for ; Tue, 28 Mar 2017 01:24:49 -0700 (PDT) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:subject:date:message-id:in-reply-to :references; bh=AomlNve3mFO7Z3glQvOa2CZl2Ftu3bdFu7l9ozxOnr0=; b=EC6Zc/XnGsYbIwAcuGrZB/E+qKah6PLrHBMsOvteIhgh2Oz2bAU7N2zPo707zX9r8p rtbh2UYwU2Fj9d5JY44OW9Ov97vBnfs1070IN+Pk/PWV+4r0h/iluZSnMTxvNxHmcHzK RVSs9NyBJetinu+KTC18DcNcP/wfBM7G9B9uUR8weZtVwm/UxePFLJweXMR5IcwnT7gY sgGzxt8MY81H20wHCSy9ZyUDNisygoqMKbnG35jc2yHmJWD/iKIYs0SmkRfg8l6iTPYj fiPLovC7bUhk0GYikDilXdu8Tbb99XnylzQjB4jYjP98esgtsMQgDWU503Xp6S5vWyUj 5Rww== X-Gm-Message-State: AFeK/H3Kgm+NgrRsPu4S27yw09iZfofGw2bEfkS74VL/1oegp6827afgUO/Ot+zYagZWFA== X-Received: by 10.223.129.199 with SMTP id 65mr12036085wra.118.1490689487349; Tue, 28 Mar 2017 01:24:47 -0700 (PDT) Received: from E107787-LIN.cambridge.arm.com ([194.214.185.158]) by smtp.gmail.com with ESMTPSA id o52sm3835188wrb.51.2017.03.28.01.24.46 for (version=TLS1_2 cipher=ECDHE-RSA-AES128-SHA bits=128/128); Tue, 28 Mar 2017 01:24:46 -0700 (PDT) From: Yao Qi X-Google-Original-From: Yao Qi To: gdb-patches@sourceware.org Subject: [PATCH 2/2] Delete thread_info is refcount is zero Date: Tue, 28 Mar 2017 09:24:43 +0100 Message-Id: <1490689483-16084-3-git-send-email-yao.qi@linaro.org> In-Reply-To: <1490689483-16084-1-git-send-email-yao.qi@linaro.org> References: <1490689483-16084-1-git-send-email-yao.qi@linaro.org> X-IsSubscribed: yes I build GDB with asan, and run test case hook-stop.exp, and threadapply.exp, I got the following asan error, =================================================================^M ^[[1m^[[31m==2291==ERROR: AddressSanitizer: heap-use-after-free on address 0x6160000999c4 at pc 0x000000826022 bp 0x7ffd28a8ff70 sp 0x7ffd28a8ff60^M ^[[1m^[[0m^[[1m^[[34mREAD of size 4 at 0x6160000999c4 thread T0^[[1m^[[0m^M #0 0x826021 in release_stop_context_cleanup ../../binutils-gdb/gdb/infrun.c:8203^M #1 0x72798a in do_my_cleanups ../../binutils-gdb/gdb/common/cleanups.c:154^M #2 0x727a32 in do_cleanups(cleanup*) ../../binutils-gdb/gdb/common/cleanups.c:176^M #3 0x826895 in normal_stop() ../../binutils-gdb/gdb/infrun.c:8381^M #4 0x815208 in fetch_inferior_event(void*) ../../binutils-gdb/gdb/infrun.c:4011^M #5 0x868aca in inferior_event_handler(inferior_event_type, void*) ../../binutils-gdb/gdb/inf-loop.c:44^M .... ^[[1m^[[32m0x6160000999c4 is located 68 bytes inside of 568-byte region [0x616000099980,0x616000099bb8)^M ^[[1m^[[0m^[[1m^[[35mfreed by thread T0 here:^[[1m^[[0m^M #0 0x7fb0bc1312ca in __interceptor_free (/usr/lib/x86_64-linux-gnu/libasan.so.2+0x982ca)^M #1 0xb8c62f in xfree(void*) ../../binutils-gdb/gdb/common/common-utils.c:100^M #2 0x83df67 in free_thread ../../binutils-gdb/gdb/thread.c:207^M #3 0x83dfd2 in init_thread_list() ../../binutils-gdb/gdb/thread.c:223^M #4 0x805494 in kill_command ../../binutils-gdb/gdb/infcmd.c:2595^M .... Detaching from program: /home/yao.qi/SourceCode/gnu/build-with-asan/gdb/testsuite/outputs/gdb.threads/threadapply/threadapply, process 2399^M =================================================================^M ^[[1m^[[31m==2387==ERROR: AddressSanitizer: heap-use-after-free on address 0x6160000a98c0 at pc 0x00000083fd28 bp 0x7ffd401c3110 sp 0x7ffd401c3100^M ^[[1m^[[0m^[[1m^[[34mREAD of size 4 at 0x6160000a98c0 thread T0^[[1m^[[0m^M #0 0x83fd27 in thread_alive ../../binutils-gdb/gdb/thread.c:741^M #1 0x844277 in thread_apply_all_command ../../binutils-gdb/gdb/thread.c:1804^M .... ^M ^[[1m^[[32m0x6160000a98c0 is located 64 bytes inside of 568-byte region [0x6160000a9880,0x6160000a9ab8)^M ^[[1m^[[0m^[[1m^[[35mfreed by thread T0 here:^[[1m^[[0m^M #0 0x7f59a7e322ca in __interceptor_free (/usr/lib/x86_64-linux-gnu/libasan.so.2+0x982ca)^M #1 0xb8c62f in xfree(void*) ../../binutils-gdb/gdb/common/common-utils.c:100^M #2 0x83df67 in free_thread ../../binutils-gdb/gdb/thread.c:207^M #3 0x83dfd2 in init_thread_list() ../../binutils-gdb/gdb/thread.c:223^M This patch fixes the issue by always checking refcount before decreasing it. If it is zero already, delete the thread_info. gdb: 2017-03-28 Yao Qi PR gdb/19942 * infrun.c (release_stop_context_cleanup): If refcount is zero delete thread, otherwise decrease the refcount. * thread.c (init_thread_list): Likewise. (restore_current_thread_cleanup_dtor): Likewise. (set_thread_refcount): Likewise. --- gdb/infrun.c | 7 ++++++- gdb/thread.c | 19 ++++++++++++++++--- 2 files changed, 22 insertions(+), 4 deletions(-) diff --git a/gdb/infrun.c b/gdb/infrun.c index c8c2d6e..f8eeddb 100644 --- a/gdb/infrun.c +++ b/gdb/infrun.c @@ -8182,7 +8182,12 @@ release_stop_context_cleanup (void *arg) struct stop_context *sc = (struct stop_context *) arg; if (sc->thread != NULL) - sc->thread->refcount--; + { + if (sc->thread->refcount == 0) + delete sc->thread; + else + sc->thread->refcount--; + } xfree (sc); } diff --git a/gdb/thread.c b/gdb/thread.c index 28907c5..b38c5bd 100644 --- a/gdb/thread.c +++ b/gdb/thread.c @@ -205,8 +205,11 @@ init_thread_list (void) for (tp = thread_list; tp; tp = tpnext) { tpnext = tp->next; - delete tp; + if (tp->refcount == 0) + delete tp; + else + tp->refcount--; } thread_list = NULL; @@ -1636,7 +1639,12 @@ restore_current_thread_cleanup_dtor (void *arg) tp = find_thread_ptid (old->inferior_ptid); if (tp) - tp->refcount--; + { + if (tp->refcount == 0) + delete tp; + else + tp->refcount--; + } inf = find_inferior_id (old->inf_id); if (inf != NULL) inf->removable = old->was_removable; @@ -1653,7 +1661,12 @@ set_thread_refcount (void *data) = (struct thread_array_cleanup *) data; for (k = 0; k != ta_cleanup->count; k++) - ta_cleanup->tp_array[k]->refcount--; + { + if (ta_cleanup->tp_array[k]->refcount == 0) + delete ta_cleanup->tp_array[k]; + else + ta_cleanup->tp_array[k]->refcount--; + } } struct cleanup *