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

Jan Kratochvil
2012-12-17T18:59:34Z

On Mon, 17 Dec 2012 19:41:38 +0100, Tom Tromey wrote:
> Jan> It cannot be, as it is ${objdir}, not ${srcdir}, as the source file
> Jan> needs to be modified (=deleted).
>
> standard_output_file makes a file name in objdir.

OK, sorry.

Jan

gdb/
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/doc/gdb.texinfo b/gdb/doc/gdb.texinfo
index 5abcd93..c1ba745 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/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 b01c8f0..867c802 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/testsuite/gdb.mi/mi-fullname-deleted.exp b/gdb/testsuite/gdb.mi/mi-fullname-deleted.exp
new file mode 100644
index 0000000..d76225e
--- /dev/null
+++ b/gdb/testsuite/gdb.mi/mi-fullname-deleted.exp
@@ -0,0 +1,41 @@
+# 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 srcfileabs [standard_output_file $srcfile]
+
+set f [open $srcfileabs "w"]
+puts $f "int main (void) { return 0; }"
+close $f
+
+if { [gdb_compile "$srcfileabs" "${binfile}" executable {debug}] != "" } {
+ untested $testname
+ return -1
+}
+
+file delete -- $srcfileabs
+
+mi_gdb_reinitialize_dir $srcdir/$subdir
+mi_gdb_load ${binfile}
+
+mi_gdb_test "-file-list-exec-source-file" ".*\",fullname=\"[string_to_regexp $srcfileabs]\".*" "fullname present"
diff --git a/gdb/tracepoint.c b/gdb/tracepoint.c
index f61ede7..647c31e 100644
--- a/gdb/tracepoint.c
+++ b/gdb/tracepoint.c
@@ -4873,8 +4873,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");