1 /* List lines of source files for GDB, the GNU debugger.
2 Copyright (C) 1986, 1987, 1988 Free Software Foundation, Inc.
4 GDB is distributed in the hope that it will be useful, but WITHOUT ANY
5 WARRANTY. No author or distributor accepts responsibility to anyone
6 for the consequences of using it or for whether it serves any
7 particular purpose or works at all, unless he says so in writing.
8 Refer to the GDB General Public License for full details.
10 Everyone is granted permission to copy, modify and redistribute GDB,
11 but only under the conditions described in the GDB General Public
12 License. A copy of this license is supposed to have been given to you
13 along with GDB so you can know your rights and responsibilities. It
14 should be in a file named COPYING. Among other things, the copyright
15 notice and this notice must be preserved on all copies.
17 In other words, go ahead and share GDB, but don't try to stop
18 anyone else from sharing it farther. Help stamp out software hoarding!
22 #include <sys/param.h>
26 #include "initialize.h"
29 /* Path of directories to search for source files.
30 Same format as the PATH environment variable's value. */
32 static char *source_path
;
34 /* Symtab of default file for listing lines of. */
36 struct symtab
*current_source_symtab
;
38 /* Default next line to list. */
40 int current_source_line
;
42 /* Line number of last line printed. Default for various commands.
43 current_source_line is usually, but not always, the same as this. */
45 static int last_line_listed
;
47 /* First line number listed by last listing command. */
49 static int first_line_listed
;
53 /* Set the source file default for the "list" command,
54 specifying a symtab. */
57 select_source_symtab (s
)
58 register struct symtab
*s
;
62 struct symtabs_and_lines sals
;
63 struct symtab_and_line sal
;
65 /* Make the default place to list be the function `main'
67 if (lookup_symbol ("main", 0, VAR_NAMESPACE
))
69 sals
= decode_line_spec ("main", 1);
72 current_source_symtab
= sal
.symtab
;
73 current_source_line
= sal
.line
- 9;
77 /* If there is no `main', use the last symtab in the list,
78 which is actually the first found in the file's symbol table.
79 But ignore .h files. */
82 char *name
= s
->filename
;
83 int len
= strlen (name
);
84 if (! (len
> 2 && !strcmp (&name
[len
- 2], ".h")))
85 current_source_symtab
= s
;
89 current_source_line
= 1;
96 printf ("Source directories searched: %s\n", source_path
);
102 register struct symtab
*s
;
104 source_path
= savestring (current_directory
, strlen (current_directory
));
106 /* Forget what we learned about line positions in source files;
107 must check again now since files may be found in
108 a different directory now. */
109 for (s
= symtab_list
; s
; s
= s
->next
)
110 if (s
->line_charpos
!= 0)
112 free (s
->line_charpos
);
118 directory_command (dirname
, from_tty
)
122 char *old
= source_path
;
126 if (query ("Reinitialize source path to %s? ", current_directory
))
135 register int len
= strlen (dirname
);
137 extern char *index ();
139 if (index (dirname
, ':'))
140 error ("Please add one directory at a time to the source path.");
141 if (dirname
[len
- 1] == '/')
142 /* Sigh. "foo/" => "foo" */
143 dirname
[--len
] == '\0';
145 while (dirname
[len
- 1] == '.')
149 /* "." => getwd () */
150 dirname
= current_directory
;
153 else if (dirname
[len
- 2] == '/')
158 dirname
[--len
] = '\0';
163 /* "...foo/." => "...foo" */
164 dirname
[len
-= 2] = '\0';
171 if (dirname
[0] != '/')
172 dirname
= concat (current_directory
, "/", dirname
);
174 dirname
= savestring (dirname
, len
);
175 make_cleanup (free
, dirname
);
177 if (stat (dirname
, &st
) < 0)
178 perror_with_name (dirname
);
179 if ((st
.st_mode
& S_IFMT
) != S_IFDIR
)
180 error ("%s is not a directory.", dirname
);
183 len
= strlen (dirname
);
187 if (!strncmp (tem
, dirname
, len
)
188 && (tem
[len
] == '\0' || tem
[len
] == ':'))
190 printf ("\"%s\" is already in the source path.\n",
194 tem
= index (tem
, ':');
199 source_path
= concat (old
, ":", dirname
);
209 /* Open a file named STRING, searching path PATH (dir names sep by colons)
210 using mode MODE and protection bits PROT in the calls to open.
211 If TRY_CWD_FIRST, try to open ./STRING before searching PATH.
212 (ie pretend the first element of PATH is ".")
213 If FILENAMED_OPENED is non-null, set it to a newly allocated string naming
214 the actual file opened (this string will always start with a "/"
216 If a file is found, return the descriptor.
217 Otherwise, return -1, with errno set for the last name we tried to open. */
219 /* >>>> This should only allow files of certain types,
220 >>>> eg executable, non-directory */
222 openp (path
, try_cwd_first
, string
, mode
, prot
, filename_opened
)
228 char **filename_opened
;
231 register char *filename
;
232 register char *p
, *p1
;
236 while (string
[0] == '.' && string
[1] == '/')
239 if (try_cwd_first
|| string
[0] == '/')
242 fd
= open (filename
, mode
, prot
);
243 if (fd
>= 0 || string
[0] == '/')
247 filename
= (char *) alloca (strlen (path
) + strlen (string
) + 2);
249 for (p
= path
; p
; p
= p1
? p1
+ 1 : 0)
251 p1
= (char *) index (p
, ':');
257 strncpy (filename
, p
, len
);
259 strcat (filename
, "/");
260 strcat (filename
, string
);
262 fd
= open (filename
, mode
, prot
);
269 *filename_opened
= (char *) 0;
270 else if (filename
[0] == '/')
271 *filename_opened
= savestring (filename
, strlen (filename
));
274 *filename_opened
= concat (current_directory
, "/", filename
);
280 /* Create and initialize the table S->line_charpos that records
281 the positions of the lines in the source file, which is assumed
282 to be open on descriptor DESC.
283 All set S->nlines to the number of such lines. */
286 find_source_lines (s
, desc
)
291 register char *data
, *p
, *end
;
293 int lines_allocated
= 1000;
294 int *line_charpos
= (int *) xmalloc (lines_allocated
* sizeof (int));
295 extern int exec_mtime
;
298 if (get_exec_file (0) != 0 && exec_mtime
< st
.st_mtime
)
299 printf ("Source file is more recent than executable.\n");
301 data
= (char *) alloca (st
.st_size
);
302 myread (desc
, data
, st
.st_size
);
303 end
= data
+ st
.st_size
;
310 /* A newline at the end does not start a new line. */
313 if (nlines
== lines_allocated
)
315 lines_allocated
*= 2;
316 line_charpos
= (int *) xrealloc (line_charpos
,
317 sizeof (int) * lines_allocated
);
319 line_charpos
[nlines
++] = p
- data
;
323 s
->line_charpos
= (int *) xrealloc (line_charpos
, nlines
* sizeof (int));
326 /* Return the character position of a line LINE in symtab S.
327 Return 0 if anything is invalid. */
330 source_line_charpos (s
, line
)
335 if (!s
->line_charpos
|| line
<= 0) return 0;
336 if (line
> s
->nlines
)
338 return s
->line_charpos
[line
- 1];
341 /* Return the line number of character position POS in symtab S. */
344 source_charpos_line (s
, chr
)
345 register struct symtab
*s
;
348 register int line
= 0;
351 if (s
== 0 || s
->line_charpos
== 0) return 0;
352 lnp
= s
->line_charpos
;
353 /* Files are usually short, so sequential search is Ok */
354 while (line
< s
->nlines
&& *lnp
<= chr
)
359 if (line
>= s
->nlines
)
364 /* Get full pathname and line number positions for a symtab.
365 Return nonzero if line numbers may have changed.
366 Set *FULLNAME to actual name of the file as found by `openp',
367 or to 0 if the file is not found. */
370 get_filename_and_charpos (s
, line
, fullname
)
375 register int desc
, linenums_changed
= 0;
377 desc
= openp (source_path
, 0, s
->filename
, O_RDONLY
, 0, &s
->fullname
);
385 *fullname
= s
->fullname
;
386 if (s
->line_charpos
== 0) linenums_changed
= 1;
387 if (linenums_changed
) find_source_lines (s
, desc
);
389 return linenums_changed
;
392 /* Print text describing the full name of the source file S
393 and the line number LINE and its corresponding character position.
394 The text starts with two Ctrl-z so that the Emacs-GDB interface
397 MID_STATEMENT is nonzero if the PC is not at the beginning of that line.
399 Return 1 if successful, 0 if could not find the file. */
402 identify_source_line (s
, line
, mid_statement
)
407 if (s
->line_charpos
== 0)
408 get_filename_and_charpos (s
, line
, 0);
409 if (s
->fullname
== 0)
411 printf ("\032\032%s:%d:%d:%s\n", s
->fullname
,
412 line
, s
->line_charpos
[line
- 1],
413 mid_statement
? "middle" : "beg");
414 current_source_line
= line
;
415 first_line_listed
= line
;
416 last_line_listed
= line
;
417 current_source_symtab
= s
;
421 /* Print source lines from the file of symtab S,
422 starting with line number LINE and stopping before line number STOPLINE. */
425 print_source_lines (s
, line
, stopline
, noerror
)
432 register FILE *stream
;
433 int nlines
= stopline
- line
;
435 desc
= openp (source_path
, 0, s
->filename
, O_RDONLY
, 0, &s
->fullname
);
440 perror_with_name (s
->filename
);
441 print_sys_errmsg (s
->filename
, errno
);
445 if (s
->line_charpos
== 0)
446 find_source_lines (s
, desc
);
448 if (line
< 1 || line
> s
->nlines
)
451 error ("Line number out of range; %s has %d lines.",
452 s
->filename
, s
->nlines
);
455 if (lseek (desc
, s
->line_charpos
[line
- 1], 0) < 0)
458 perror_with_name (s
->filename
);
461 current_source_symtab
= s
;
462 current_source_line
= line
;
463 first_line_listed
= line
;
465 stream
= fdopen (desc
, "r");
472 last_line_listed
= current_source_line
;
473 printf ("%d\t", current_source_line
++);
476 if (c
< 040 && c
!= '\t' && c
!= '\n')
479 fputc (c
+ 0100, stdout
);
485 } while (c
!= '\n' && (c
= fgetc (stream
)) >= 0);
492 list_command (arg
, from_tty
)
496 struct symtabs_and_lines sals
, sals_end
;
497 struct symtab_and_line sal
, sal_end
;
506 if (symtab_list
== 0)
507 error ("Listing source lines requires symbols.");
509 /* "l" or "l +" lists next ten lines. */
511 if (arg
== 0 || !strcmp (arg
, "+"))
513 if (current_source_symtab
== 0)
514 error ("No default source file yet. Do \"help list\".");
515 print_source_lines (current_source_symtab
, current_source_line
,
516 current_source_line
+ 10, 0);
520 /* "l -" lists previous ten lines, the ones before the ten just listed. */
521 if (!strcmp (arg
, "-"))
523 if (current_source_symtab
== 0)
524 error ("No default source file yet. Do \"help list\".");
525 print_source_lines (current_source_symtab
,
526 max (first_line_listed
- 10, 1),
527 first_line_listed
, 0);
531 /* Now if there is only one argument, decode it in SAL
533 If there are two arguments, decode them in SAL and SAL_END
534 and clear NO_END; however, if one of the arguments is blank,
535 set DUMMY_BEG or DUMMY_END to record that fact. */
542 sals
= decode_line_1 (&arg1
, 0, 0, 0);
544 if (! sals
.nelts
) return; /* C++ */
547 error ("Unreasonable listing request");
554 /* Record whether the BEG arg is all digits. */
556 for (p
= arg
; p
!= arg1
&& *p
>= '0' && *p
<= '9'; p
++);
557 linenum_beg
= (p
== arg1
);
559 while (*arg1
== ' ' || *arg1
== '\t')
565 while (*arg1
== ' ' || *arg1
== '\t')
572 sals_end
= decode_line_1 (&arg1
, 0, 0, 0);
574 sals_end
= decode_line_1 (&arg1
, 0, sal
.symtab
, sal
.line
);
575 if (! sals_end
.nelts
) return; /* C++ */
576 sal_end
= sals_end
.sals
[0];
577 free (sals_end
.sals
);
582 error ("Junk at end of line specification.");
584 if (!no_end
&& !dummy_beg
&& !dummy_end
585 && sal
.symtab
!= sal_end
.symtab
)
586 error ("Specified start and end are in different files.");
587 if (dummy_beg
&& dummy_end
)
588 error ("Two empty args do not say what lines to list.");
590 /* if line was specified by address,
591 first print exactly which line, and which file.
592 In this case, sal.symtab == 0 means address is outside
593 of all known source files, not that user failed to give a filename. */
597 error ("No source file for address 0x%x.", sal
.pc
);
598 sym
= find_pc_function (sal
.pc
);
600 printf ("0x%x is in %s (%s, line %d).\n",
601 sal
.pc
, SYMBOL_NAME (sym
), sal
.symtab
->filename
, sal
.line
);
603 printf ("0x%x is in %s, line %d.\n",
604 sal
.pc
, sal
.symtab
->filename
, sal
.line
);
607 /* If line was not specified by just a line number,
608 and it does not imply a symtab, it must be an undebuggable symbol
609 which means no source code. */
611 if (! linenum_beg
&& sal
.symtab
== 0)
612 error ("No line number known for %s.", arg
);
614 /* If this command is repeated with RET,
615 turn it into the no-arg variant. */
620 if (dummy_beg
&& sal_end
.symtab
== 0)
621 error ("No default source file yet. Do \"help list\".");
623 print_source_lines (sal_end
.symtab
, max (sal_end
.line
- 9, 1),
624 sal_end
.line
+ 1, 0);
625 else if (sal
.symtab
== 0)
626 error ("No default source file yet. Do \"help list\".");
628 print_source_lines (sal
.symtab
, max (sal
.line
- 5, 1), sal
.line
+ 5, 0);
630 print_source_lines (sal
.symtab
, sal
.line
,
631 dummy_end
? sal
.line
+ 10 : sal_end
.line
+ 1, 0);
634 /* Print info on range of pc's in a specified line. */
637 line_info (arg
, from_tty
)
641 struct symtabs_and_lines sals
;
642 struct symtab_and_line sal
;
643 int start_pc
, end_pc
;
647 sal
.symtab
= current_source_symtab
;
648 sal
.line
= last_line_listed
;
652 sals
= decode_line_spec (arg
);
657 error ("unreasonable line info request");
661 /* If this command is repeated with RET,
662 turn it into the no-arg variant. */
669 error ("No source file specified.");
671 && find_line_pc_range (sal
.symtab
, sal
.line
, &start_pc
, &end_pc
))
673 if (start_pc
== end_pc
)
674 printf ("Line %d of \"%s\" is at pc 0x%x but contains no code.\n",
675 sal
.line
, sal
.symtab
->filename
, start_pc
);
677 printf ("Line %d of \"%s\" starts at pc 0x%x and ends at 0x%x.\n",
678 sal
.line
, sal
.symtab
->filename
, start_pc
, end_pc
);
679 /* x/i should display this line's code. */
680 set_next_address (start_pc
);
681 /* Repeating "info line" should do the following line. */
682 last_line_listed
= sal
.line
+ 1;
685 printf ("Line number %d is out of range for \"%s\".\n",
686 sal
.line
, sal
.symtab
->filename
);
689 /* Commands to search the source file for a regexp. */
692 forward_search_command (regex
, from_tty
)
697 register FILE *stream
;
698 int line
= last_line_listed
+ 1;
701 msg
= (char *) re_comp (regex
);
705 if (current_source_symtab
== 0)
706 error ("No default source file yet. Do \"help list\".");
708 /* Search from last_line_listed+1 in current_source_symtab */
710 desc
= openp (source_path
, 0, current_source_symtab
->filename
,
711 O_RDONLY
, 0, ¤t_source_symtab
->fullname
);
713 perror_with_name (current_source_symtab
->filename
);
715 if (current_source_symtab
->line_charpos
== 0)
716 find_source_lines (current_source_symtab
, desc
);
718 if (line
< 1 || line
> current_source_symtab
->nlines
)
721 error ("Expression not found");
724 if (lseek (desc
, current_source_symtab
->line_charpos
[line
- 1], 0) < 0)
727 perror_with_name (current_source_symtab
->filename
);
730 stream
= fdopen (desc
, "r");
733 char buf
[4096]; /* Should be reasonable??? */
734 register char *p
= buf
;
741 } while (c
!= '\n' && (c
= fgetc (stream
)) >= 0);
743 /* we now have a source line in buf, null terminate and match */
745 if (re_exec (buf
) > 0)
749 print_source_lines (current_source_symtab
,
751 current_source_line
= max (line
- 5, 1);
757 printf ("Expression not found\n");
762 reverse_search_command (regex
, from_tty
)
767 register FILE *stream
;
768 int line
= last_line_listed
- 1;
771 msg
= (char *) re_comp (regex
);
775 if (current_source_symtab
== 0)
776 error ("No default source file yet. Do \"help list\".");
778 /* Search from last_line_listed-1 in current_source_symtab */
780 desc
= openp (source_path
, 0, current_source_symtab
->filename
,
781 O_RDONLY
, 0, ¤t_source_symtab
->fullname
);
783 perror_with_name (current_source_symtab
->filename
);
785 if (current_source_symtab
->line_charpos
== 0)
786 find_source_lines (current_source_symtab
, desc
);
788 if (line
< 1 || line
> current_source_symtab
->nlines
)
791 error ("Expression not found");
794 if (lseek (desc
, current_source_symtab
->line_charpos
[line
- 1], 0) < 0)
797 perror_with_name (current_source_symtab
->filename
);
800 stream
= fdopen (desc
, "r");
804 char buf
[4096]; /* Should be reasonable??? */
805 register char *p
= buf
;
812 } while (c
!= '\n' && (c
= fgetc (stream
)) >= 0);
814 /* We now have a source line in buf; null terminate and match. */
816 if (re_exec (buf
) > 0)
820 print_source_lines (current_source_symtab
,
822 current_source_line
= max (line
- 5, 1);
826 if (fseek (stream
, current_source_symtab
->line_charpos
[line
- 1], 0) < 0)
829 perror_with_name (current_source_symtab
->filename
);
833 printf ("Expression not found\n");
841 current_source_symtab
= 0;
844 add_com ("directory", class_files
, directory_command
,
845 "Add directory DIR to end of search path for source files.\n\
846 With no argument, reset the search path to just the working directory\n\
847 and forget cached info on line positions in source files.");
849 add_info ("directories", directories_info
,
850 "Current search path for finding source files.");
852 add_info ("line", line_info
,
853 "Core addresses of the code for a source line.\n\
854 Line can be specified as\n\
855 LINENUM, to list around that line in current file,\n\
856 FILE:LINENUM, to list around that line in that file,\n\
857 FUNCTION, to list around beginning of that function,\n\
858 FILE:FUNCTION, to distinguish among like-named static functions.\n\
859 Default is to describe the last source line that was listed.\n\n\
860 This sets the default address for \"x\" to the line's first instruction\n\
861 so that \"x/i\" suffices to start examining the machine code.\n\
862 The address is also stored as the value of \"$_\".");
864 add_com ("forward-search", class_files
, forward_search_command
,
865 "Search for regular expression (see regex(3)) from last line listed.");
866 add_com_alias ("search", "forward-search", class_files
, 0);
868 add_com ("reverse-search", class_files
, reverse_search_command
,
869 "Search backward for regular expression (see regex(3)) from last line listed.");
871 add_com ("list", class_files
, list_command
,
872 "List specified function or line.\n\
873 With no argument, lists ten more lines after or around previous listing.\n\
874 \"list -\" lists the ten lines before a previous ten-line listing.\n\
875 One argument specifies a line, and ten lines are listed around that line.\n\
876 Two arguments with comma between specify starting and ending lines to list.\n\
877 Lines can be specified in these ways:\n\
878 LINENUM, to list around that line in current file,\n\
879 FILE:LINENUM, to list around that line in that file,\n\
880 FUNCTION, to list around beginning of that function,\n\
881 FILE:FUNCTION, to distinguish among like-named static functions.\n\
882 *ADDRESS, to list around the line containing that address.\n\
883 With two args if one is empty it stands for ten lines away from the other arg.");