From patchwork Wed Aug 23 21:56:53 2017 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: jon@ringle.org X-Patchwork-Id: 22339 Received: (qmail 31720 invoked by alias); 23 Aug 2017 21:56:57 -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 31249 invoked by uid 89); 23 Aug 2017 21:56:56 -0000 Authentication-Results: sourceware.org; auth=none X-Virus-Found: No X-Spam-SWARE-Status: No, score=-26.4 required=5.0 tests=BAYES_00, FREEMAIL_FROM, GIT_PATCH_0, GIT_PATCH_1, GIT_PATCH_2, GIT_PATCH_3, RCVD_IN_DNSWL_NONE, RCVD_IN_SORBS_SPAM, SPF_PASS autolearn=ham version=3.3.2 spammy=7183, 7158 X-HELO: mail-qt0-f193.google.com Received: from mail-qt0-f193.google.com (HELO mail-qt0-f193.google.com) (209.85.216.193) by sourceware.org (qpsmtpd/0.93/v0.84-503-g423c35a) with ESMTP; Wed, 23 Aug 2017 21:56:54 +0000 Received: by mail-qt0-f193.google.com with SMTP id f63so763576qtb.1 for ; Wed, 23 Aug 2017 14:56:54 -0700 (PDT) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:sender:from:to:cc:subject:date:message-id; bh=KRlPkQ4N5/GqfqGfDaWr4MpwjXr5Sf9xDSbJpKJXtlc=; b=TY3TNXMlQZ2dhjQL0wueI2cnNB53FX+68gJhmPloud44ySP3m6vnVWArNkE3Y562w0 9AIaL7XUYfCBAkCOJBvBBnJeKKt567hLhlZCZdDaopOUpy3VyBovC5xg6t+kjbuohBCh YTM+KHFeIm3e7dE3fUSVx3ANhJ4asVMmegcX+PmZAXy66pSuWYB45+xofgjYzKT2knMI +JMYwuJ7tLmZuFu+5KuSYgRaMSEN6sQlww9YEMRhYkbcIA/vrkfk2oLz/hXhH1khPulp Vv0/nLm6ZD0ucRnFtAoh5twpBOckXoi8E/IEipVmzNDMh/WObS8ub9WdhdFaIHbO6/9x rS1g== X-Gm-Message-State: AHYfb5jZO5Hf7uZTtZbaKM4RBsFF6JZSVhjoVO+bXh68+/nsWg8HPBKB 02Lx80lVgfj+nAJcX40= X-Received: by 10.200.37.110 with SMTP id 43mr5966456qtn.10.1503525412679; Wed, 23 Aug 2017 14:56:52 -0700 (PDT) Received: from jring-w510-7m3g.gridpoint.com (c-75-75-44-91.hsd1.va.comcast.net. [75.75.44.91]) by smtp.gmail.com with ESMTPSA id 13sm1493699qkd.70.2017.08.23.14.56.51 (version=TLS1_2 cipher=ECDHE-RSA-AES128-SHA bits=128/128); Wed, 23 Aug 2017 14:56:52 -0700 (PDT) From: jon@ringle.org To: gdb-patches@sourceware.org Cc: Jon Ringle Subject: [PATCH] gdbserver: linux_low: elf_64_file_p cache results Date: Wed, 23 Aug 2017 17:56:53 -0400 Message-Id: <1503525413-14843-1-git-send-email-jon@ringle.org> From: Jon Ringle I was debugging a systemd service that would drop root privileges, and found that I was unable to debug it properly because gdb could not resolve any symbols. The gdbserver on my arm target would report: gdbserver: Corrupted shared library list: 0x0 != 0xe2822038 Prior to getting the above message, symbols could be resolved successfully. I finally determined that the problem was that in linux_low.c in function linux_qxfer_libraries_svr4() the is_elf64 variable was causing the wrong lmo and ptr_size to get used. Here's that code snippet: 7136 static int 7137 linux_qxfer_libraries_svr4 (const char *annex, unsigned char *readbuf, 7138 unsigned const char *writebuf, 7139 CORE_ADDR offset, int len) 7140 { 7141 char *document; 7142 unsigned document_len; 7143 struct process_info_private *const priv = current_process ()->priv; 7144 char filename[PATH_MAX]; 7145 int pid, is_elf64; 7146 7147 static const struct link_map_offsets lmo_32bit_offsets = 7148 { 7149 0, /* r_version offset. */ 7150 4, /* r_debug.r_map offset. */ 7151 0, /* l_addr offset in link_map. */ 7152 4, /* l_name offset in link_map. */ 7153 8, /* l_ld offset in link_map. */ 7154 12, /* l_next offset in link_map. */ 7155 16 /* l_prev offset in link_map. */ 7156 }; 7157 7158 static const struct link_map_offsets lmo_64bit_offsets = 7159 { 7160 0, /* r_version offset. */ 7161 8, /* r_debug.r_map offset. */ 7162 0, /* l_addr offset in link_map. */ 7163 8, /* l_name offset in link_map. */ 7164 16, /* l_ld offset in link_map. */ 7165 24, /* l_next offset in link_map. */ 7166 32 /* l_prev offset in link_map. */ 7167 }; 7168 const struct link_map_offsets *lmo; 7169 unsigned int machine; 7170 int ptr_size; 7171 CORE_ADDR lm_addr = 0, lm_prev = 0; 7172 int allocated = 1024; 7173 char *p; 7174 CORE_ADDR l_name, l_addr, l_ld, l_next, l_prev; 7175 int header_done = 0; 7176 7177 if (writebuf != NULL) 7178 return -2; 7179 if (readbuf == NULL) 7180 return -1; 7181 7182 pid = lwpid_of (current_thread); 7183 xsnprintf (filename, sizeof filename, "/proc/%d/exe", pid); 7184 is_elf64 = elf_64_file_p (filename, &machine); 7185 lmo = is_elf64 ? &lmo_64bit_offsets : &lmo_32bit_offsets; 7186 ptr_size = is_elf64 ? 8 : 4; The problem lied in the fact that the function elf_64_file_p() was returning -1 because it could not open the file (with errno set to EACCESS) This was because the inferior's code was dropping root privileges and no longer was able to read the file. This patch implements a cache per file in the elf_64_file_p() function so that it remembers the results of a previous query for the same filename. Since it seems that c++ is now accepted, it was implemented using std::map Signed-off-by: Jon Ringle --- gdb/gdbserver/linux-low.c | 24 ++++++++++++++++++------ 1 file changed, 18 insertions(+), 6 deletions(-) diff --git a/gdb/gdbserver/linux-low.c b/gdb/gdbserver/linux-low.c index e27cbf825a5b..0b1c7e089227 100644 --- a/gdb/gdbserver/linux-low.c +++ b/gdb/gdbserver/linux-low.c @@ -47,6 +47,8 @@ #include "tracepoint.h" #include "hostio.h" #include +#include + #ifndef ELFMAG0 /* Don't include here. If it got included by gdb_proc_service.h then ELFMAG0 will have been defined. If it didn't get included by @@ -370,24 +372,34 @@ elf_64_header_p (const Elf64_Ehdr *header, unsigned int *machine) zero if the file is not a 64-bit ELF file, and -1 if the file is not accessible or doesn't exist. */ +static std::map> is_elf64_cache; + static int elf_64_file_p (const char *file, unsigned int *machine) { Elf64_Ehdr header; int fd; + int is_elf64 = 0; + + auto iter = is_elf64_cache.find(file); + if (iter != is_elf64_cache.end()) + { + *machine = iter->second.second; + return iter->second.first; + } fd = open (file, O_RDONLY); if (fd < 0) return -1; - if (read (fd, &header, sizeof (header)) != sizeof (header)) - { - close (fd); - return 0; - } + if (read (fd, &header, sizeof (header)) == sizeof (header)) + is_elf64 = elf_64_header_p (&header, machine); + close (fd); - return elf_64_header_p (&header, machine); + is_elf64_cache.emplace(file, std::make_pair(is_elf64, *machine)); + + return is_elf64; } /* Accepts an integer PID; Returns true if the executable PID is