-file-list-exec-source-files

Bob Rossi
2004-02-25T04:01:06Z

Hi,

Here is an initial patch for -file-list-exec-source-files.
Some feedback would be appreciated.

I ran the testsuite and the results are the same before and after this
patch.

Index: gdb/ChangeLog
* dbxread.c (read_dbx_symtab): set pst->dirname when known
* dwarf2read.c (partial_die_info) : add dirname field
(dwarf2_build_psymtabs_hard) : set pst->dirname when known
(read_partial_die) : save away DW_AT_comp_dir
* defs.h (symtab_to_filename) : Removed.
* source.c (find_and_open_source) : Added.
(open_source_file): just calls find_and_open_source
(symtab_to_filename) : Removed.
(symtab_to_fullname, psymtab_to_fullname ) : Added.
* source.h (psymtab_to_fullname,symtab_to_fullname): Added.
* symtab.c (lookup_symtab): Call symtab_to_fullname instead of
symtab_to_filename
* symtab.h (partial_symtab): Add dirname field.
* mi/mi-cmd-file.c (FILENAME,FULLNAME): Add
(mi_cmd_file_list_exec_source_file): Call new function symtab_to_fullname
to find fullname. Print out "filename", instead of "file"
(mi_cmd_file_list_exec_source_files): Added.
* mi/mi-cmds.c (mi_cmd_mi_cmds) : Add -file-list-exec-source-files
* mi/mi-cmds.h (mi_cmd_file_list_exec_source_files): Added

Index: gdb/doc/ChangeLog
* gdb.texinfo: Add -file-list-exec-source-files doco
(-file-list-exec-source-file): change "file" to "filename"

Index: gdb/testsuite/ChangeLog
* gdb.mi/mi-file.exp: Change "file" to "filename"
* gdb.mi/mi2-file.exp:
(test_file_list_exec_source_files) Added
(test_file_list_exec_source_file) Added
(test_tbreak_creation_and_listing) Removed

Index: gdb/dbxread.c
===================================================================
RCS file: /cvs/src/src/gdb/dbxread.c,v
retrieving revision 1.64
diff -w -u -r1.64 dbxread.c
--- gdb/dbxread.c 14 Feb 2004 15:46:32 -0000 1.64
+++ gdb/dbxread.c 25 Feb 2004 03:51:34 -0000
@@ -1463,6 +1463,7 @@
static int prev_so_symnum = -10;
static int first_so_symnum;
char *p;
+ static char *dirname_nso;
int prev_textlow_not_set;

valu = nlist.n_value + ANOFFSET (objfile->section_offsets, SECT_OFF_TEXT (objfile));
@@ -1520,18 +1521,27 @@

p = strrchr (namestring, '/');
if (p && *(p + 1) == '\000')
- continue; /* Simply ignore directory name SOs */
+ {
+ /* Save the directory name SOs locally, then save it into
+ the psymtab when it's created below. */
+ dirname_nso = namestring;
+ continue;
+ }

/* Some other compilers (C++ ones in particular) emit useless
SOs for non-existant .c files. We ignore all subsequent SOs that
immediately follow the first. */

if (!pst)
+ {
pst = start_psymtab (objfile,
namestring, valu,
first_so_symnum * symbol_size,
objfile->global_psymbols.next,
objfile->static_psymbols.next);
+ pst->dirname = dirname_nso;
+ dirname_nso = NULL;
+ }
continue;
}

Index: gdb/defs.h
===================================================================
RCS file: /cvs/src/src/gdb/defs.h,v
retrieving revision 1.143
diff -w -u -r1.143 defs.h
--- gdb/defs.h 23 Feb 2004 19:26:14 -0000 1.143
+++ gdb/defs.h 25 Feb 2004 03:51:35 -0000
@@ -616,8 +616,6 @@

extern void init_last_source_visited (void);

-extern char *symtab_to_filename (struct symtab *);
-
/* From exec.c */

