[rfc] Print MI fullname even for non-existing files

Jan Kratochvil
2012-12-17T15:59:31Z

Hi,

symtab_to_fullname now always returns non-NULL.

The goal is that currently with deleted /usr/src/debug one gets:

0x00007ffff637d7d0 in __poll_nocancel () at ../sysdeps/unix/syscall-template.S:81
81 ../sysdeps/unix/syscall-template.S: No such file or directory.

but I would like to get rather:

Program received signal SIGINT, Interrupt.
0x00007ffff637d7d0 in __poll_nocancel () at ../sysdeps/unix/syscall-template.S:81
81 /usr/src/debug/glibc-2.16-75f0d304/sysdeps/unix/syscall-template.S: No such file or directory.

But this patch does not do that part yet, it will be done by the new switch to
fully absolute filenames everywhere, as is being worked on top of this patch
as a rewrite of:
[patchv2] GDB 7.2: new feature for "backtrace" that cuts path to file (remain filename)
http://sourceware.org/ml/gdb-patches/2012-11/msg00957.html
and
set filename-display absolute

Currently this patch only changes from user point of view MI:
(gdb) -file-list-exec-source-file
^done,line="1",file="deleted.c",macro-info="0"
->
^done,line="1",file="deleted.c",fullname="/path/to/deleted.c",macro-info="0"

Is there a serious reason why fullname was suppressed for non-existing files?
While it breaks MI compatibility in some way I find it an acceptable change.

No regressions on {x86_64,x86_64-m32,i686}-fedora18-linux-gnu.

Thanks,
Jan

2012-12-17 Jan Kratochvil <jan.kratochvil@redhat.com>

* ada-lang.c (is_known_support_routine): New variable fullname. Use
access call to verify the symtab_to_fullname result.
* breakpoint.c (print_breakpoint_location, update_static_tracepoint):
Remove NULL check of symtab_to_fullname result.
* cli/cli-cmds.c (edit_command): Likewise.
* mi/mi-cmd-file.c (mi_cmd_file_list_exec_source_file)
(mi_cmd_file_list_exec_source_files): Likewise.
* python/py-symtab.c (stpy_fullname): Likewise.
* source.c (symtab_to_fullname): Update function comment. Rename
variable r to fd, move it to inner block. Always provide non-NULL
result.
(print_source_lines_base): Remove NULL check of symtab_to_fullname
result.
* stack.c (print_frame): Likewise.
* symtab.c (iterate_over_some_symtabs, find_line_symtab, sources_info):
Likewise.
* tracepoint.c (print_one_static_tracepoint_marker): Likewise.

gdb/doc/
2012-12-17 Jan Kratochvil <jan.kratochvil@redhat.com>

* gdb.texinfo (GDB/MI Data Manipulation) (fullname): Make it always
present.
(GDB/MI File Commands) (-file-list-exec-source-files): Make the
fullname output always present.

gdb/testsuite/
2012-12-17 Jan Kratochvil <jan.kratochvil@redhat.com>

* gdb.mi/mi-fullname-deleted.exp: New file.

diff --git a/gdb/ada-lang.c b/gdb/ada-lang.c
index f07e4bc..cb7313b 100644
--- a/gdb/ada-lang.c
+++ b/gdb/ada-lang.c
@@ -11084,6 +11084,7 @@ is_known_support_routine (struct frame_info *frame)
const char *func_name;
enum language func_lang;
int i;
+ const char *fullname;

/* If this code does not have any debugging information (no symtab),
This cannot be any user code. */
@@ -11098,7 +11099,8 @@ is_known_support_routine (struct frame_info *frame)
for the user. This should also take care of case such as VxWorks
where the kernel has some debugging info provided for a few units. */

- if (symtab_to_fullname (sal.symtab) == NULL)
+ fullname = symtab_to_fullname (sal.symtab);
+ if (access (fullname, R_OK) != 0)
return 1;

