Bug 29999 - Bogus error message printed when debuginfod doesn't find source file
Summary: Bogus error message printed when debuginfod doesn't find source file
Status: RESOLVED FIXED
Alias: None
Product: gdb
Classification: Unclassified
Component: gdb (show other bugs)
Version: HEAD
: P2 normal
Target Milestone: ---
Assignee: Not yet assigned to anyone
URL:
Keywords:
Depends on:
Blocks:
 
Reported: 2023-01-13 14:49 UTC by Simon Marchi
Modified: 2023-02-11 02:16 UTC (History)
1 user (show)

See Also:
Host:
Target:
Build:
Last reconfirmed:


Attachments
patch (355 bytes, patch)
2023-01-14 01:07 UTC, Aaron Merey
Details | Diff

Note You need to log in before you can comment on or make changes to this bug.
Description Simon Marchi 2023-01-13 14:49:09 UTC
Debugging on Arch Linux with DEBUGINFOD_URLS=https://debuginfod.archlinux.org, stopping into a glibc function for which debuginfod didn't find the source file (for whatever reason), GDB printed:

__libc_start_call_main (main=main@entry=0x555555555139 <main>, argc=argc@entry=1, argv=argv@entry=0x7fffffffd6f8) at ../sysdeps/nptl/libc_start_call_main.h:74
Downloading source file /usr/src/debug/glibc/csu/../sysdeps/nptl/libc_start_call_main.h
74      ../sysdeps/nptl/libc_start_call_main.h: Directory not empty.   

The next times (when the cache was populated, I suppose), I got:

__libc_start_call_main (main=main@entry=0x555555555139 <main>, argc=argc@entry=1, 
    argv=argv@entry=0x7fffffffd6f8) at ../sysdeps/nptl/libc_start_call_main.h:74
74      ../sysdeps/nptl/libc_start_call_main.h: Bad file descriptor.

I think this use of errno, in print_source_lines_base, is incorrect:

https://gitlab.com/gnutools/binutils-gdb/-/blob/6f9f448118eaeaf006f867a25699aef7d8c72770/gdb/source.c#L1357

The last thing we did before this was to call into debuginfod_find_source, which returned -2 (meaning ENOENT, which makes sense).  But the errno value after calling debuginfod_find_source is not defined, and I think this results in an error message that does not make sense.
Comment 1 Aaron Merey 2023-01-14 01:07:15 UTC
Created attachment 14592 [details]
patch

(In reply to Simon Marchi from comment #0)
> I think this use of errno, in print_source_lines_base, is incorrect:
> 
> https://gitlab.com/gnutools/binutils-gdb/-/blob/
> 6f9f448118eaeaf006f867a25699aef7d8c72770/gdb/source.c#L1357
> 
> The last thing we did before this was to call into debuginfod_find_source,
> which returned -2 (meaning ENOENT, which makes sense).  But the errno value
> after calling debuginfod_find_source is not defined, and I think this
> results in an error message that does not make sense.

It looks like errno gets set in find_and_open_source (in the case of ENOENT at least) before the call to debuginfod_find_source:

https://gitlab.com/gnutools/binutils-gdb/-/blob/6f9f448118eaeaf006f867a25699aef7d8c72770/gdb/source.c#L1179

However function calls within debuginfod_find_source may end up reassigning errno to a value unrelated to the status of the download, even if the download is successful. debuginfod_find_source returns a negative errno indicating the actual reason for a failed download. This is the errno that should be reported to the user, not one related to routine cache creation, for example.

We also don't want to hide an errno set in find_and_open_source. debuginfod errors are already reported in the debuginfod progress output, so I think we should save errno before calling debuginfod_find_source and revert errno to the saved value afterwards. This way both debuginfod errors and find_and_open_source errors are correctly reported to the user.

I've attached a patch for this.
Comment 2 Simon Marchi 2023-01-14 01:14:08 UTC
If possible, it would be nice to make internal GDB functions (like find_and_open_source) return error codes explicitly, instead of relying of errno.  I think that will make the code clearer than saving and restoring errno.
Comment 3 Sourceware Commits 2023-02-11 02:12:01 UTC
The master branch has been updated by Aaron Merey <amerey@sourceware.org>:

https://sourceware.org/git/gitweb.cgi?p=binutils-gdb.git;h=8cc96ee4169f631917d048cbaeec14ddf8ccb90d

commit 8cc96ee4169f631917d048cbaeec14ddf8ccb90d
Author: Aaron Merey <amerey@redhat.com>
Date:   Thu Feb 9 20:35:32 2023 -0500

    gdb/source: Fix open_source_file error handling
    
    open_source_file relies on errno to communicate the reason for a missing
    source file.
    
    open_source_file may also call debuginfod_find_source.  It is possible
    for debuginfod_find_source to set errno to a value unrelated to the
    reason for a failed download.
    
    This can result in bogus error messages being reported as the reason for
    a missing source file.  The following error message should instead be
    "No such file or directory":
    
      Temporary breakpoint 1, 0x00005555556f4de0 in main ()
      (gdb) list
      Downloading source file /usr/src/debug/glibc-2.36-8.fc37.x86_64/elf/<built-in>
      1       /usr/src/debug/glibc-2.36-8.fc37.x86_64/elf/<built-in>: Directory not empty.
    
    Fix this by having open_source_file return a negative errno if it fails
    to open a source file.  Use this value to generate the error message
    instead of errno.
    
    Approved-By: Tom Tromey <tom@tromey.com>
    Bug: https://sourceware.org/bugzilla/show_bug.cgi?id=29999
Comment 4 Aaron Merey 2023-02-11 02:16:10 UTC
Fixed in the above commit.