extern void exec_set_section_offsets (bfd_signed_vma text_off,
Index: gdb/dwarf2read.c
===================================================================
RCS file: /cvs/src/src/gdb/dwarf2read.c,v
retrieving revision 1.135
diff -w -u -r1.135 dwarf2read.c
--- gdb/dwarf2read.c 21 Feb 2004 02:13:35 -0000 1.135
+++ gdb/dwarf2read.c 25 Feb 2004 03:51:43 -0000
@@ -316,6 +316,7 @@
unsigned int offset;
unsigned int abbrev;
char *name;
+ char *dirname;
int has_pc_info;
CORE_ADDR lowpc;
CORE_ADDR highpc;
@@ -1254,6 +1255,8 @@
objfile->global_psymbols.next,
objfile->static_psymbols.next);

+ pst->dirname = xstrdup ( comp_unit_die.dirname );
+
pst->read_symtab_private = (char *)
obstack_alloc (&objfile->objfile_obstack, sizeof (struct dwarf2_pinfo));
DWARF_INFO_BUFFER (pst) = dwarf_info_buffer;
@@ -4326,6 +4329,10 @@
/* Prefer DW_AT_MIPS_linkage_name over DW_AT_name. */
if (part_die->name == NULL)
part_die->name = DW_STRING (&attr);
+ break;
+ case DW_AT_comp_dir:
+ if (part_die->dirname == NULL)
+ part_die->dirname = DW_STRING (&attr);
break;
case DW_AT_MIPS_linkage_name:
part_die->name = DW_STRING (&attr);
Index: gdb/source.c
===================================================================
RCS file: /cvs/src/src/gdb/source.c,v
retrieving revision 1.49
diff -w -u -r1.49 source.c
--- gdb/source.c 27 Jan 2004 23:19:51 -0000 1.49
+++ gdb/source.c 25 Feb 2004 03:51:45 -0000
@@ -805,30 +805,47 @@
return 1;
}

-
-/* Open a source file given a symtab S. Returns a file descriptor or
- negative number for error. */
-
+/* This function is capable of finding the absolute path to a
+ source file, and opening it, provided you give it an
+ OBJFILE and FILENAME. Both the DIRNAME and FULLNAME are only
+ added suggestions on where to find the file.
+
+ OBJFILE should be the objfile associated with a psymtab or symtab.
+ FILENAME should be the filename to open.
+ DIRNAME is the compilation directory of a particular source file.
+ Only some debug formats provide this info.
+ FULLNAME can be the last known absolute path to the file in question.
+
+ On Success
+ A valid file descriptor is returned. ( the return value is positive )
+ FULLNAME is set to the absolute path to the file just opened.
+
+ On Failure
+ A non valid file descriptor is returned. ( the return value is negitive )
+ FULLNAME is set to NULL. */
int
-open_source_file (struct symtab *s)
+find_and_open_source (
+ struct objfile *objfile,
+ const char *filename,
+ const char *dirname,
+ char **fullname )
{
char *path = source_path;
const char *p;
int result;
- char *fullname;

/* Quick way out if we already know its full name */
- if (s->fullname)
+ if (*fullname)
{
- result = open (s->fullname, OPEN_MODE);
+ result = open (*fullname, OPEN_MODE);
if (result >= 0)
return result;
/* Didn't work -- free old one, try again. */
- xmfree (s->objfile->md, s->fullname);
- s->fullname = NULL;
+ xmfree (objfile->md, *fullname);
+ *fullname = NULL;
}

- if (s->dirname != NULL)
+ if (dirname != NULL)
{
/* Replace a path entry of $cdir with the compilation directory name */
#define cdir_len 5
@@ -841,60 +858,102 @@
int len;

path = (char *)
- alloca (strlen (source_path) + 1 + strlen (s->dirname) + 1);
+ alloca (strlen (source_path) + 1 + strlen (dirname) + 1);
len = p - source_path;
strncpy (path, source_path, len); /* Before $cdir */
- strcpy (path + len, s->dirname); /* new stuff */
+ strcpy (path + len, dirname); /* new stuff */
strcat (path + len, source_path + len + cdir_len); /* After $cdir */
}
}