/* Check the unit filename againt the Ada runtime file naming.
diff --git a/gdb/breakpoint.c b/gdb/breakpoint.c
index c2ce96c..d587cb4 100644
--- a/gdb/breakpoint.c
+++ b/gdb/breakpoint.c
@@ -5694,8 +5694,7 @@ print_breakpoint_location (struct breakpoint *b,
struct symtab_and_line sal = find_pc_line (loc->address, 0);
const char *fullname = symtab_to_fullname (sal.symtab);

- if (fullname)
- ui_out_field_string (uiout, "fullname", fullname);
+ ui_out_field_string (uiout, "fullname", fullname);
}

ui_out_field_int (uiout, "line", loc->line_number);
@@ -13872,8 +13871,7 @@ update_static_tracepoint (struct breakpoint *b, struct symtab_and_line sal)
{
const char *fullname = symtab_to_fullname (sal2.symtab);

- if (fullname)
- ui_out_field_string (uiout, "fullname", fullname);
+ ui_out_field_string (uiout, "fullname", fullname);
}

ui_out_field_int (uiout, "line", sal2.line);
diff --git a/gdb/cli/cli-cmds.c b/gdb/cli/cli-cmds.c
index b65262e..fe84256 100644
--- a/gdb/cli/cli-cmds.c
+++ b/gdb/cli/cli-cmds.c
@@ -842,16 +842,7 @@ edit_command (char *arg, int from_tty)
if ((editor = (char *) getenv ("EDITOR")) == NULL)
editor = "/bin/ex";

- /* If we don't already know the full absolute file name of the
- source file, find it now. */
- if (!sal.symtab->fullname)
- {
- fn = symtab_to_fullname (sal.symtab);
- if (!fn)
- fn = "unknown";
- }
- else
- fn = sal.symtab->fullname;
+ fn = symtab_to_fullname (sal.symtab);

/* Quote the file name, in case it has whitespace or other special
characters. */
diff --git a/gdb/mi/mi-cmd-file.c b/gdb/mi/mi-cmd-file.c
index 0b2b725..018f505 100644
--- a/gdb/mi/mi-cmd-file.c
+++ b/gdb/mi/mi-cmd-file.c
@@ -48,16 +48,11 @@ mi_cmd_file_list_exec_source_file (char *command, char **argv, int argc)
if (!st.symtab)
error (_("-file-list-exec-source-file: No symtab"));

- /* Extract the fullname if it is not known yet. */
- symtab_to_fullname (st.symtab);
-
/* Print to the user the line, filename and fullname. */
ui_out_field_int (uiout, "line", st.line);
ui_out_field_string (uiout, "file", st.symtab->filename);

- /* We may not be able to open the file (not available). */
- if (st.symtab->fullname)
- ui_out_field_string (uiout, "fullname", st.symtab->fullname);
+ ui_out_field_string (uiout, "fullname", symtab_to_fullname (st.symtab));

ui_out_field_int (uiout, "macro-info", st.symtab->macro_table ? 1 : 0);
}
@@ -99,12 +94,7 @@ mi_cmd_file_list_exec_source_files (char *command, char **argv, int argc)
ui_out_begin (uiout, ui_out_type_tuple, NULL);

ui_out_field_string (uiout, "file", s->filename);
-
- /* Extract the fullname if it is not known yet. */
- symtab_to_fullname (s);
-
- if (s->fullname)
- ui_out_field_string (uiout, "fullname", s->fullname);
+ ui_out_field_string (uiout, "fullname", symtab_to_fullname (s));

ui_out_end (uiout, ui_out_type_tuple);
}
diff --git a/gdb/python/py-symtab.c b/gdb/python/py-symtab.c
index d3e95db..deb7330 100644
--- a/gdb/python/py-symtab.c
+++ b/gdb/python/py-symtab.c
@@ -132,11 +132,8 @@ stpy_fullname (PyObject *self, PyObject *args)
STPY_REQUIRE_VALID (self, symtab);

fullname = symtab_to_fullname (symtab);
- if (fullname)
- return PyString_Decode (fullname, strlen (fullname),
- host_charset (), NULL);

- Py_RETURN_NONE;
+ return PyString_Decode (fullname, strlen (fullname), host_charset (), NULL);
}

