From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (qmail 31884 invoked by alias); 13 Nov 2008 21:35:46 -0000 Received: (qmail 31575 invoked by uid 22791); 13 Nov 2008 21:35:39 -0000 X-Spam-Check-By: sourceware.org Received: from smtp-outbound-2.vmware.com (HELO smtp-outbound-2.vmware.com) (65.115.85.73) by sourceware.org (qpsmtpd/0.31) with ESMTP; Thu, 13 Nov 2008 21:35:02 +0000 Received: from mailhost3.vmware.com (mailhost3.vmware.com [10.16.27.45]) by smtp-outbound-2.vmware.com (Postfix) with ESMTP id 56D0026005; Thu, 13 Nov 2008 13:35:00 -0800 (PST) Received: from [10.20.92.59] (promb-2s-dhcp59.eng.vmware.com [10.20.92.59]) by mailhost3.vmware.com (Postfix) with ESMTP id 479E4C9A8D; Thu, 13 Nov 2008 13:35:00 -0800 (PST) Message-ID: <491C9D75.7010701@vmware.com> Date: Fri, 14 Nov 2008 00:54:00 -0000 From: Michael Snyder User-Agent: Thunderbird 1.5.0.12 (X11/20080411) MIME-Version: 1.0 To: "tromey@redhat.com" CC: "gdb-patches@sourceware.org" Subject: Re: RFA: attach to a PID using a different exec References: In-Reply-To: Content-Type: text/plain; charset=ISO-8859-1; format=flowed Content-Transfer-Encoding: 7bit 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: 2008-11/txt/msg00303.txt.bz2 No way should we do this without asking. It's just as possible that the first file was the one the user wanted, and the one attached to was a mistake. Tom Tromey wrote: > Sometimes I will start gdb like "gdb /some/path/to/gdb" and then > "attach PID" -- where PID is actually running "/some/other/gdb". > That is, the current exec file and the attached process disagree. > > Right now this usually yields an error along the lines of: > "Cannot access memory at address 0x2e". > > This patch changes gdb to look at the target's notion of the exec > file, and then switch to it if it differs from the current exec. > > I looked a little and didn't see an existing "are these two files 'the > same'" predicate in gdb, so I just compare the real paths. > > Built and regtested on x86-64 (compile farm). > New test included -- it fails before the patch and passes after it. > > Please review. > > thanks, > Tom > > 2008-11-13 Tom Tromey > > * infcmd.c (attach_command_post_wait): Compare current exec file > with target's exec file. > > 2008-11-13 Tom Tromey > > * gdb.base/attach.exp (do_attach_tests): Test attaching to a PID > using a different exec file. > > diff --git a/gdb/infcmd.c b/gdb/infcmd.c > index b3af31f..2efdd14 100644 > --- a/gdb/infcmd.c > +++ b/gdb/infcmd.c > @@ -2114,37 +2114,63 @@ proceed_after_attach (int pid) > static void > attach_command_post_wait (char *args, int from_tty, int async_exec) > { > - char *exec_file; > - char *full_exec_path = NULL; > + char *exec_file, *targ_exec_file; > + char *full_targ_exec_path = NULL; > struct inferior *inferior; > + int must_attach; > > inferior = current_inferior (); > inferior->stop_soon = NO_STOP_QUIETLY; > > - /* If no exec file is yet known, try to determine it from the > - process itself. */ > + /* Figure out what to do about the exec. There are four cases to > + consider -- we may or may not have a current exec file, and the > + target may or may not be able to determine the exec file of the > + attached process. */ > exec_file = (char *) get_exec_file (0); > - if (!exec_file) > + > + /* Get the target's notion of the current exec. */ > + targ_exec_file = target_pid_to_exec_file (PIDGET (inferior_ptid)); > + if (targ_exec_file) > { > - exec_file = target_pid_to_exec_file (PIDGET (inferior_ptid)); > - if (exec_file) > + /* It's possible we don't have a full path, but rather just a > + filename. Some targets, such as HP-UX, don't provide the > + full path, sigh. > + > + Attempt to qualify the filename against the source path. > + (If that fails, we'll just fall back on the original > + filename. Not much more we can do...) > + */ > + if (!source_full_path_of (targ_exec_file, &full_targ_exec_path)) > + full_targ_exec_path = xstrdup (targ_exec_file); > + } > + > + must_attach = 0; > + /* If the target knows the exec, check to see if it matches our > + current exec. */ > + if (full_targ_exec_path) > + { > + /* If we don't have a current exec, just go with what the target > + reported. */ > + if (!exec_file) > + must_attach = 1; > + else > { > - /* It's possible we don't have a full path, but rather just a > - filename. Some targets, such as HP-UX, don't provide the > - full path, sigh. > - > - Attempt to qualify the filename against the source path. > - (If that fails, we'll just fall back on the original > - filename. Not much more we can do...) > - */ > - if (!source_full_path_of (exec_file, &full_exec_path)) > - full_exec_path = savestring (exec_file, strlen (exec_file)); > - > - exec_file_attach (full_exec_path, from_tty); > - symbol_file_add_main (full_exec_path, from_tty); > + char *real_path = gdb_realpath (exec_file); > + char *targ_real_path = gdb_realpath (full_targ_exec_path); > + must_attach = strcmp (real_path, targ_real_path) != 0; > + if (!must_attach) > + xfree (full_targ_exec_path); > + xfree (real_path); > + xfree (targ_real_path); > } > } > - else > + > + if (must_attach) > + { > + exec_file_attach (full_targ_exec_path, from_tty); > + symbol_file_add_main (full_targ_exec_path, from_tty); > + } > + else if (exec_file) > { > reopen_exec_file (); > reread_symbols (); > @@ -2163,7 +2189,7 @@ attach_command_post_wait (char *args, int from_tty, int async_exec) > /* The user requested an `attach&', so be sure to leave threads > that didn't get a signal running. */ > > - /* Immediatelly resume all suspended threads of this inferior, > + /* Immediately resume all suspended threads of this inferior, > and this inferior only. This should have no effect on > already running threads. If a thread has been stopped with a > signal, leave it be. */ > diff --git a/gdb/testsuite/gdb.base/attach.exp b/gdb/testsuite/gdb.base/attach.exp > index 4529715..fd59c0f 100644 > --- a/gdb/testsuite/gdb.base/attach.exp > +++ b/gdb/testsuite/gdb.base/attach.exp > @@ -48,6 +48,7 @@ set srcfile2 ${testfile}2.c > set binfile ${objdir}/${subdir}/${testfile} > set binfile2 ${objdir}/${subdir}/${testfile}2 > set escapedbinfile [string_to_regexp ${objdir}/${subdir}/${testfile}] > +set escapedbinfile2 [string_to_regexp ${objdir}/${subdir}/${testfile}2] > > #execute_anywhere "rm -f ${binfile} ${binfile2}" > remote_exec build "rm -f ${binfile} ${binfile2}" > @@ -75,8 +76,8 @@ if [get_compiler_info ${binfile}] { > > proc do_attach_tests {} { > global gdb_prompt > - global binfile > - global escapedbinfile > + global binfile binfile2 > + global escapedbinfile escapedbinfile2 > global srcfile > global testfile > global objdir > @@ -313,7 +314,53 @@ proc do_attach_tests {} { > "Attaching to process $testpid.*Reading symbols from $escapedbinfile.*main.*at .*" \ > "attach when process' a.out not in cwd" > > - set test "after attach3, exit" > + # Detach the process. > + > + gdb_test "detach" \ > + "Detaching from program: .*$escapedbinfile, process $testpid" \ > + "before attach4, detach" > + > + # Wait a bit for gdb to finish detaching > + > + exec sleep 5 > + > + # Use symbols from one file, then attach to a process executing > + # from another file. > + gdb_test "file $binfile2" \ > + "Reading symbols from $escapedbinfile2\.\.\.*done." \ > + "attach4, select binfile2" \ > + "Load new symbol table from .*? .y or n. " \ > + "y" > + > + set test "attach to PID using different exec" > + send_gdb "attach $testpid\n" > + gdb_expect { > + -re "Attaching to program.*, process $testpid.*Load new symbol table from \"$escapedbinfile\".*y or n. $" { > + send_gdb "y\n" > + gdb_expect { > + -re "main.*at.*$srcfile:.*$gdb_prompt $" { > + pass "$test" > + } > + -re "$gdb_prompt $" { > + fail "$test" > + } > + timeout { > + fail "$test (timeout)" > + } > + } > + } > + -re "Attaching to program.*, process $testpid.*Cannot access memory at .*$" { > + fail "$test" > + } > + -re "Attaching to program.*, process $testpid.*$gdb_prompt $" { > + fail "$test" > + } > + timeout { > + fail "$test (timeout)" > + } > + } > + > + set test "after attach4, exit" > gdb_test_multiple "kill" "$test" { > -re "Kill the program being debugged.*y or n. $" { > gdb_test "y" "" "$test"