- result = openp (path, 0, s->filename, OPEN_MODE, 0, &s->fullname);
+ result = openp (path, 0, filename, OPEN_MODE, 0, fullname);
if (result < 0)
{
/* Didn't work. Try using just the basename. */
- p = lbasename (s->filename);
- if (p != s->filename)
- result = openp (path, 0, p, OPEN_MODE, 0, &s->fullname);
+ p = lbasename (filename);
+ if (p != filename)
+ result = openp (path, 0, p, OPEN_MODE, 0, fullname);
}

if (result >= 0)
{
- fullname = s->fullname;
- s->fullname = mstrsave (s->objfile->md, s->fullname);
- xfree (fullname);
+ char *tmp_fullname;
+ tmp_fullname = *fullname;
+ *fullname = mstrsave (objfile->md, *fullname);
+ xfree (tmp_fullname);
}
return result;
}

-/* Return the path to the source file associated with symtab. Returns NULL
- if no symtab. */
+/* Open a source file given a symtab S. Returns a file descriptor or
+ negative number for error.
+
+ This function is a convience function to find_and_open_source. */
+
+int
+open_source_file (struct symtab *s)
+{
+ if (!s)
+ return -1;
+
+ return find_and_open_source ( s->objfile, s->filename, s->dirname, &s->fullname );
+}
+
+/* Finds the fullname that a symtab represents.
+
+ If this functions finds the fullname, it will save it in ps->fullname
+ and it will also return the value.

+ If this function fails to find the file that this symtab represents,
+ NULL will be returned and ps->fullname will be set to NULL. */
char *
-symtab_to_filename (struct symtab *s)
+symtab_to_fullname (struct symtab *s)
{
- int fd;
+ int r;

if (!s)
return NULL;

- /* If we've seen the file before, just return fullname. */
+ /* Don't check s->fullname here, the file could have been
+ deleted/moved/..., look for it again */
+ r = find_and_open_source ( s->objfile, s->filename, s->dirname, &s->fullname);

- if (s->fullname)
+ if (r)
+ {
+ close (r);
return s->fullname;
+ }

- /* Try opening the file to setup fullname */
+ return NULL;
+}

- fd = open_source_file (s);
- if (fd < 0)
- return s->filename; /* File not found. Just use short name */
+/* Finds the fullname that a partial_symtab represents.

- /* Found the file. Cleanup and return the full name */
+ If this functions finds the fullname, it will save it in ps->fullname
+ and it will also return the value.

- close (fd);
- return s->fullname;
+ If this function fails to find the file that this partial_symtab represents,
+ NULL will be returned and ps->fullname will be set to NULL. */
+char *
+psymtab_to_fullname (struct partial_symtab *ps)
+{
+ int r;
+
+ if (!ps)
+ return NULL;
+
+ /* Don't check ps->fullname here, the file could have been
+ deleted/moved/..., look for it again */
+ r = find_and_open_source ( ps->objfile, ps->filename, ps->dirname, &ps->fullname);
+
+ if (r)
+ {
+ close (r);
+ return ps->fullname;
}
\f
+ return NULL;
+}

/* Create and initialize the table S->line_charpos that records
the positions of the lines in the source file, which is assumed
Index: gdb/source.h
===================================================================
RCS file: /cvs/src/src/gdb/source.h,v
retrieving revision 1.4
diff -w -u -r1.4 source.h
--- gdb/source.h 12 Apr 2003 17:41:25 -0000 1.4
+++ gdb/source.h 25 Feb 2004 03:51:45 -0000
@@ -27,6 +27,9 @@
negative number for error. */
extern int open_source_file (struct symtab *s);

