From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (qmail 88494 invoked by alias); 23 Jul 2015 23:26:03 -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 88482 invoked by uid 89); 23 Jul 2015 23:26:02 -0000 Authentication-Results: sourceware.org; auth=none X-Virus-Found: No X-Spam-SWARE-Status: No, score=-2.0 required=5.0 tests=AWL,BAYES_00,KAM_LAZY_DOMAIN_SECURITY,RP_MATCHES_RCVD,SPF_HELO_PASS autolearn=ham version=3.3.2 X-HELO: mx1.redhat.com Received: from mx1.redhat.com (HELO mx1.redhat.com) (209.132.183.28) by sourceware.org (qpsmtpd/0.93/v0.84-503-g423c35a) with (AES256-GCM-SHA384 encrypted) ESMTPS; Thu, 23 Jul 2015 23:26:01 +0000 Received: from int-mx14.intmail.prod.int.phx2.redhat.com (int-mx14.intmail.prod.int.phx2.redhat.com [10.5.11.27]) by mx1.redhat.com (Postfix) with ESMTPS id 716C0A8D; Thu, 23 Jul 2015 23:26:00 +0000 (UTC) Received: from [127.0.0.1] (ovpn01.gateway.prod.ext.ams2.redhat.com [10.39.146.11]) by int-mx14.intmail.prod.int.phx2.redhat.com (8.14.4/8.14.4) with ESMTP id t6NNPwpC021804; Thu, 23 Jul 2015 19:25:59 -0400 Message-ID: <55B17806.2060000@redhat.com> Date: Thu, 23 Jul 2015 23:26:00 -0000 From: Pedro Alves User-Agent: Mozilla/5.0 (X11; Linux x86_64; rv:31.0) Gecko/20100101 Thunderbird/31.5.0 MIME-Version: 1.0 To: Yao Qi , gdb-patches@sourceware.org Subject: Re: [PATCH 7/8] Initialise target descrption after skipping extra traps for --wrapper References: <1437392126-29503-1-git-send-email-yao.qi@linaro.org> <1437392126-29503-8-git-send-email-yao.qi@linaro.org> In-Reply-To: <1437392126-29503-8-git-send-email-yao.qi@linaro.org> Content-Type: text/plain; charset=windows-1252 Content-Transfer-Encoding: 7bit X-SW-Source: 2015-07/txt/msg00673.txt.bz2 On 07/20/2015 12:35 PM, Yao Qi wrote: > Nowadays, when --wrapper is used, GDBserver skips extra traps/stops > in the wrapper program, and stops at the first instruction of the > program to be debugged. However, GDBserver created target description > in the first stop of inferior, and the executable of the inferior > is the wrapper program rather than the program to be debugged. In > this way, the target description can be wrong if the architectures > of wrapper program and program to be debugged are different. This > is shown by some fails in gdb.server/wrapper.exp on buildbot. > > We are testing i686-linux GDB (Fedora-i686) on an x86_64-linux box > (fedora-x86-64-4) in buildbot, such configuration causes fails in > gdb.server/wrapper.exp like this: > > spawn /home/gdb-buildbot-2/fedora-x86-64-4/fedora-i686/build/gdb/testsuite/../../gdb/gdbserver/gdbserver --once --wrapper env TEST=1 -- :2346 /home/gdb-buildbot-2/fedora-x86-64-4/fedora-i686/build/gdb/testsuite/outputs/gdb.server/wrapper/wrapper > Process /home/gdb-buildbot-2/fedora-x86-64-4/fedora-i686/build/gdb/testsuite/outputs/gdb.server/wrapper/wrapper created; pid = 8795 > Can't debug 64-bit process with 32-bit GDBserver > Exiting > target remote localhost:2346 > localhost:2346: Connection timed out. > (gdb) FAIL: gdb.server/wrapper.exp: setting breakpoint at marker > > See https://sourceware.org/ml/gdb-testers/2015-q3/msg01541.html > > In this case, program to be debugged ("wrapper") is 32-bit but wrapper > program ("/usr/bin/env") is 64-bit, so GDBserver gets the 64-bit > target description instead of 32-bit. > > The root cause of this problem is that GDBserver creates target > description too early, and the rationale of fix could be creating > target description once the GDBserver skips extra traps and inferior > stops at the first instruction of the program we want to debug. IOW, > when GDBserver skips extra traps, the inferior's tdesc is NULL, and > mywait and its callees shouldn't use inferior's tdesc, so in this > patch, we do the shortcut if proc->tdesc == NULL, see changes in > linux_resume_one_lwp_throw and need_step_over_p. > > In linux_low_filter_event, if target description isn't initialised and > GDBserver attached the process, we create target description immediately, > because GDBserver don't have to skip extra traps for attach, IOW, it > makes no sense to use --attach and --wrapper together. Otherwise, the > process is launched by GDBserver, we keep the status pending, and return. > > After GDBserver skipped extra traps in start_inferior, we call a > target_ops hook arch_setup to initialise target description there. > Great, thanks for doing this. Looks generally good to me. One comment below. > @@ -3651,6 +3671,31 @@ linux_resume_one_lwp_throw (struct lwp_info *lwp, > struct thread_info *thread = get_lwp_thread (lwp); > struct thread_info *saved_thread; > int fast_tp_collecting; > + struct process_info *proc = get_thread_process (thread); > + > + if (proc->tdesc == NULL) > + { > + /* Target description isn't initialised because the program hasn't > + stop at the first instruction. It means GDBserver skips the "hasn't stopped" ... "first instruction yet". > + extra traps from the wrapper program (see option --wrapper), > + and GDBserver just simply resumes the program without accessing > + inferior registers, because target description is unavailable > + at this point. */ > + errno = 0; > + lwp->stepping = step; > + ptrace (step ? PTRACE_SINGLESTEP : PTRACE_CONT, lwpid_of (thread), > + (PTRACE_TYPE_ARG3) 0, > + /* Coerce to a uintptr_t first to avoid potential gcc warning > + of coercing an 8 byte integer to a 4 byte pointer. */ > + (PTRACE_TYPE_ARG4) (uintptr_t) signal); > + > + if (errno) > + perror_with_name ("resuming thread"); > + > + lwp->stopped = 0; > + lwp->stop_reason = TARGET_STOPPED_BY_NO_REASON; > + return; Instead of this whole code block, I think we should be able to skip the bits in the function that require accessing registers. E.g., this: /* Cancel actions that rely on GDB not changing the PC (e.g., the user used the "jump" command, or "set $pc = foo"). */ if (lwp->stop_pc != get_pc (lwp)) { /* Collecting 'while-stepping' actions doesn't make sense anymore. */ release_while_stepping_state_list (thread); } Could be guarded by: if (thread->while_stepping != NULL) And this: if (the_low_target.get_pc != NULL) { struct regcache *regcache = get_thread_regcache (current_thread, 1); lwp->stop_pc = (*the_low_target.get_pc) (regcache); if (debug_threads) { debug_printf (" %s from pc 0x%lx\n", step ? "step" : "continue", (long) lwp->stop_pc); } } could be guarded by: if (proc->tdesc == NULL) Did you try that? > + } > > if (lwp->stopped == 0) > return; Thanks, Pedro Alves