From patchwork Wed Dec 16 21:47:44 2015 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Brian Vandenberg X-Patchwork-Id: 10040 Received: (qmail 98852 invoked by alias); 16 Dec 2015 21:47:50 -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 98840 invoked by uid 89); 16 Dec 2015 21:47:50 -0000 Authentication-Results: sourceware.org; auth=none X-Virus-Found: No X-Spam-SWARE-Status: No, score=-2.6 required=5.0 tests=BAYES_00, FREEMAIL_FROM, RCVD_IN_DNSWL_LOW, SPF_PASS autolearn=ham version=3.3.2 spammy=exe, 1947, Changelog, typos X-HELO: mail-qk0-f176.google.com Received: from mail-qk0-f176.google.com (HELO mail-qk0-f176.google.com) (209.85.220.176) by sourceware.org (qpsmtpd/0.93/v0.84-503-g423c35a) with (AES128-GCM-SHA256 encrypted) ESMTPS; Wed, 16 Dec 2015 21:47:47 +0000 Received: by mail-qk0-f176.google.com with SMTP id k189so87540811qkc.0 for ; Wed, 16 Dec 2015 13:47:46 -0800 (PST) MIME-Version: 1.0 X-Received: by 10.129.153.135 with SMTP id q129mr29580651ywg.15.1450302464509; Wed, 16 Dec 2015 13:47:44 -0800 (PST) Received: by 10.37.118.88 with HTTP; Wed, 16 Dec 2015 13:47:44 -0800 (PST) Date: Wed, 16 Dec 2015 14:47:44 -0700 Message-ID: Subject: [PATCH][PR gdb/17903] Implement to_pid_to_exec_file for solaris From: Brian Vandenberg To: gdb-patches@sourceware.org This patch is to address an issue in Solaris, bug 17903. When attaching to a process by PID the current implementation in gdb/procfs.c leaves "to_pid_to_exec_file" at the default -- a stub function that returns NULL. This causes symbols not to load when attaching, forcing the user to either attach by specifying the path on the command line or inside gdb. After specifying the file inside gdb it's also necessary to manually load symbolic information. The proposed change resembles the implementation in gdb/linux-nat.c, but is generic enough that it could work on most platforms supporting procfs and could potentially be used as a replacement for the current default. If you only care about fixing this in Solaris 10+, the loop could be done away with and readlink could just read from "/proc/self/path/a.out", allowing you to get rid of the xsnprintf call as well. I don't have DejaGNU installed on my development machines at work and I don't have one [that functions] at home, so I was unable to run the test suite (otherwise I would have). Lastly: I made these changes on a machine that doesn't have network access. I had to hand-type the following diff. My apologies if there are typos; I did my best. Obviously I won't be able to push this myself. gdb/Changelog: 2015-12-16 Brian Vandenberg PR gdb/17903 * gdb/procfs.c (inclusions): Included ansidecl.h for UNUSED_ARG (procfs_target): added procfs_child_pid_to_exec_file to target_ops struct (procfs_child_pid_to_exec_file): to_pid_to_exec_file implementation for solaris diff --git a/gdb/procfs.c b/gdb/procfs.c index 7b7ff45..a663223 100644 --- a/gdb/procfs.c +++ b/gdb/procfs.c @@ -51,6 +51,7 @@ #include "auxv.h" #include "procfs.h" #include "observer.h" +#include "ansidecl.h" /* This module provides the interface between GDB and the /proc file system, which is used on many versions of Unix @@ -118,6 +119,7 @@ static void procfs_fetch_registers (struct target_ops *, struct regcache *, int); static void procfs_store_registers (struct target_ops *, struct regcache *, int); +static char* procfs_child_pid_to_exec_file( struct target_ops*, int ); static void procfs_pass_signals (struct target_ops *self, int, unsigned char *); static void procfs_kill_inferior (struct target_ops *ops); @@ -192,6 +194,7 @@procfs_target (void) t->to_resume = procfs_resume; t->to_fetch_registers = procfs_fetch_registers; t->to_store_registers = procfs_store_registers; + t->to_pid_to_exec_file = procfs_child_pid_to_exec_file; t->to_xfer_partial = procfs_xfer_partial; t->to_pass_signals = procfs_pass_signals; t->to_files_info = procfs_files_info; @@ -3301,6 +3304,41 @@ procfs_store_registers (struct target_ops *ops, } } +/* "self" may not exist on some platforms, + * otherwise that would be preferable to + * a format string. */ +static const char *proc_path_lookup[] = { + "/proc/%u/path/a.out" // Most UNIXes with procfs (Solaris) +, "/proc/%u/file" // BSD +, "/proc/%u/exe" // Linux, Windows, NetBSD +, "/proc/%u/a.out" // No idea, I've only seen references to it +}; + +/* Get a fully qualified path to the debugged process */ +static char* procfs_child_pid_to_exec_file( struct target_ops *ARG_UNUSED(self), int pid ) { + static char buf[PATH_MAX] = {0}; + char name[PATH_MAX] = {0}; + ssize_t sz = -1; + size_t ii = 0; + + pid = pid >= 0 ? pid : -pid; + + for( ii = 0; ii < sizeof(proc_path_lookup)/sizeof(proc_path_lookup[0]); ++ii ) { + xsnprintf( name, sizeof(name), proc_path_lookup[ii], (unsigned int)pid ); + sz = readlink( name, buf, sizeof( name ) ); + + if( 0 < sz ) { + buf[sz] = '\0'; + return buf; + } + } + + /* This is the default behavior as defined in target.h + * and implemented in inf_child_pid_to_exec_file() */ + return NULL; +} +