/* Implementation of gdb.Symtab.is_valid (self) -> Boolean.
diff --git a/gdb/source.c b/gdb/source.c
index 7e14fc6..6e65d1a 100644
--- a/gdb/source.c
+++ b/gdb/source.c
@@ -1075,35 +1075,32 @@ open_source_file (struct symtab *s)

/* Finds the fullname that a symtab represents.

- If this functions finds the fullname, it will save it in s->fullname
- and it will also return the value.
+ This functions finds the fullname and saves it in s->fullname.
+ It will also return the value.

If this function fails to find the file that this symtab represents,
- NULL will be returned and s->fullname will be set to NULL. */
+ the expected fullname is used. Therefore the files does not have to
+ exist. */

const char *
symtab_to_fullname (struct symtab *s)
{
- int r;
-
- if (!s)
- return NULL;
-
/* Use cached copy if we have it.
We rely on forget_cached_source_info being called appropriately
to handle cases like the file being moved. */
- if (s->fullname)
- return s->fullname;
-
- r = find_and_open_source (s->filename, s->dirname, &s->fullname);
-
- if (r >= 0)
+ if (s->fullname == NULL)
{
- close (r);
- return s->fullname;
- }
+ int fd = find_and_open_source (s->filename, s->dirname, &s->fullname);

- return NULL;
+ if (fd >= 0)
+ close (fd);
+ else if (s->dirname == NULL)
+ s->fullname = xstrdup (s->filename);
+ else
+ s->fullname = concat (s->dirname, SLASH_STRING, s->filename, NULL);
+ }
+
+ return s->fullname;
}
\f
/* Create and initialize the table S->line_charpos that records
@@ -1306,8 +1303,7 @@ print_source_lines_base (struct symtab *s, int line, int stopline,
{
const char *fullname = symtab_to_fullname (s);

- if (fullname != NULL)
- ui_out_field_string (uiout, "fullname", fullname);
+ ui_out_field_string (uiout, "fullname", fullname);
}
ui_out_text (uiout, "\n");
}
diff --git a/gdb/stack.c b/gdb/stack.c
index e246a68..6cf6052 100644
--- a/gdb/stack.c
+++ b/gdb/stack.c
@@ -1189,8 +1189,7 @@ print_frame (struct frame_info *frame, int print_level,
{
const char *fullname = symtab_to_fullname (sal.symtab);

- if (fullname != NULL)
- ui_out_field_string (uiout, "fullname", fullname);
+ ui_out_field_string (uiout, "fullname", fullname);
}
annotate_frame_source_file_end ();
ui_out_text (uiout, ":");
diff --git a/gdb/symtab.c b/gdb/symtab.c
index 0fd75e5..e3c0700 100644
--- a/gdb/symtab.c
+++ b/gdb/symtab.c
@@ -225,13 +225,13 @@ iterate_over_some_symtabs (const char *name,
{
const char *fp = symtab_to_fullname (s);

- if (fp != NULL && FILENAME_CMP (full_path, fp) == 0)
+ if (FILENAME_CMP (full_path, fp) == 0)
{
if (callback (s, data))
return 1;
}

- if (fp != NULL && !is_abs && compare_filenames_for_search (fp, name))
+ if (!is_abs && compare_filenames_for_search (fp, name))
{
if (callback (s, data))
return 1;
@@ -241,24 +241,20 @@ iterate_over_some_symtabs (const char *name,
if (real_path != NULL)
{
const char *fullname = symtab_to_fullname (s);
+ char *rp = gdb_realpath (fullname);

- if (fullname != NULL)
- {
- char *rp = gdb_realpath (fullname);
-
- make_cleanup (xfree, rp);
- if (FILENAME_CMP (real_path, rp) == 0)
- {
- if (callback (s, data))
- return 1;
- }
+ make_cleanup (xfree, rp);
+ if (FILENAME_CMP (real_path, rp) == 0)
+ {
+ if (callback (s, data))
+ return 1;
+ }

- if (!is_abs && compare_filenames_for_search (rp, name))
- {
- if (callback (s, data))
- return 1;
- }
- }
+ if (!is_abs && compare_filenames_for_search (rp, name))
+ {
+ if (callback (s, data))
+ return 1;
+ }
}
}

@@ -2552,9 +2548,6 @@ find_line_symtab (struct symtab *symtab, int line,
symtab->filename);
}

- /* Get symbol full file name if possible. */
- symtab_to_fullname (symtab);
-
ALL_SYMTABS (objfile, s)
{
struct linetable *l;
@@ -2562,9 +2555,7 @@ find_line_symtab (struct symtab *symtab, int line,

if (FILENAME_CMP (symtab->filename, s->filename) != 0)
continue;
- if (symtab->fullname != NULL
- && symtab_to_fullname (s) != NULL
- && FILENAME_CMP (symtab->fullname, s->fullname) != 0)
+ if (FILENAME_CMP (symtab->fullname, symtab_to_fullname (s)) != 0)
continue;
l = LINETABLE (s);
ind = find_line_common (l, line, &exact, 0);
@@ -3295,7 +3286,7 @@ sources_info (char *ignore, int from_tty)
{
const char *fullname = symtab_to_fullname (s);

- output_source_filename (fullname ? fullname : s->filename, &data);
+ output_source_filename (fullname, &data);
}
printf_filtered ("\n\n");

diff --git a/gdb/tracepoint.c b/gdb/tracepoint.c
index 848179a..2ab8323 100644
--- a/gdb/tracepoint.c
+++ b/gdb/tracepoint.c
@@ -4872,8 +4872,7 @@ print_one_static_tracepoint_marker (int count,
{
const char *fullname = symtab_to_fullname (sal.symtab);

- if (fullname)
- ui_out_field_string (uiout, "fullname", fullname);
+ ui_out_field_string (uiout, "fullname", fullname);
}
else
ui_out_field_skip (uiout, "fullname");
diff --git a/gdb/doc/gdb.texinfo b/gdb/doc/gdb.texinfo
index 5abcd93..c40cc82 100644
--- a/gdb/doc/gdb.texinfo
+++ b/gdb/doc/gdb.texinfo
@@ -31086,9 +31086,13 @@ file name or a relative file name depending on the compile command
used.

@item fullname
-This field is optional. If it is present it will contain an absolute
-file name of @samp{file}. If this field is not present then
-@value{GDBN} was unable to determine the absolute file name.
+Absolute file name of @samp{file}. It is converted to a canonical form
+using the source file search path
+(@pxref{Source Path, ,Specifying Source Directories}).
+and after resolving all the symbolic links.
+
+If the source file is not found this field will contain the path as
+present in the debug information.

@item line_asm_insn
This is a list of tuples containing the disassembly for @samp{line} in
@@ -32269,8 +32273,8 @@ The @value{GDBN} equivalent is @samp{info source}

List the source files for the current executable.

-It will always output the filename, but only when @value{GDBN} can find
-the absolute file name of a source file, will it output the fullname.
+It will always output both the filename and fullname (absolute file
+name) of a source file.

@subsubheading @value{GDBN} Command

diff --git a/gdb/testsuite/gdb.mi/mi-fullname-deleted.exp b/gdb/testsuite/gdb.mi/mi-fullname-deleted.exp
new file mode 100644
index 0000000..c40f6b2
--- /dev/null
+++ b/gdb/testsuite/gdb.mi/mi-fullname-deleted.exp
@@ -0,0 +1,40 @@
+# Copyright 2012 Free Software Foundation, Inc.
+
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 3 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program. If not, see <http://www.gnu.org/licenses/>.
+
+load_lib mi-support.exp
+set MIFLAGS "-i=mi"
+
+gdb_exit
+if [mi_gdb_start] {
+ continue
+}
+
+standard_testfile
+
+set f [open ${objdir}/${subdir}/${srcfile} "w"]
+puts $f "int main (void) { return 0; }"
+close $f
+
+if { [gdb_compile "${objdir}/${subdir}/${srcfile}" "${binfile}" executable {debug}] != "" } {
+ untested $testname
+ return -1
+}
+
+file delete -- ${objdir}/${subdir}/${srcfile}
+
+mi_gdb_reinitialize_dir $srcdir/$subdir
+mi_gdb_load ${binfile}
+
+mi_gdb_test "-file-list-exec-source-file" ".*\",fullname=\"[string_to_regexp ${objdir}/${subdir}/${srcfile}]\".*" "fullname present"