From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (qmail 11904 invoked by alias); 12 Jun 2012 18:44:59 -0000 Received: (qmail 11894 invoked by uid 22791); 12 Jun 2012 18:44:57 -0000 X-SWARE-Spam-Status: No, hits=-6.7 required=5.0 tests=AWL,BAYES_00,KHOP_RCVD_UNTRUST,RCVD_IN_DNSWL_HI,RCVD_IN_HOSTKARMA_W,SPF_HELO_PASS,T_FILL_THIS_FORM_SHORT,T_RP_MATCHES_RCVD X-Spam-Check-By: sourceware.org Received: from mx1.redhat.com (HELO mx1.redhat.com) (209.132.183.28) by sourceware.org (qpsmtpd/0.43rc1) with ESMTP; Tue, 12 Jun 2012 18:44:42 +0000 Received: from int-mx12.intmail.prod.int.phx2.redhat.com (int-mx12.intmail.prod.int.phx2.redhat.com [10.5.11.25]) by mx1.redhat.com (8.14.4/8.14.4) with ESMTP id q5CIighH022859 (version=TLSv1/SSLv3 cipher=DHE-RSA-AES256-SHA bits=256 verify=OK) for ; Tue, 12 Jun 2012 14:44:42 -0400 Received: from brno.lan (ovpn01.gateway.prod.ext.ams2.redhat.com [10.39.146.11]) by int-mx12.intmail.prod.int.phx2.redhat.com (8.14.4/8.14.4) with ESMTP id q5CIifFx010150 for ; Tue, 12 Jun 2012 14:44:41 -0400 Subject: [PATCH] Don't switch to the event thread early in non-stop mode. To: gdb-patches@sourceware.org From: Pedro Alves Date: Tue, 12 Jun 2012 18:44:00 -0000 Message-ID: <20120612184440.29776.25769.stgit@brno.lan> User-Agent: StGit/0.16 MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" 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: 2012-06/txt/msg00368.txt.bz2 It is largely no longer necessary to special case non-stop mode, WRT caring about the current context being set (the real "context switching" context_switch used to exist for, is gone) before calling handle_inferior event. Trying to harmonize all-stop and non-stop modes a bit further, this removes that non-stop special casing. I went through handle_inferior_event looking for places that miss switching to the event thread and made them do so. The missing switching was never missed for single-process all-stop, but it's important for both multi-process all-stop, and non-stop, so we don't e.g., remove breakpoints in the context of a previously selected inferior or thread that has already exited, or is presently running. I actually was going to push a patch that centralized all the context_switch calls at the top of handle_inferior_event (and I've mentioned wanted to do it before a few times in the past years), but in the end decided against, mostly because it felt counter to all the parameterization in handle_inferior_event that moves away from global state. Tested on x86_64 Fedora 16, native and gdbserver, and applied. 2012-06-12 Pedro Alves * infrun.c (infrun_thread_stop_requested_callback): Don't switch threads here. (prepare_for_detach): No longer context switch here in non-stop mode. (fetch_inferior_event): Ditto. (handle_inferior_event) : Switch to the event thread before removing breakpoints. Switch to the event thread before inserting breakpoints and resuming. (handle_inferior_event) : Switch to the event thread before resuming. (handle_inferior_event) : Switch to the event thread before removing breakpoints. --- gdb/infrun.c | 30 ++++++++++-------------------- 1 files changed, 10 insertions(+), 20 deletions(-) diff --git a/gdb/infrun.c b/gdb/infrun.c index b98e379..e36e42e 100644 --- a/gdb/infrun.c +++ b/gdb/infrun.c @@ -2437,8 +2437,6 @@ infrun_thread_stop_requested_callback (struct thread_info *info, void *arg) old_chain = make_cleanup_restore_current_thread (); - switch_to_thread (info->ptid); - /* Go through handle_inferior_event/normal_stop, so we always have consistent output as if the stop event had been reported. */ @@ -2655,14 +2653,6 @@ prepare_for_detach (void) old_chain_2 = make_cleanup (finish_thread_state_cleanup, &minus_one_ptid); - /* In non-stop mode, each thread is handled individually. - Switch early, so the global state is set correctly for this - thread. */ - if (non_stop - && ecs->ws.kind != TARGET_WAITKIND_EXITED - && ecs->ws.kind != TARGET_WAITKIND_SIGNALLED) - context_switch (ecs->ptid); - /* Now figure out what to do with the result of the result. */ handle_inferior_event (ecs); @@ -2789,16 +2779,6 @@ fetch_inferior_event (void *client_data) if (debug_infrun) print_target_wait_results (waiton_ptid, ecs->ptid, &ecs->ws); - if (non_stop - && ecs->ws.kind != TARGET_WAITKIND_IGNORE - && ecs->ws.kind != TARGET_WAITKIND_NO_RESUMED - && ecs->ws.kind != TARGET_WAITKIND_EXITED - && ecs->ws.kind != TARGET_WAITKIND_SIGNALLED) - /* In non-stop mode, each thread is handled individually. Switch - early, so the global state is set correctly for this - thread. */ - context_switch (ecs->ptid); - /* If an error happens while handling the event, propagate GDB's knowledge of the executing state to the frontend/user running state. */ @@ -3380,6 +3360,9 @@ handle_inferior_event (struct execution_control_state *ecs) we're attaching or setting up a remote connection. */ if (stop_soon == STOP_QUIETLY || stop_soon == NO_STOP_QUIETLY) { + if (!ptid_equal (ecs->ptid, inferior_ptid)) + context_switch (ecs->ptid); + /* Loading of shared libraries might have changed breakpoint addresses. Make sure new breakpoints are inserted. */ if (stop_soon == NO_STOP_QUIETLY @@ -3395,6 +3378,9 @@ handle_inferior_event (struct execution_control_state *ecs) case TARGET_WAITKIND_SPURIOUS: if (debug_infrun) fprintf_unfiltered (gdb_stdlog, "infrun: TARGET_WAITKIND_SPURIOUS\n"); + if (!ptid_equal (ecs->ptid, inferior_ptid) + && !ptid_equal (ecs->ptid, minus_one_ptid)) + context_switch (ecs->ptid); resume (0, GDB_SIGNAL_0); prepare_to_wait (ecs); return; @@ -3769,6 +3755,8 @@ handle_inferior_event (struct execution_control_state *ecs) "infrun: stepping_past_" "singlestep_breakpoint\n"); /* Pull the single step breakpoints out of the target. */ + if (!ptid_equal (ecs->ptid, inferior_ptid)) + context_switch (ecs->ptid); remove_single_step_breakpoints (); singlestep_breakpoints_inserted_p = 0; @@ -3801,6 +3789,8 @@ handle_inferior_event (struct execution_control_state *ecs) /* Pull the single step breakpoints out of the target. */ if (singlestep_breakpoints_inserted_p) { + if (!ptid_equal (ecs->ptid, inferior_ptid)) + context_switch (ecs->ptid); remove_single_step_breakpoints (); singlestep_breakpoints_inserted_p = 0; }