+extern char* psymtab_to_fullname ( struct partial_symtab *ps );
+extern char* symtab_to_fullname ( struct symtab *s );
+
/* Create and initialize the table S->line_charpos that records the
positions of the lines in the source file, which is assumed to be
open on descriptor DESC. All set S->nlines to the number of such
Index: gdb/symtab.c
===================================================================
RCS file: /cvs/src/src/gdb/symtab.c,v
retrieving revision 1.128
diff -w -u -r1.128 symtab.c
--- gdb/symtab.c 19 Feb 2004 19:01:26 -0000 1.128
+++ gdb/symtab.c 25 Feb 2004 03:51:49 -0000
@@ -181,7 +181,7 @@

if (full_path != NULL)
{
- const char *fp = symtab_to_filename (s);
+ const char *fp = symtab_to_fullname (s);
if (FILENAME_CMP (full_path, fp) == 0)
{
return s;
@@ -190,7 +190,7 @@

if (real_path != NULL)
{
- char *rp = gdb_realpath (symtab_to_filename (s));
+ char *rp = gdb_realpath (symtab_to_fullname (s));
make_cleanup (xfree, rp);
if (FILENAME_CMP (real_path, rp) == 0)
{
Index: gdb/symtab.h
===================================================================
RCS file: /cvs/src/src/gdb/symtab.h,v
retrieving revision 1.88
diff -w -u -r1.88 symtab.h
--- gdb/symtab.h 17 Feb 2004 15:21:22 -0000 1.88
+++ gdb/symtab.h 25 Feb 2004 03:51:51 -0000
@@ -877,6 +877,10 @@

char *fullname;

+ /* Directory in which it was compiled, or NULL if we don't know. */
+
+ char *dirname;
+
/* Information about the object file from which symbols should be read. */

struct objfile *objfile;
Index: gdb/doc/gdb.texinfo
===================================================================
RCS file: /cvs/src/src/gdb/doc/gdb.texinfo,v
retrieving revision 1.196
diff -w -u -r1.196 gdb.texinfo
--- gdb/doc/gdb.texinfo 24 Feb 2004 15:41:29 -0000 1.196
+++ gdb/doc/gdb.texinfo 25 Feb 2004 03:52:19 -0000
@@ -16740,7 +16740,7 @@
@smallexample
(@value{GDBP})
123-file-list-exec-source-file
-123^done,line="1",file="foo.c",fullname="/home/bar/foo.c"
+123^done,line="1",filename="foo.c",fullname="/home/bar/foo.c"
(@value{GDBP})
@end smallexample

@@ -16756,14 +16756,24 @@

List the source files for the current executable.

+It will always output the filename, but only when GDB can find the absolute
+path to a source file, will it output the fullname.
+
@subsubheading @value{GDBN} Command

There's no @value{GDBN} command which directly corresponds to this one.
@code{gdbtk} has an analogous command @samp{gdb_listfiles}.

@subsubheading Example
-N.A.
-
+@smallexample
+(@value{GDBP})
+-file-list-exec-source-files
+^done,files=[
+@{filename=foo.c,fullname=/home/foo.c@},
+@{filename=/home/bar.c,fullname=/home/bar.c@},
+@{filename=gdb_could_not_find_fullpath.c@}]
+(@value{GDBP})
+@end smallexample

@subheading The @code{-file-list-shared-libraries} Command
@findex -file-list-shared-libraries
Index: gdb/mi/mi-cmd-file.c
===================================================================
RCS file: /cvs/src/src/gdb/mi/mi-cmd-file.c,v
retrieving revision 1.1
diff -w -u -r1.1 mi-cmd-file.c
--- gdb/mi/mi-cmd-file.c 2 Apr 2003 22:10:35 -0000 1.1
+++ gdb/mi/mi-cmd-file.c 25 Feb 2004 03:52:20 -0000
@@ -25,6 +25,10 @@
#include "ui-out.h"
#include "symtab.h"
#include "source.h"
+#include "objfiles.h"
+
+static const char * const FILENAME = "filename";
+static const char * const FULLNAME = "fullname";

