From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (qmail 31483 invoked by alias); 5 Aug 2013 12:01:56 -0000 Mailing-List: contact gdb-patches-help@sourceware.org; run by ezmlm Precedence: bulk List-Id: List-Subscribe: List-Archive: List-Post: List-Help: , Sender: gdb-patches-owner@sourceware.org Received: (qmail 31449 invoked by uid 89); 5 Aug 2013 12:01:56 -0000 X-Spam-SWARE-Status: No, score=-3.4 required=5.0 tests=AWL,BAYES_00,KHOP_RCVD_UNTRUST,KHOP_THREADED,RCVD_IN_HOSTKARMA_W,RCVD_IN_HOSTKARMA_WL,RDNS_NONE autolearn=no version=3.3.1 Received: from Unknown (HELO relay1.mentorg.com) (192.94.38.131) by sourceware.org (qpsmtpd/0.84/v0.84-167-ge50287c) with ESMTP; Mon, 05 Aug 2013 12:01:54 +0000 Received: from svr-orw-exc-10.mgc.mentorg.com ([147.34.98.58]) by relay1.mentorg.com with esmtp id 1V6JTu-0000r2-Qo from Muhammad_Waqas@mentor.com ; Mon, 05 Aug 2013 05:01:46 -0700 Received: from SVR-ORW-FEM-04.mgc.mentorg.com ([147.34.97.41]) by SVR-ORW-EXC-10.mgc.mentorg.com with Microsoft SMTPSVC(6.0.3790.4675); Mon, 5 Aug 2013 05:01:46 -0700 Received: from [137.202.157.111] (147.34.91.1) by SVR-ORW-FEM-04.mgc.mentorg.com (147.34.97.41) with Microsoft SMTP Server (TLS) id 14.2.247.3; Mon, 5 Aug 2013 05:01:46 -0700 Message-ID: <51FF941E.7060705@codesourcery.com> Date: Mon, 05 Aug 2013 12:01:00 -0000 From: Muhammad Waqas User-Agent: Mozilla/5.0 (X11; Linux x86_64; rv:17.0) Gecko/20130623 Thunderbird/17.0.7 MIME-Version: 1.0 To: Pedro Alves CC: Yao Qi , , , Subject: Re: [PATCH with testcase] Bug 11568 - delete thread-specific breakpoint on the thread exit References: <51F619CE.5040407@codesourcery.com> <51F633E5.7000302@codesourcery.com> <51F65519.2080806@codesourcery.com> <51F67992.30704@codesourcery.com> <51F7967E.3060900@codesourcery.com> <51FA4D21.4000309@redhat.com> <51FA5806.7050505@codesourcery.com> <51FB7F9E.30701@redhat.com> In-Reply-To: <51FB7F9E.30701@redhat.com> Content-Type: text/plain; charset="UTF-8"; format=flowed Content-Transfer-Encoding: 7bit X-SW-Source: 2013-08/txt/msg00135.txt.bz2 On 08/02/2013 02:45 PM, Pedro Alves wrote: > On 08/01/2013 01:43 PM, Muhammad Waqas wrote: >>>>>> + || !target_thread_alive (tp->ptid))) >>>>>> + if ( tp != NULL && (tp->state == THREAD_EXITED >>>>>> + || !target_thread_alive (tp->ptid))) >>>> Do we really need this target_thread_alive call? It >>>> means we have extra remote traffic whenever we have a thread >>>> specific breakpoint in the list. If the user (or GDB itself) >>>> hasn't refreshed the thread list, is there any harm in delaying >>>> deleting the breakpoint? >>>> >>>> But, I think I agree with Yao in that this doesn't look like >>>> the right way to do this. >>>> >>>> In fact, breakpoint_auto_delete is only called when the >>>> target reports some stop. If you're trying to delete >>>> stale thread specific breakpoints, then you'd want to >>>> do that even if the target hasn't reported a stop, right? >>>> >>>> Say, in non-stop mode, w/ the remote target, if you have two >>>> threads, set a thread-specific break on thread 2, and while >>>> all threads are running free in busy loops, not reporting >>>> any event, keep doing "info threads", and "info break". At some >>>> point thread #2 exits. You can see that from "info threads". >>>> But "info break" will still show you the stale breakpoint... >> If breakpoint will be deleted when thread list is updated through >> user or GDB and also when info break command is executed >> by user, Will it work? What will you say about this technique? >> > I wouldn't even consider special casing "info break". Otherwise, > you end up considering whether to handle all sorts of breakpoint > manipulation commands, like "enable", "disable", etc., and what > to do if the thread is already gone. > > Tie this to GDB's own lifetime of the inferior's threads. If GDB > learns the thread is gone, remove the breakpoint. Otherwise, > leave it there. Whether to remove the breakpoint immediately, > or mark it as disp_del_at_next_stop (and hide it, say, set its > bp->num to 0) is another question. You'll note that > clear_thread_inferior_resources does the latter. (That's because > most of GDB's native targets can't touch memory of running processes.) > Thanks for review and helping me out. Now I register a function for deletion of breakpoint with thread_exit if breakpoint is on thread so breakpoint will be deleted when thread finished. Changlog 2013-08-05 Muhammad Waqas PR gdb/11568 * breakpoint.c (remove_threaded_breakpoints): New function. * breakpoint.c (install_breakpoint): If breakpoint is on specific thread remove_threaded_breakpoints will be registered with thread_exit. Index: ./../../breakpoint.c =================================================================== RCS file: /cvs/src/src/gdb/breakpoint.c,v retrieving revision 1.773 diff -u -p -r1.773 breakpoint.c --- ./../../breakpoint.c 24 Jul 2013 19:50:32 -0000 1.773 +++ ./../../breakpoint.c 5 Aug 2013 11:51:43 -0000 @@ -200,6 +200,8 @@ typedef enum } insertion_state_t; +static void remove_threaded_breakpoints (struct thread_info *tp, int silent); + static int remove_breakpoint (struct bp_location *, insertion_state_t); static int remove_breakpoint_1 (struct bp_location *, insertion_state_t); @@ -2928,6 +2930,21 @@ remove_breakpoints (void) return val; } +static void +remove_threaded_breakpoints(struct thread_info *tp, int silent) +{ + struct breakpoint *b, *b_tmp; + + ALL_BREAKPOINTS_SAFE (b, b_tmp) + { + if (b->thread == tp->num) + { + b->disposition = disp_del_at_next_stop; + b->number = 0; + } + } +} + /* Remove breakpoints of process PID. */ int @@ -8450,7 +8467,12 @@ install_breakpoint (int internal, struct if (!internal) mention (b); observer_notify_breakpoint_created (b); - + + if (b->thread > 0) + { + observer_attach_thread_exit (remove_threaded_breakpoints); + } + if (update_gll) update_global_location_list (1); } Changlog 2013-07-24 Muhammad Waqas Jan Kratochvil PR gdb/11568 *gdb.thread/thread-specific-bp.c: Newfile. *gdb.thread/thread-specific-bp.exp: Newfile. testcase now testing All stop and non stop mode explicitly Index: thread-specific-bp.c =================================================================== RCS file: thread-specific-bp.c diff -N thread-specific-bp.c --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ thread-specific-bp.c 5 Aug 2013 11:51:51 -0000 @@ -0,0 +1,33 @@ +/* This testcase is part of GDB, the GNU debugger. + + Copyright 2013 Free Software Foundation, Inc. + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see . */ + +#include + +static void * +start (void *arg) +{ + return NULL; +} + +int +main (void) +{ + pthread_t thread; + pthread_create (&thread, NULL, start, NULL); + pthread_join (thread, NULL); + return 0; /*set break here*/ +} Index: thread-specific-bp.exp =================================================================== RCS file: thread-specific-bp.exp diff -N thread-specific-bp.exp --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ thread-specific-bp.exp 5 Aug 2013 11:52:03 -0000 @@ -0,0 +1,84 @@ +# Copyright (C) 2013 Free Software Foundation, Inc. + +# This program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 3 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program. If not, see . +# +# Verify that a thread-specific breakpoint is deleted when the +# corresponding thread is gone. + +standard_testfile + +set mode "All stop" + +if {[gdb_compile_pthreads \ + "${srcdir}/${subdir}/${srcfile}" \ + "${binfile}" executable {debug} ] != "" } { + return -1 +} + +clean_restart ${binfile} + +proc check_threaded_breakpoint {} { + global gdb_prompt mode + gdb_breakpoint "start" + gdb_continue_to_breakpoint "start" + set thre 0 + gdb_test_multiple "info threads" "get thread 1 id" { + -re "(\[0-9\]+)(\[^\n\r\]*Thread\[^\n\r\]*start.*)($gdb_prompt $)" { + pass "$mode: thread created" + # get the id of thread + set thre $expect_out(1,string) + } + } + gdb_breakpoint [gdb_get_line_number "set break here"] + + # Force GDB to update its knowledge on existing threads when this + # breakpoint is hit. Otherwise, GDB doesn't realize thread $thre + # has exited and doesn't remove the thread specific breakpoint. + gdb_test "commands\ninfo threads\nend" "End with.*" "$mode: add breakpoint commands" + gdb_breakpoint "main thread $thre" + gdb_test "info break" ".*breakpoint.*thread $thre" "$mode: Breakpoint set" + gdb_test "thread $thre" "Switching to thread $thre.*" "$mode: Thread $thre selected" + gdb_continue_to_breakpoint "$mode: set break here" + set test "$mode: thread-specific breakpoint is deleted" + gdb_test_multiple "info breakpoint" $test { + -re "thread $thre.*$gdb_prompt $" { + fail $test + } + -re "$gdb_prompt $" { + pass $test + } + } +} + +if ![runto_main] { + untested "could not run to main" + return -1 +} + +# Testing in all stop mode. +check_threaded_breakpoint + +clean_restart ${binfile} + +gdb_test "set target-async on" ".*" "Set async mode" +gdb_test "set non-stop on" ".*" "Set non stop mode" + +if ![runto_main] { + untested "could not run to main" + return -1 +} + +# Testing in non-stop+async mode. +set mode "non-stop\\async" +check_threaded_breakpoint