From patchwork Tue Nov 5 01:59:03 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Aaron Merey X-Patchwork-Id: 35637 Received: (qmail 80348 invoked by alias); 5 Nov 2019 01:59:18 -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 80295 invoked by uid 89); 5 Nov 2019 01:59:18 -0000 Authentication-Results: sourceware.org; auth=none X-Spam-SWARE-Status: No, score=-16.4 required=5.0 tests=AWL, BAYES_00, GIT_PATCH_0, GIT_PATCH_1, GIT_PATCH_2, GIT_PATCH_3, SPF_HELO_PASS autolearn=ham version=3.3.1 spammy=xfree, auxvh, UD:auxv.h, auxv.h 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 ESMTP; Tue, 05 Nov 2019 01:59:16 +0000 Received: from mail-vk1-f198.google.com (mail-vk1-f198.google.com [209.85.221.198]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by mx1.redhat.com (Postfix) with ESMTPS id 982E859449 for ; Tue, 5 Nov 2019 01:59:15 +0000 (UTC) Received: by mail-vk1-f198.google.com with SMTP id k127so8714679vka.10 for ; Mon, 04 Nov 2019 17:59:15 -0800 (PST) MIME-Version: 1.0 References: <20190820202809.25367-1-amerey@redhat.com> <87pnj6dl3k.fsf@tromey.com> <87sgn71ji6.fsf@tromey.com> <87lfsye5l5.fsf@redhat.com> <87bltrelab.fsf@redhat.com> <20191104162616.GA13319@redhat.com> In-Reply-To: <20191104162616.GA13319@redhat.com> From: Aaron Merey Date: Mon, 4 Nov 2019 20:59:03 -0500 Message-ID: Subject: Re: [RFC PATCH] Support debuginfo and source file fetching via debuginfo server To: "Frank Ch. Eigler" Cc: Simon Marchi , Tom Tromey , Christian Biesinger via gdb-patches , Christian Biesinger On Mon, Nov 4, 2019 at 11:26 AM Frank Ch. Eigler wrote: > > Hi - > > > I haven't followed this thread closely, so it might be an obvious "no", but > > I was wondering if the library could offer to install a callback that is call > > relatively often, allowing GDB to interrupt the operation [...] > > That could also work, at the cost of extending the API. Will play with it. > > - FChE Attached is the updated debuginfo and source lookup code, using the callback idea that Simon suggested. Downloads are now cancelled upon SIGINT and the callback can be modified with code that prints progress messages (the a and b parameters in the callback represent the numerator and denominator of the download's completion fraction). gdb/elfread.c | 36 +++++++++++++++++++++++++++++++++++- gdb/source.c | 47 +++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 82 insertions(+), 1 deletion(-) diff --git a/gdb/elfread.c b/gdb/elfread.c index 226e3f09d3..e24bca610f 100644 --- a/gdb/elfread.c +++ b/gdb/elfread.c @@ -48,7 +48,11 @@ #include "auxv.h" #include "mdebugread.h" #include "ctfread.h" +#include "gdbsupport/scoped_fd.h" #include "gdbsupport/gdb_string_view.h" +#if HAVE_LIBDEBUGINFOD +#include +#endif /* Forward declarations. */ extern const struct sym_fns elf_sym_fns_gdb_index; @@ -1311,8 +1315,38 @@ elf_symfile_read (struct objfile *objfile, symfile_add_flags symfile_flags) symbol_file_add_separate (debug_bfd.get (), debugfile.c_str (), symfile_flags, objfile); } - else + else + { has_dwarf2 = false; + +#if HAVE_LIBDEBUGINFOD + const struct bfd_build_id *build_id; + char *symfile_path; + + build_id = build_id_bfd_get (objfile->obfd); + + /* Allow debuginfod to abort the download if SIGINT is raised. */ + debuginfod_set_progressfn ( + [] (long a, long b) { return 1 ? check_quit_flag () : 0; } + ); + + /* Query debuginfod servers for symfile. */ + scoped_fd fd (debuginfod_find_debuginfo (build_id->data, + build_id->size, + &symfile_path)); + + if (fd.get () >= 0) + { + /* file successfully retrieved from server. */ + gdb_bfd_ref_ptr debug_bfd (symfile_bfd_open (symfile_path)); + + symbol_file_add_separate (debug_bfd.get (), symfile_path, + symfile_flags, objfile); + xfree (symfile_path); + has_dwarf2 = true; + } +#endif /* LIBDEBUGINFOD */ + } } /* Read the CTF section only if there is no DWARF info. */ diff --git a/gdb/source.c b/gdb/source.c index 9f53d654f3..4e8a6558b7 100644 --- a/gdb/source.c +++ b/gdb/source.c @@ -30,6 +30,10 @@ #include #include +#include "build-id.h" +#ifdef HAVE_LIBDEBUGINFOD +#include +#endif #include "gdbcore.h" #include "gdb_regex.h" #include "symfile.h" @@ -1127,6 +1131,49 @@ open_source_file (struct symtab *s) s->fullname = NULL; scoped_fd fd = find_and_open_source (s->filename, SYMTAB_DIRNAME (s), &fullname); + +#if HAVE_LIBDEBUGINFOD + if (fd.get () < 0 && SYMTAB_COMPUNIT (s) != NULL) + { + const struct bfd_build_id *build_id; + const objfile *ofp = COMPUNIT_OBJFILE (SYMTAB_COMPUNIT (s)); + + std::string srcpath; + if (IS_DIR_SEPARATOR (s->filename[0])) + srcpath = s->filename; + else + { + srcpath = SYMTAB_DIRNAME (s); + srcpath += SLASH_STRING; + srcpath += s->filename; + } + + build_id = build_id_bfd_get (ofp->obfd); + + /* Query debuginfod for the source file. */ + if (build_id != NULL) + { + char *name_in_cache; + + /* Allow debuginfod to abort the download if SIGINT is raised. */ + debuginfod_set_progressfn ( + [] (long a, long b) { return 1 ? check_quit_flag () : 0; } + ); + + scoped_fd src_fd (debuginfod_find_source (build_id->data, + build_id->size, + srcpath.c_str (), + &name_in_cache)); + + if (src_fd.get () >= 0) + fullname.reset (name_in_cache); + + s->fullname = fullname.release (); + return src_fd; + } + } +#endif /* HAVE_LIBDEBUGINFOD */ + s->fullname = fullname.release (); return fd; }