From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (qmail 11644 invoked by alias); 21 Sep 2009 15:15:00 -0000 Received: (qmail 11588 invoked by uid 22791); 21 Sep 2009 15:14:58 -0000 X-SWARE-Spam-Status: No, hits=-2.1 required=5.0 tests=AWL,BAYES_00 X-Spam-Check-By: sourceware.org Received: from mailhost.u-strasbg.fr (HELO mailhost.u-strasbg.fr) (130.79.200.153) by sourceware.org (qpsmtpd/0.43rc1) with ESMTP; Mon, 21 Sep 2009 15:14:53 +0000 Received: from baal.u-strasbg.fr (baal.u-strasbg.fr [IPv6:2001:660:2402::41]) by mailhost.u-strasbg.fr (8.14.2/jtpda-5.5pre1) with ESMTP id n8LFEnFT055731 for ; Mon, 21 Sep 2009 17:14:49 +0200 (CEST) (envelope-from muller@ics.u-strasbg.fr) Received: from mailserver.u-strasbg.fr (ms2.u-strasbg.fr [IPv6:2001:660:2402:d::11]) by baal.u-strasbg.fr (8.14.0/jtpda-5.5pre1) with ESMTP id n8LFEnR6076663 for ; Mon, 21 Sep 2009 17:14:49 +0200 (CEST) (envelope-from muller@ics.u-strasbg.fr) Received: from d620muller (www-ics.u-strasbg.fr [130.79.210.225]) (user=mullerp mech=LOGIN) by mailserver.u-strasbg.fr (8.14.3/jtpda-5.5pre1) with ESMTP id n8LFEmkb037188 (version=TLSv1/SSLv3 cipher=RC4-MD5 bits=128 verify=NO) for ; Mon, 21 Sep 2009 17:14:49 +0200 (CEST) (envelope-from muller@ics.u-strasbg.fr) From: "Pierre Muller" To: Subject: [RFA] windows-nat.c Cygwin save_context fix Date: Mon, 21 Sep 2009 15:15:00 -0000 Message-ID: <001d01ca3ace$4878c9f0$d96a5dd0$@u-strasbg.fr> MIME-Version: 1.0 Content-Type: text/plain; charset="us-ascii" Content-Transfer-Encoding: 7bit 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-09/txt/msg00664.txt.bz2 Cygwin has a way to give a "fake" context for an exception using a OUTPUT_DEBUG_STRING_EVENT. While trying to debug some crashes inside cygwin dll, I realized the the saved_context code has a problem. The saved context was correctly written to the thread_info struct, but later overwritten by a call to GetThreadContext. After the cygwin special output_debug_string was correctly converted into a context stored in saved_context. The next call to do_windows_fetch_inferior_registers then copied this context to the thread_info struct, set the reload_context field to zero. But a later call to thread_rec() with get_context=1 can reset reload_context to one, if suspended field is zero (this only happens if it is not the main thread). My patch fixes the problem by explicitly calling SuspendThread for the threaded of the saved_context if suspended is still zero at that point. Pierre Muller Pascal language support maintainer for GDB 2009-09-21 Pierre Muller * src/gdb/windows-nat.c (saved_threadid): New variable. (do_windows_fetch_inferior_registers): Check for correct thread id and force call to SuspendThread if needed. (handle_output_debug_string): Set saved_threadid. Index: src/gdb/windows-nat.c =================================================================== RCS file: /cvs/src/src/gdb/windows-nat.c,v retrieving revision 1.196 diff -u -p -r1.196 windows-nat.c --- src/gdb/windows-nat.c 2 Jul 2009 17:21:07 -0000 1.196 +++ src/gdb/windows-nat.c 21 Sep 2009 14:53:38 -0000 @@ -97,6 +98,7 @@ static CORE_ADDR cygwin_load_start; static CORE_ADDR cygwin_load_end; #endif +static int saved_threadid; static int have_saved_context; /* True if we've saved context from a cygwin signal. */ static CONTEXT saved_context; /* Containes the saved context from a cygwin signal. */ @@ -381,11 +383,23 @@ do_windows_fetch_inferior_registers (str if (current_thread->reload_context) { #ifdef __COPY_CONTEXT_SIZE - if (have_saved_context) + if (have_saved_context && current_thread->id == saved_threadid) { /* Lie about where the program actually is stopped since cygwin has informed us that we should consider the signal to have occurred at another location which is stored in "saved_context. */ + if (!current_thread->suspended) + /* Force suspend to avoid resetting reload_context + later in get_thread. */ + { + if (SuspendThread (current_thread->h) == (DWORD) -1) + { + DWORD err = GetLastError (); + warning (_("SuspendThread failed. (winerr %d)"), + (int) err); + } + current_thread->suspended = 1; + } memcpy (¤t_thread->context, &saved_context, __COPY_CONTEXT_SIZE); have_saved_context = 0; } @@ -863,6 +877,7 @@ handle_output_debug_string (struct targe &saved_context, __COPY_CONTEXT_SIZE, &n) && n == __COPY_CONTEXT_SIZE) have_saved_context = 1; + saved_threadid = retval; current_event.dwThreadId = retval; } }