From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (qmail 11377 invoked by alias); 12 Nov 2009 00:35:16 -0000 Received: (qmail 11369 invoked by uid 22791); 12 Nov 2009 00:35:15 -0000 X-SWARE-Spam-Status: No, hits=-2.2 required=5.0 tests=AWL,BAYES_00,SPF_HELO_PASS,SPF_PASS X-Spam-Check-By: sourceware.org Received: from smtp-out.google.com (HELO smtp-out.google.com) (216.239.33.17) by sourceware.org (qpsmtpd/0.43rc1) with ESMTP; Thu, 12 Nov 2009 00:35:10 +0000 Received: from wpaz24.hot.corp.google.com (wpaz24.hot.corp.google.com [172.24.198.88]) by smtp-out.google.com with ESMTP id nAC0Z77G011920 for ; Thu, 12 Nov 2009 00:35:08 GMT Received: from ppluzhnikov.mtv.corp.google.com (ppluzhnikov.mtv.corp.google.com [172.18.118.92]) by wpaz24.hot.corp.google.com with ESMTP id nAC0Z445021898; Wed, 11 Nov 2009 16:35:04 -0800 Received: by ppluzhnikov.mtv.corp.google.com (Postfix, from userid 74925) id 29C4876D6F; Wed, 11 Nov 2009 16:35:04 -0800 (PST) To: gdb-patches@sourceware.org Cc: ppluzhnikov@google.com Subject: [patch] Fix for PR gdb/10838 Message-Id: <20091112003504.29C4876D6F@ppluzhnikov.mtv.corp.google.com> Date: Thu, 12 Nov 2009 00:35:00 -0000 From: ppluzhnikov@google.com (Paul Pluzhnikov) X-IsSubscribed: yes 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 X-SW-Source: 2009-11/txt/msg00273.txt.bz2 Greetings, In http://sourceware.org/bugzilla/show_bug.cgi?id=10838 gdb attach; detach; attach sequence leaves libpthread in hosed state. The root cause turned out to be that this: td_event_emptyset (&events); info->td_ta_set_event_p (info->thread_agent, &events); is a no-op -- glibc ORs new event bits in, but doesn't clear any already set bits. To clear them, one must call td_ta_clear_event() instead. Here is a patch which fixes this in gdb and gdbserver. Tested (GDB only) on Linux/x86_64 with no regressions. Thanks, -- Paul Pluzhnikov gdb/ChangeLog: 2009-11-11 Paul Pluzhnikov PR gdb/10838 * linux-thread-db.c (thread_db_info): New member. (disable_thread_event_reporting): Call td_ta_clear_event. gdbserver/ChangeLog: 2009-11-11 Paul Pluzhnikov PR gdb/10838 * thread-db.c (thread_db_free): Call td_ta_clear_event. Index: linux-thread-db.c =================================================================== RCS file: /cvs/src/src/gdb/linux-thread-db.c,v retrieving revision 1.67 diff -u -p -u -r1.67 linux-thread-db.c --- linux-thread-db.c 3 Nov 2009 17:14:56 -0000 1.67 +++ linux-thread-db.c 12 Nov 2009 00:21:02 -0000 @@ -141,6 +141,8 @@ struct thread_db_info td_event_e event, td_notify_t *ptr); td_err_e (*td_ta_set_event_p) (const td_thragent_t *ta, td_thr_events_t *event); + td_err_e (*td_ta_clear_event_p) (const td_thragent_t *ta, + td_thr_events_t *event); td_err_e (*td_ta_event_getmsg_p) (const td_thragent_t *ta, td_event_msg_t *msg); @@ -701,6 +703,7 @@ try_thread_db_load_1 (struct thread_db_i /* These are not essential. */ info->td_ta_event_addr_p = dlsym (info->handle, "td_ta_event_addr"); info->td_ta_set_event_p = dlsym (info->handle, "td_ta_set_event"); + info->td_ta_clear_event_p = dlsym (info->handle, "td_ta_clear_event"); info->td_ta_event_getmsg_p = dlsym (info->handle, "td_ta_event_getmsg"); info->td_thr_event_enable_p = dlsym (info->handle, "td_thr_event_enable"); info->td_thr_tls_get_addr_p = dlsym (info->handle, "td_thr_tls_get_addr"); @@ -907,14 +910,14 @@ thread_db_load (void) static void disable_thread_event_reporting (struct thread_db_info *info) { - if (info->td_ta_set_event_p != NULL) + if (info->td_ta_clear_event_p != NULL) { td_thr_events_t events; /* Set the process wide mask saying we aren't interested in any events anymore. */ - td_event_emptyset (&events); - info->td_ta_set_event_p (info->thread_agent, &events); + td_event_fillset (&events); + info->td_ta_clear_event_p (info->thread_agent, &events); } info->td_create_bp_addr = 0; Index: gdbserver/thread-db.c =================================================================== RCS file: /cvs/src/src/gdb/gdbserver/thread-db.c,v retrieving revision 1.26 diff -u -p -u -r1.26 thread-db.c --- gdbserver/thread-db.c 29 Oct 2009 17:43:44 -0000 1.26 +++ gdbserver/thread-db.c 12 Nov 2009 00:21:02 -0000 @@ -759,6 +759,19 @@ thread_db_free (struct process_info *pro { #ifndef USE_LIBTHREAD_DB_DIRECTLY td_err_e (*td_ta_delete_p) (td_thragent_t *); + td_err_e (*td_ta_clear_event_p) (const td_thragent_t *ta, + td_thr_events_t *event); + + td_ta_clear_event_p = dlsym (thread_db->handle, "td_ta_clear_event"); + if (td_ta_clear_event_p != NULL) + { + td_thr_events_t events; + + /* Set the process wide mask saying we aren't interested in any + events anymore. */ + td_event_fillset (&events); + (*td_ta_clear_event_p) (thread_db->thread_agent, &events); + } td_ta_delete_p = dlsym (thread_db->handle, "td_ta_delete"); if (td_ta_delete_p != NULL) @@ -766,6 +779,10 @@ thread_db_free (struct process_info *pro dlclose (thread_db->handle); #else + td_thd_events_t events; + + td_event_fillset (&events); + td_ta_clear_event (thread_db->thread_agent, &events); td_ta_delete (thread_db->thread_agent); #endif /* USE_LIBTHREAD_DB_DIRECTLY */