/* Return to the client the absolute path and line number of the
current file being executed. */
@@ -39,7 +43,6 @@
if ( !mi_valid_noargs("mi_cmd_file_list_exec_source_file", argc, argv) )
error ("mi_cmd_file_list_exec_source_file: Usage: No args");

-
/* Set the default file and line, also get them */
set_default_source_symtab_and_line();
st = get_current_source_symtab_and_line();
@@ -51,17 +54,67 @@
error ("mi_cmd_file_list_exec_source_file: No symtab");

/* Extract the fullname if it is not known yet */
- if (st.symtab->fullname == NULL)
- symtab_to_filename (st.symtab);
-
- /* We may not be able to open the file (not available). */
- if (st.symtab->fullname == NULL)
- error ("mi_cmd_file_list_exec_source_file: File not found");
+ 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);
- ui_out_field_string (uiout, "fullname", st.symtab->fullname);
+ ui_out_field_string (uiout, FILENAME, 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);
+
+ return MI_CMD_DONE;
+}
+
+enum mi_cmd_result
+mi_cmd_file_list_exec_source_files(char *command, char **argv, int argc)
+{
+ struct symtab *s;
+ struct partial_symtab *ps;
+ struct objfile *objfile;
+
+ if ( !mi_valid_noargs("mi_cmd_file_list_exec_source_files", argc, argv) )
+ error ("mi_cmd_file_list_exec_source_files: Usage: No args");
+
+ /* Print the table header */
+ ui_out_begin ( uiout, ui_out_type_list, "files");
+
+ /* Look at all of the symtabs */
+ ALL_SYMTABS (objfile, s)
+ {
+ ui_out_begin ( uiout, ui_out_type_tuple, NULL);
+
+ ui_out_field_string (uiout, FILENAME, 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_end ( uiout, ui_out_type_tuple );
+ }
+
+ /* Look at all of the psymtabs */
+ ALL_PSYMTABS (objfile, ps)
+ {
+ if (!ps->readin) {
+ ui_out_begin ( uiout, ui_out_type_tuple, NULL);
+
+ ui_out_field_string (uiout, FILENAME, ps->filename);
+
+ /* Extract the fullname if it is not known yet */
+ psymtab_to_fullname (ps);
+
+ if (ps->fullname)
+ ui_out_field_string (uiout, FULLNAME, ps->fullname);
+
+ ui_out_end ( uiout, ui_out_type_tuple );
+ }
+ }
+
+ ui_out_end ( uiout, ui_out_type_list );

return MI_CMD_DONE;
}
Index: gdb/mi/mi-cmds.c
===================================================================
RCS file: /cvs/src/src/gdb/mi/mi-cmds.c,v
retrieving revision 1.14
diff -w -u -r1.14 mi-cmds.c
--- gdb/mi/mi-cmds.c 4 Aug 2003 23:18:50 -0000 1.14
+++ gdb/mi/mi-cmds.c 25 Feb 2004 03:52:20 -0000
@@ -81,7 +81,7 @@
{ "file-exec-file", { "exec-file", 1 }, NULL, NULL },
{ "file-list-exec-sections", { NULL, 0 }, NULL, NULL },
{ "file-list-exec-source-file", { NULL, 0 }, 0, mi_cmd_file_list_exec_source_file},
- { "file-list-exec-source-files", { NULL, 0 }, NULL, NULL },
+ { "file-list-exec-source-files", { NULL, 0 }, NULL, mi_cmd_file_list_exec_source_files },
{ "file-list-shared-libraries", { NULL, 0 }, NULL, NULL },
{ "file-list-symbol-files", { NULL, 0 }, NULL, NULL },
{ "file-symbol-file", { "symbol-file", 1 }, NULL, NULL },
Index: gdb/mi/mi-cmds.h
===================================================================
RCS file: /cvs/src/src/gdb/mi/mi-cmds.h,v
retrieving revision 1.12
diff -w -u -r1.12 mi-cmds.h
--- gdb/mi/mi-cmds.h 24 Jan 2004 04:21:43 -0000 1.12
+++ gdb/mi/mi-cmds.h 25 Feb 2004 03:52:20 -0000
@@ -87,6 +87,7 @@
extern mi_cmd_args_ftype mi_cmd_exec_until;
extern mi_cmd_args_ftype mi_cmd_exec_interrupt;
extern mi_cmd_argv_ftype mi_cmd_file_list_exec_source_file;
+extern mi_cmd_argv_ftype mi_cmd_file_list_exec_source_files;
extern mi_cmd_argv_ftype mi_cmd_gdb_exit;
extern mi_cmd_argv_ftype mi_cmd_interpreter_exec;
extern mi_cmd_argv_ftype mi_cmd_stack_info_depth;
Index: gdb/testsuite/gdb.mi/mi-file.exp
===================================================================
RCS file: /cvs/src/src/gdb/testsuite/gdb.mi/mi-file.exp,v
retrieving revision 1.1
diff -w -u -r1.1 mi-file.exp
--- gdb/testsuite/gdb.mi/mi-file.exp 2 Apr 2003 22:10:35 -0000 1.1
+++ gdb/testsuite/gdb.mi/mi-file.exp 25 Feb 2004 03:52:36 -0000
@@ -55,7 +55,7 @@

# get the path and absolute path to the current executable
mi_gdb_test "111-file-list-exec-source-file" \
- "111\\\^done,line=\"23\",file=\"${srcfilepath}\",fullname=\"/.*/${srcfile}\"" \
+ "111\\\^done,line=\"23\",filename=\"${srcfilepath}\",fullname=\"/.*/${srcfile}\"" \
"request path info of current source file (${srcfile})"
}

