mirror of
https://github.com/espressif/binutils-gdb.git
synced 2025-06-18 16:53:50 +08:00
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
This commit is contained in:
@ -33,8 +33,9 @@
|
|||||||
source file path is `/my/source/foo.c`, then SRC_PATH should be
|
source file path is `/my/source/foo.c`, then SRC_PATH should be
|
||||||
`/my/build/../source/foo.c`.
|
`/my/build/../source/foo.c`.
|
||||||
|
|
||||||
If the file is successfully retrieved, its path on the local machine
|
If the file is successfully retrieved, return a file descriptor and store
|
||||||
is stored in DESTNAME. If GDB is not built with debuginfod, this
|
the file's local path in DESTNAME. If unsuccessful, print an error message
|
||||||
|
and return a negative errno. If GDB is not built with debuginfod, this
|
||||||
function returns -ENOSYS. */
|
function returns -ENOSYS. */
|
||||||
|
|
||||||
extern scoped_fd
|
extern scoped_fd
|
||||||
@ -51,8 +52,9 @@ debuginfod_source_query (const unsigned char *build_id,
|
|||||||
FILENAME should be the name or path of the main binary associated with
|
FILENAME should be the name or path of the main binary associated with
|
||||||
the separate debug info. It is used for printing messages to the user.
|
the separate debug info. It is used for printing messages to the user.
|
||||||
|
|
||||||
If the file is successfully retrieved, its path on the local machine
|
If the file is successfully retrieved, return a file descriptor and store
|
||||||
is stored in DESTNAME. If GDB is not built with debuginfod, this
|
the file's local path in DESTNAME. If unsuccessful, print an error message
|
||||||
|
and return a negative errno. If GDB is not built with debuginfod, this
|
||||||
function returns -ENOSYS. */
|
function returns -ENOSYS. */
|
||||||
|
|
||||||
extern scoped_fd
|
extern scoped_fd
|
||||||
@ -69,8 +71,9 @@ debuginfod_debuginfo_query (const unsigned char *build_id,
|
|||||||
FILENAME should be the name or path associated with the executable.
|
FILENAME should be the name or path associated with the executable.
|
||||||
It is used for printing messages to the user.
|
It is used for printing messages to the user.
|
||||||
|
|
||||||
If the file is successfully retrieved, its path on the local machine
|
If the file is successfully retrieved, return a file descriptor and store
|
||||||
is stored in DESTNAME. If GDB is not built with debuginfod, this
|
the file's local path in DESTNAME. If unsuccessful, print an error message
|
||||||
|
and return a negative errno. If GDB is not built with debuginfod, this
|
||||||
function returns -ENOSYS. */
|
function returns -ENOSYS. */
|
||||||
|
|
||||||
extern scoped_fd debuginfod_exec_query (const unsigned char *build_id,
|
extern scoped_fd debuginfod_exec_query (const unsigned char *build_id,
|
||||||
|
@ -95,7 +95,7 @@ source_cache::get_plain_source_lines (struct symtab *s,
|
|||||||
{
|
{
|
||||||
scoped_fd desc (open_source_file (s));
|
scoped_fd desc (open_source_file (s));
|
||||||
if (desc.get () < 0)
|
if (desc.get () < 0)
|
||||||
perror_with_name (symtab_to_filename_for_display (s));
|
perror_with_name (symtab_to_filename_for_display (s), -desc.get ());
|
||||||
|
|
||||||
struct stat st;
|
struct stat st;
|
||||||
if (fstat (desc.get (), &st) < 0)
|
if (fstat (desc.get (), &st) < 0)
|
||||||
|
40
gdb/source.c
40
gdb/source.c
@ -1069,7 +1069,7 @@ find_and_open_source (const char *filename,
|
|||||||
the attempt to read this source file failed. GDB will then display
|
the attempt to read this source file failed. GDB will then display
|
||||||
the filename and line number instead. */
|
the filename and line number instead. */
|
||||||
if (!source_open)
|
if (!source_open)
|
||||||
return scoped_fd (-1);
|
return scoped_fd (-ECANCELED);
|
||||||
|
|
||||||
/* Quick way out if we already know its full name. */
|
/* Quick way out if we already know its full name. */
|
||||||
if (*fullname)
|
if (*fullname)
|
||||||
@ -1160,11 +1160,15 @@ find_and_open_source (const char *filename,
|
|||||||
OPEN_MODE, fullname);
|
OPEN_MODE, fullname);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* If the file wasn't found, then openp will have set errno accordingly. */
|
||||||
|
if (result < 0)
|
||||||
|
result = -errno;
|
||||||
|
|
||||||
return scoped_fd (result);
|
return scoped_fd (result);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Open a source file given a symtab S. Returns a file descriptor or
|
/* Open a source file given a symtab S. Returns a file descriptor or
|
||||||
negative number for error.
|
negative errno for error.
|
||||||
|
|
||||||
This function is a convenience function to find_and_open_source. */
|
This function is a convenience function to find_and_open_source. */
|
||||||
|
|
||||||
@ -1172,7 +1176,7 @@ scoped_fd
|
|||||||
open_source_file (struct symtab *s)
|
open_source_file (struct symtab *s)
|
||||||
{
|
{
|
||||||
if (!s)
|
if (!s)
|
||||||
return scoped_fd (-1);
|
return scoped_fd (-EINVAL);
|
||||||
|
|
||||||
gdb::unique_xmalloc_ptr<char> fullname (s->fullname);
|
gdb::unique_xmalloc_ptr<char> fullname (s->fullname);
|
||||||
s->fullname = NULL;
|
s->fullname = NULL;
|
||||||
@ -1200,10 +1204,21 @@ open_source_file (struct symtab *s)
|
|||||||
|
|
||||||
/* Query debuginfod for the source file. */
|
/* Query debuginfod for the source file. */
|
||||||
if (build_id != nullptr && !srcpath.empty ())
|
if (build_id != nullptr && !srcpath.empty ())
|
||||||
fd = debuginfod_source_query (build_id->data,
|
{
|
||||||
build_id->size,
|
scoped_fd query_fd
|
||||||
srcpath.c_str (),
|
= debuginfod_source_query (build_id->data,
|
||||||
&fullname);
|
build_id->size,
|
||||||
|
srcpath.c_str (),
|
||||||
|
&fullname);
|
||||||
|
|
||||||
|
/* Don't return a negative errno from debuginfod_source_query.
|
||||||
|
It handles the reporting of its own errors. */
|
||||||
|
if (query_fd.get () >= 0)
|
||||||
|
{
|
||||||
|
s->fullname = fullname.release ();
|
||||||
|
return query_fd;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1306,6 +1321,7 @@ print_source_lines_base (struct symtab *s, int line, int stopline,
|
|||||||
print_source_lines_flags flags)
|
print_source_lines_flags flags)
|
||||||
{
|
{
|
||||||
bool noprint = false;
|
bool noprint = false;
|
||||||
|
int errcode = ENOENT;
|
||||||
int nlines = stopline - line;
|
int nlines = stopline - line;
|
||||||
struct ui_out *uiout = current_uiout;
|
struct ui_out *uiout = current_uiout;
|
||||||
|
|
||||||
@ -1336,7 +1352,10 @@ print_source_lines_base (struct symtab *s, int line, int stopline,
|
|||||||
scoped_fd desc = open_source_file (s);
|
scoped_fd desc = open_source_file (s);
|
||||||
last_source_error = desc.get () < 0;
|
last_source_error = desc.get () < 0;
|
||||||
if (last_source_error)
|
if (last_source_error)
|
||||||
noprint = true;
|
{
|
||||||
|
noprint = true;
|
||||||
|
errcode = -desc.get ();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
@ -1354,7 +1373,7 @@ print_source_lines_base (struct symtab *s, int line, int stopline,
|
|||||||
char *name = (char *) alloca (len);
|
char *name = (char *) alloca (len);
|
||||||
|
|
||||||
xsnprintf (name, len, "%d\t%s", line, filename);
|
xsnprintf (name, len, "%d\t%s", line, filename);
|
||||||
print_sys_errmsg (name, errno);
|
print_sys_errmsg (name, errcode);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
@ -1627,7 +1646,8 @@ search_command_helper (const char *regex, int from_tty, bool forward)
|
|||||||
|
|
||||||
scoped_fd desc (open_source_file (loc->symtab ()));
|
scoped_fd desc (open_source_file (loc->symtab ()));
|
||||||
if (desc.get () < 0)
|
if (desc.get () < 0)
|
||||||
perror_with_name (symtab_to_filename_for_display (loc->symtab ()));
|
perror_with_name (symtab_to_filename_for_display (loc->symtab ()),
|
||||||
|
-desc.get ());
|
||||||
|
|
||||||
int line = (forward
|
int line = (forward
|
||||||
? last_line_listed + 1
|
? last_line_listed + 1
|
||||||
|
@ -67,7 +67,8 @@ extern void init_source_path (void);
|
|||||||
The caller is responsible for freeing FULLNAME.
|
The caller is responsible for freeing FULLNAME.
|
||||||
|
|
||||||
On Failure
|
On Failure
|
||||||
An invalid file descriptor is returned (the return value is negative).
|
An invalid file descriptor is returned. The value of this file
|
||||||
|
descriptor is a negative errno indicating the reason for the failure.
|
||||||
FULLNAME is set to NULL. */
|
FULLNAME is set to NULL. */
|
||||||
extern scoped_fd find_and_open_source (const char *filename,
|
extern scoped_fd find_and_open_source (const char *filename,
|
||||||
const char *dirname,
|
const char *dirname,
|
||||||
@ -81,7 +82,7 @@ extern gdb::unique_xmalloc_ptr<char> find_source_or_rewrite
|
|||||||
(const char *filename, const char *dirname);
|
(const char *filename, const char *dirname);
|
||||||
|
|
||||||
/* Open a source file given a symtab S. Returns a file descriptor or
|
/* Open a source file given a symtab S. Returns a file descriptor or
|
||||||
negative number for error. */
|
negative errno indicating the reason for the failure. */
|
||||||
extern scoped_fd open_source_file (struct symtab *s);
|
extern scoped_fd open_source_file (struct symtab *s);
|
||||||
|
|
||||||
extern gdb::unique_xmalloc_ptr<char> rewrite_source_path (const char *path);
|
extern gdb::unique_xmalloc_ptr<char> rewrite_source_path (const char *path);
|
||||||
|
Reference in New Issue
Block a user