From patchwork Tue Apr 14 11:03:02 2015 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Jon Turney X-Patchwork-Id: 6211 Received: (qmail 55998 invoked by alias); 14 Apr 2015 11:03:24 -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 55981 invoked by uid 89); 14 Apr 2015 11:03:23 -0000 Authentication-Results: sourceware.org; auth=none X-Virus-Found: No X-Spam-SWARE-Status: No, score=0.2 required=5.0 tests=AWL, BAYES_50, KAM_LAZY_DOMAIN_SECURITY, RCVD_IN_DNSWL_NONE autolearn=no version=3.3.2 X-HELO: rgout0305.bt.lon5.cpcloud.co.uk Received: from rgout0305.bt.lon5.cpcloud.co.uk (HELO rgout0305.bt.lon5.cpcloud.co.uk) (65.20.0.211) by sourceware.org (qpsmtpd/0.93/v0.84-503-g423c35a) with ESMTP; Tue, 14 Apr 2015 11:03:21 +0000 X-OWM-Source-IP: 86.179.112.55(GB) X-OWM-Env-Sender: jonturney@btinternet.com X-CTCH-RefID: str=0001.0A090203.552CF3F6.0085, ss=1, re=0.000, recu=0.000, reip=0.000, cl=1, cld=1, fgs=0 X-Junkmail-Premium-Raw: score=27/50, refid=2.7.2:2015.4.6.93621:17:27.888, ip=86.179.112.55, rules=__HAS_FROM, __TO_MALFORMED_2, __TO_NO_NAME, __SUBJ_ALPHA_END, __HAS_MSGID, __SANE_MSGID, __HAS_X_MAILER, __ANY_URI, __URI_NO_WWW, __URI_NO_PATH, __CP_NOT_1, __MIME_TEXT_ONLY, RDNS_GENERIC_POOLED, __URI_NS, SXL_IP_DYNAMIC[55.112.179.86.fur], HTML_00_01, HTML_00_10, RDNS_SUSP_GENERIC, RDNS_SUSP X-CTCH-Spam: Unknown Received: from localhost.localdomain (86.179.112.55) by rgout03.bt.lon5.cpcloud.co.uk (8.6.122.06) (authenticated as jonturney@btinternet.com) id 551D2F0E014889FF; Tue, 14 Apr 2015 12:03:18 +0100 From: Jon Turney To: gdb-patches@sourceware.org Cc: Jon Turney Subject: [PATCH] Fixes to Cygwin-specific signal handling Date: Tue, 14 Apr 2015 12:03:02 +0100 Message-Id: <1429009382-21040-1-git-send-email-jon.turney@dronecode.org.uk> Originally by cgf, this patch has been carried in Cygwin's gdb package for a few years. I've cleaned it up a bit and revised it for master. Without this patch, it's impossible to usefully run the testsuite on Cygwin. gdb/ChangeLog: 2015-04-11 Jon Turney * windows-nat.c: Replace have_saved_context with signal_thread_id throughout. (thread_rec): Don't retrieve context if we have a saved one. Ignore 'Invalid Handle' errors. (handle_output_debug_string): Mark signal context as not to be written to inferior by windows_continue() or windows_resume(). (get_windows_debug_event): Replace retval with thread_id throughout. Don't clear any saved context. --- gdb/ChangeLog | 11 +++++++++++ gdb/windows-nat.c | 55 +++++++++++++++++++++++++++++++------------------------ 2 files changed, 42 insertions(+), 24 deletions(-) diff --git a/gdb/windows-nat.c b/gdb/windows-nat.c index fd31083..5c191de 100644 --- a/gdb/windows-nat.c +++ b/gdb/windows-nat.c @@ -118,8 +118,8 @@ static COORD WINAPI (*GetConsoleFontSize) (HANDLE, DWORD); # define bad_GetModuleFileNameEx bad_GetModuleFileNameExW #endif -static int have_saved_context; /* True if we've saved context from a - cygwin signal. */ +static DWORD signal_thread_id; /* Non-zero thread id if we have a saved + context from a cygwin signal. */ static CONTEXT saved_context; /* Containes the saved context from a cygwin signal. */ @@ -301,7 +301,8 @@ thread_rec (DWORD id, int get_context) { if (!th->suspended && get_context) { - if (get_context > 0 && id != current_event.dwThreadId) + if (get_context > 0 && id != current_event.dwThreadId + && id != signal_thread_id) { if (SuspendThread (th->h) == (DWORD) -1) { @@ -310,8 +311,11 @@ thread_rec (DWORD id, int get_context) /* We get Access Denied (5) when trying to suspend threads that Windows started on behalf of the debuggee, usually when those threads are just - about to exit. */ - if (err != ERROR_ACCESS_DENIED) + about to exit. + We can get Invalid Handle (6) if the main thread + has exited. */ + if (err != ERROR_INVALID_HANDLE + && err != ERROR_ACCESS_DENIED) warning (_("SuspendThread (tid=0x%x) failed." " (winerr %u)"), (unsigned) id, (unsigned) err); @@ -433,7 +437,7 @@ do_windows_fetch_inferior_registers (struct regcache *regcache, int r) if (current_thread->reload_context) { #ifdef __COPY_CONTEXT_SIZE - if (have_saved_context) + if (signal_thread_id) { /* Lie about where the program actually is stopped since cygwin has informed us that we should consider the signal @@ -441,7 +445,7 @@ do_windows_fetch_inferior_registers (struct regcache *regcache, int r) "saved_context. */ memcpy (¤t_thread->context, &saved_context, __COPY_CONTEXT_SIZE); - have_saved_context = 0; + signal_thread_id = 0; } else #endif @@ -849,8 +853,12 @@ handle_output_debug_string (struct target_waitstatus *ourstatus) &saved_context, __COPY_CONTEXT_SIZE, &n) && n == __COPY_CONTEXT_SIZE) - have_saved_context = 1; - current_event.dwThreadId = retval; + { + signal_thread_id = retval; + saved_context.ContextFlags = 0; /* Don't attempt to call SetThreadContext */ + } + else + retval = 0; } } #endif @@ -1317,7 +1325,7 @@ get_windows_debug_event (struct target_ops *ops, DWORD continue_status, event_code; windows_thread_info *th; static windows_thread_info dummy_thread_info; - int retval = 0; + DWORD thread_id = 0; last_sig = GDB_SIGNAL_0; @@ -1330,7 +1338,6 @@ get_windows_debug_event (struct target_ops *ops, event_code = current_event.dwDebugEventCode; ourstatus->kind = TARGET_WAITKIND_SPURIOUS; th = NULL; - have_saved_context = 0; switch (event_code) { @@ -1348,14 +1355,14 @@ get_windows_debug_event (struct target_ops *ops, /* Kludge around a Windows bug where first event is a create thread event. Caused when attached process does not have a main thread. */ - retval = fake_create_process (); - if (retval) + thread_id = fake_create_process (); + if (thread_id) saw_create++; } break; } /* Record the existence of this thread. */ - retval = current_event.dwThreadId; + thread_id = current_event.dwThreadId; th = windows_add_thread (ptid_build (current_event.dwProcessId, 0, current_event.dwThreadId), current_event.u.CreateThread.hThread, @@ -1398,7 +1405,7 @@ get_windows_debug_event (struct target_ops *ops, current_event.dwThreadId), current_event.u.CreateProcessInfo.hThread, current_event.u.CreateProcessInfo.lpThreadLocalBase); - retval = current_event.dwThreadId; + thread_id = current_event.dwThreadId; break; case EXIT_PROCESS_DEBUG_EVENT: @@ -1417,7 +1424,7 @@ get_windows_debug_event (struct target_ops *ops, { ourstatus->kind = TARGET_WAITKIND_EXITED; ourstatus->value.integer = current_event.u.ExitProcess.dwExitCode; - retval = main_thread_id; + thread_id = main_thread_id; } break; @@ -1432,7 +1439,7 @@ get_windows_debug_event (struct target_ops *ops, catch_errors (handle_load_dll, NULL, (char *) "", RETURN_MASK_ALL); ourstatus->kind = TARGET_WAITKIND_LOADED; ourstatus->value.integer = 0; - retval = main_thread_id; + thread_id = main_thread_id; break; case UNLOAD_DLL_DEBUG_EVENT: @@ -1445,7 +1452,7 @@ get_windows_debug_event (struct target_ops *ops, catch_errors (handle_unload_dll, NULL, (char *) "", RETURN_MASK_ALL); ourstatus->kind = TARGET_WAITKIND_LOADED; ourstatus->value.integer = 0; - retval = main_thread_id; + thread_id = main_thread_id; break; case EXCEPTION_DEBUG_EVENT: @@ -1461,7 +1468,7 @@ get_windows_debug_event (struct target_ops *ops, continue_status = DBG_EXCEPTION_NOT_HANDLED; break; case 1: - retval = current_event.dwThreadId; + thread_id = current_event.dwThreadId; break; case -1: last_sig = 1; @@ -1477,7 +1484,7 @@ get_windows_debug_event (struct target_ops *ops, "OUTPUT_DEBUG_STRING_EVENT")); if (saw_create != 1) break; - retval = handle_output_debug_string (ourstatus); + thread_id = handle_output_debug_string (ourstatus); break; default: @@ -1491,7 +1498,7 @@ get_windows_debug_event (struct target_ops *ops, break; } - if (!retval || saw_create != 1) + if (!thread_id || saw_create != 1) { if (continue_status == -1) windows_resume (ops, minus_one_ptid, 0, 1); @@ -1501,12 +1508,12 @@ get_windows_debug_event (struct target_ops *ops, else { inferior_ptid = ptid_build (current_event.dwProcessId, 0, - retval); - current_thread = th ?: thread_rec (current_event.dwThreadId, TRUE); + thread_id); + current_thread = th ?: thread_rec (thread_id, TRUE); } out: - return retval; + return (int) thread_id; } /* Wait for interesting events to occur in the target process. */