Index: gdb/testsuite/gdb.mi/mi2-file.exp
===================================================================
RCS file: /cvs/src/src/gdb/testsuite/gdb.mi/mi2-file.exp,v
retrieving revision 1.1
diff -w -u -r1.1 mi2-file.exp
--- gdb/testsuite/gdb.mi/mi2-file.exp 7 Aug 2003 17:47:42 -0000 1.1
+++ gdb/testsuite/gdb.mi/mi2-file.exp 25 Feb 2004 03:52:36 -0000
@@ -47,7 +47,7 @@
mi_gdb_reinitialize_dir $srcdir/$subdir
mi_gdb_load ${binfile}

-proc test_tbreak_creation_and_listing {} {
+proc test_file_list_exec_source_file {} {
global srcfile
global srcdir
global subdir
@@ -55,11 +55,21 @@

# get the path and absolute path to the current executable
mi_gdb_test "111-file-list-exec-source-file" \
- "111\\\^done,line=\"23\",file=\"${srcfilepath}\",fullname=\"/.*/${srcfile}\"" \
+ "111\\\^done,line=\"23\",filename=\"${srcfilepath}\",fullname=\"/.*/${srcfile}\"" \
"request path info of current source file (${srcfile})"
}

-test_tbreak_creation_and_listing
+proc test_file_list_exec_source_files {} {
+ global srcfile
+
+ # get the path and absolute path to the current executable
+ mi_gdb_test "222-file-list-exec-source-files" \
+ "222\\\^done,files=\\\[\{filename=\".*/${srcfile}\",fullname=\"/.*/${srcfile}\"\},\{filename=\".*\"\},\{filename=\".*\"\},\{filename=\".*\"\},\{filename=\".*\"\}\\\]" \
+ "Getting a list of source files failed."
+}
+
+test_file_list_exec_source_file
+test_file_list_exec_source_files

mi_gdb_exit
return 0